Decompiled source of PortalPeek XPN Bridge v1.1.0

PortalPeek_XPN_Bridge.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PortalPeek_XPN_Bridge")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("PortalPeek_XPN_Bridge")]
[assembly: AssemblyTitle("PortalPeek_XPN_Bridge")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TheShack.PortalPeekXpnBridge
{
	[BepInPlugin("theshack.portalpeek_xpn_bridge", "PortalPeek XPN Bridge", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "theshack.portalpeek_xpn_bridge";

		public const string PluginName = "PortalPeek XPN Bridge";

		public const string PluginVersion = "1.1.0";

		private const string PortalPeekGuid = "tboods.PortalPeek";

		private static readonly string[] RecordingMethods = new string[3] { "Update", "TryDepartureCapture", "Nearest" };

		internal static ManualLogSource Log;

		private static ConfigEntry<bool> recordEvery;

		private static ConfigEntry<bool> dayNight;

		private static int recording;

		private const string DayTag = "-1";

		private const string NightTag = "-0";

		private static FieldInfo libraryDir;

		private static readonly Dictionary<string, (bool exists, float checkedAt)> onDisk = new Dictionary<string, (bool, float)>();

		private const float RecheckSeconds = 5f;

		private static bool Night
		{
			get
			{
				if (Object.op_Implicit((Object)(object)EnvMan.instance))
				{
					return EnvMan.IsNight();
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0124: Expected O, but got Unknown
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Expected O, but got Unknown
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			recordEvery = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Record every portal", true, "Record what's around any portal you stand by, even one that doesn't lead anywhere itself, so portals leading to it (one-way links, like XPortalNetworks') can show it. Off: Portal Peek's own rule.");
			dayNight = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Day and night versions", true, "Keep a daytime and a nighttime recording of each portal and show the one for the light you're in. Off: one recording per portal, in whatever light it was made (Portal Peek's own way).");
			Type type = AccessTools.TypeByName("PortalPeek.PeekCapturer");
			Type type2 = AccessTools.TypeByName("PortalPeek.PeekPortal");
			MethodInfo methodInfo = ((type2 == null) ? null : AccessTools.PropertyGetter(type2, "IsConnected"));
			if (type == null || methodInfo == null)
			{
				Log.LogWarning((object)"This Portal Peek version is laid out differently; the bridge does nothing.");
				return;
			}
			Harmony val = new Harmony("theshack.portalpeek_xpn_bridge");
			int num = 0;
			string[] recordingMethods = RecordingMethods;
			foreach (string text in recordingMethods)
			{
				MethodInfo methodInfo2 = AccessTools.Method(type, text, (Type[])null, (Type[])null);
				if (methodInfo2 == null)
				{
					Log.LogWarning((object)("Portal Peek has no " + text + "; recording from there keeps Portal Peek's own rule."));
					continue;
				}
				val.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(Plugin), "EnterRecording", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "LeaveRecording", (Type[])null), (HarmonyMethod)null);
				num++;
			}
			val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "IsConnectedPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Type type3 = AccessTools.TypeByName("PortalPeek.PortalKey");
			Type type4 = AccessTools.TypeByName("PortalPeek.PeekLibrary");
			MethodInfo methodInfo3 = ((type3 == null) ? null : AccessTools.Method(type3, "For", new Type[1] { typeof(ZDO) }, (Type[])null));
			MethodInfo methodInfo4 = ((type4 == null) ? null : AccessTools.Method(type4, "Get", new Type[2]
			{
				typeof(string),
				typeof(float)
			}, (Type[])null));
			libraryDir = ((type4 == null) ? null : AccessTools.Field(type4, "s_dir"));
			string text2 = "day and night versions off (Portal Peek's layout differs)";
			if (methodInfo3 != null && methodInfo4 != null && libraryDir != null)
			{
				val.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "KeyPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(Plugin), "GetPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				text2 = "day and night versions";
			}
			Log.LogInfo((object)string.Format("{0} {1} ready ({2} of {3} recording paths bridged, {4}).", "PortalPeek XPN Bridge", "1.1.0", num, RecordingMethods.Length, text2));
		}

		private static void EnterRecording()
		{
			recording++;
		}

		private static Exception LeaveRecording(Exception __exception)
		{
			recording = Math.Max(0, recording - 1);
			return __exception;
		}

		private static void KeyPostfix(ref string __result)
		{
			if (dayNight.Value && !string.IsNullOrEmpty(__result))
			{
				__result += (Night ? "-0" : "-1");
			}
		}

		private static void GetPrefix(ref string key)
		{
			if (!dayNight.Value || string.IsNullOrEmpty(key) || (!key.EndsWith("-1") && !key.EndsWith("-0")) || !(libraryDir.GetValue(null) is string dir))
			{
				return;
			}
			string text = key.Substring(0, key.Length - 2);
			string text2 = text + (key.EndsWith("-1") ? "-0" : "-1");
			string[] array = new string[3] { key, text2, text };
			foreach (string text3 in array)
			{
				if (Exists(dir, text3))
				{
					key = text3;
					break;
				}
			}
		}

		private static bool Exists(string dir, string key)
		{
			float time = Time.time;
			if (onDisk.TryGetValue(key, out (bool, float) value) && time - value.Item2 < 5f)
			{
				return value.Item1;
			}
			bool flag = File.Exists(Path.Combine(dir, key + ".ppk"));
			onDisk[key] = (flag, time);
			return flag;
		}

		private static void IsConnectedPostfix(MonoBehaviour __instance, ref bool __result)
		{
			if (!__result && recording != 0 && recordEvery.Value && Object.op_Implicit((Object)(object)__instance))
			{
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component) && component.IsValid())
				{
					__result = true;
				}
			}
		}
	}
}