Decompiled source of IsThisTheWayICame v1.1.4

IsThisTheWayICame.dll

Decompiled a year ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using IsThisTheWayICame.Properties;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("IsThisTheWayICame")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("IsThisTheWayICame")]
[assembly: AssemblyTitle("IsThisTheWayICame")]
[assembly: AssemblyVersion("1.0.0.0")]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace IsThisTheWayICame
{
	[BepInPlugin("Electric.IsThisTheWayICame", "IsThisTheWayICame", "1.1.4")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(RoundManager))]
		internal class RoundManagerPatch
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void StartPatch(ref RoundManager __instance)
			{
				if (((NetworkBehaviour)__instance).IsServer && (Object)(object)Networker.Instance == (Object)null)
				{
					GameObject val = Object.Instantiate<GameObject>(NetworkerPrefab);
					val.GetComponent<NetworkObject>().Spawn(true);
					Networker.fakeChance.Value = fakeChance;
					Networker.changeOnUse.Value = changeOnUse;
					Networker.changeOnUseChance.Value = changeOnUseChance;
				}
			}

			[HarmonyPatch("SetExitIDs")]
			[HarmonyPostfix]
			private static void SetExitIDsPatch()
			{
				random = null;
			}
		}

		[HarmonyPatch(typeof(EntranceTeleport))]
		internal class EntranceTeleportPatch
		{
			[HarmonyPatch("TeleportPlayer")]
			[HarmonyPrefix]
			private static void TeleportPlayerPatch(ref EntranceTeleport __instance)
			{
				if (__instance.entranceId < 1 || !__instance.isEntranceToBuilding)
				{
					return;
				}
				if (random == null)
				{
					Networker.Instance.FullRelocation();
				}
				else if (Networker.changeOnUse.Value)
				{
					double num = random.NextDouble();
					if (num < (double)((float)Networker.changeOnUseChance.Value / 100f))
					{
						Networker.Instance.FullRelocation();
					}
				}
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager))]
		internal class GameNetworkManagerPatch
		{
			[HarmonyPatch("Start")]
			[HarmonyPostfix]
			private static void StartPatch()
			{
				((Component)GameNetworkManager.Instance).GetComponent<NetworkManager>().AddNetworkPrefab(NetworkerPrefab);
			}
		}

		public class Networker : NetworkBehaviour
		{
			public static Networker Instance;

			public static NetworkVariable<int> fakeChance = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

			public static NetworkVariable<bool> changeOnUse = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

			public static NetworkVariable<int> changeOnUseChance = new NetworkVariable<int>(0, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

			private void Awake()
			{
				Instance = this;
			}

			public void FullRelocation()
			{
				if (((NetworkBehaviour)this).IsOwner)
				{
					FullRelocationClientRpc();
				}
				else
				{
					FullRelocationServerRpc();
				}
			}

			[ClientRpc]
			public void FullRelocationClientRpc()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Invalid comparison between Unknown and I4
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Invalid comparison between Unknown and I4
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0105: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_011a: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0131: Unknown result type (might be due to invalid IL or missing references)
				//IL_0132: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_020a: Unknown result type (might be due to invalid IL or missing references)
				NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
				if (networkManager == null || !networkManager.IsListening)
				{
					return;
				}
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3354949447u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3354949447u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
				{
					return;
				}
				bool flag = false;
				if (random == null)
				{
					flag = true;
					random = new Random(StartOfRound.Instance.randomMapSeed + 172);
					realExits.Clear();
					realExitTPData.Clear();
				}
				Scene val3 = SceneManager.GetSceneByName("SampleSceneRelay");
				Scene sceneByName = SceneManager.GetSceneByName(RoundManager.Instance.currentLevel.sceneName);
				if (GameNetworkManager.Instance.isHostingGame)
				{
					val3 = sceneByName;
				}
				GameObject[] rootGameObjects = ((Scene)(ref val3)).GetRootGameObjects();
				List<GameObject> list = new List<GameObject>();
				foreach (GameObject tempAudioSource in tempAudioSources)
				{
					Object.Destroy((Object)(object)tempAudioSource);
				}
				tempAudioSources.Clear();
				GameObject[] array = rootGameObjects;
				foreach (GameObject val4 in array)
				{
					if (((Object)val4).name.StartsWith("EntranceTeleport") && ((Object)val4).name != "EntranceTeleportA(Clone)")
					{
						if (flag)
						{
							realExits.Add(val4.transform);
							realExitTPData.Add(new Tuple<Vector3, Quaternion>(val4.transform.GetChild(0).position, val4.transform.GetChild(0).rotation));
						}
						list.Add(val4);
					}
				}
				if (realExits.Count > list.Count || realExitTPData.Count > list.Count)
				{
					Debug.LogError((object)"ITTWIC (IsThisTheWayICame) - Exits have exceeded data limit! This normally means something has gone wrong between host and client!");
				}
				foreach (GameObject item in list)
				{
					Relocate(((Scene)(ref sceneByName)).GetRootGameObjects()[0].transform, item.transform);
				}
			}

			[ServerRpc(RequireOwnership = false)]
			public void FullRelocationServerRpc()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Invalid comparison between Unknown and I4
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Invalid comparison between Unknown and I4
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
				if (networkManager != null && networkManager.IsListening)
				{
					if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
					{
						ServerRpcParams val = default(ServerRpcParams);
						FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(858788495u, val, (RpcDelivery)0);
						((NetworkBehaviour)this).__endSendServerRpc(ref val2, 858788495u, val, (RpcDelivery)0);
					}
					if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
					{
						FullRelocationClientRpc();
					}
				}
			}

			protected override void __initializeVariables()
			{
				if (fakeChance == null)
				{
					throw new Exception("Networker.fakeChance cannot be null. All NetworkVariableBase instances must be initialized.");
				}
				((NetworkVariableBase)fakeChance).Initialize((NetworkBehaviour)(object)this);
				((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)fakeChance, "fakeChance");
				base.NetworkVariableFields.Add((NetworkVariableBase)(object)fakeChance);
				if (changeOnUse == null)
				{
					throw new Exception("Networker.changeOnUse cannot be null. All NetworkVariableBase instances must be initialized.");
				}
				((NetworkVariableBase)changeOnUse).Initialize((NetworkBehaviour)(object)this);
				((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)changeOnUse, "changeOnUse");
				base.NetworkVariableFields.Add((NetworkVariableBase)(object)changeOnUse);
				if (changeOnUseChance == null)
				{
					throw new Exception("Networker.changeOnUseChance cannot be null. All NetworkVariableBase instances must be initialized.");
				}
				((NetworkVariableBase)changeOnUseChance).Initialize((NetworkBehaviour)(object)this);
				((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)changeOnUseChance, "changeOnUseChance");
				base.NetworkVariableFields.Add((NetworkVariableBase)(object)changeOnUseChance);
				((NetworkBehaviour)this).__initializeVariables();
			}

			[RuntimeInitializeOnLoadMethod]
			internal static void InitializeRPCS_Networker()
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Expected O, but got Unknown
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				NetworkManager.__rpc_func_table.Add(3354949447u, new RpcReceiveHandler(__rpc_handler_3354949447));
				NetworkManager.__rpc_func_table.Add(858788495u, new RpcReceiveHandler(__rpc_handler_858788495));
			}

			private static void __rpc_handler_3354949447(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				NetworkManager networkManager = target.NetworkManager;
				if (networkManager != null && networkManager.IsListening)
				{
					target.__rpc_exec_stage = (__RpcExecStage)2;
					((Networker)(object)target).FullRelocationClientRpc();
					target.__rpc_exec_stage = (__RpcExecStage)0;
				}
			}

			private static void __rpc_handler_858788495(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				NetworkManager networkManager = target.NetworkManager;
				if (networkManager != null && networkManager.IsListening)
				{
					target.__rpc_exec_stage = (__RpcExecStage)1;
					((Networker)(object)target).FullRelocationServerRpc();
					target.__rpc_exec_stage = (__RpcExecStage)0;
				}
			}

			protected internal override string __getTypeName()
			{
				return "Networker";
			}
		}

		private class TemporaryAudioSource : MonoBehaviour
		{
			public AudioSource audioSource;

			public float deletionTime = 0f;

			public TemporaryAudioSource()
			{
				audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			}
		}

		private const string modGUID = "Electric.IsThisTheWayICame";

		private const string modName = "IsThisTheWayICame";

		private const string modVersion = "1.1.4";

		private readonly Harmony harmony = new Harmony("Electric.IsThisTheWayICame");

		private static int fakeChance;

		private static bool changeOnUse;

		private static int changeOnUseChance;

		private static GameObject NetworkerPrefab;

		private static Random? random;

		private static List<Transform> realExits = new List<Transform>();

		private static List<Tuple<Vector3, Quaternion>> realExitTPData = new List<Tuple<Vector3, Quaternion>>();

		private static Tuple<Vector3, Quaternion>? tempLoc;

		private static List<GameObject> tempAudioSources = new List<GameObject>();

		private void Awake()
		{
			AssetBundle val = AssetBundle.LoadFromMemory(Resources.networker);
			NetworkerPrefab = val.LoadAsset<GameObject>("Assets/Networker.prefab");
			NetworkerPrefab.AddComponent<Networker>();
			fakeChance = Mathf.Clamp(((BaseUnityPlugin)this).Config.Bind<int>("General", "Fake Chance", 40, "Chance that the fire exit will teleport you to a mimic. (0-100)").Value, 0, 100);
			changeOnUse = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Change on Use", true, "If true, the destination will change whenever a player uses the exterior door").Value;
			changeOnUseChance = Mathf.Clamp(((BaseUnityPlugin)this).Config.Bind<int>("General", "Change on Use Chance", 25, "Chance that the destination will change when used. (0-100)").Value, 0, 100);
			NetcodeWeaver();
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"IsThisTheWayICame loaded!");
		}

		private static void NetcodeWeaver()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		private static void Relocate(Transform root, Transform obj)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			Transform val = PickDoor(root, obj, StartOfRound.Instance.randomMapSeed);
			Transform child = obj.GetChild(0);
			GameObject val2 = new GameObject("TemporaryAudioSource");
			tempAudioSources.Add(val2);
			TemporaryAudioSource temporaryAudioSource = val2.AddComponent<TemporaryAudioSource>();
			if (!(((Object)((Component)val).gameObject).name == "MimicDoor(Clone)"))
			{
				if (tempLoc == null)
				{
					Debug.LogError((object)"Could not find real exit. Report to developer!");
					return;
				}
				child.rotation = tempLoc.Item2;
				child.position = tempLoc.Item1;
				val2.transform.position = child.position;
				Traverse.Create((object)((Component)obj).GetComponent<EntranceTeleport>()).Field("exitPointAudio").SetValue((object)temporaryAudioSource.audioSource);
			}
			else
			{
				Vector3 val3 = default(Vector3);
				((Vector3)(ref val3))..ctor(0f, 0.065f, 0.002f);
				val3 += val.forward * -1.5f;
				child.position = val.position + val3;
				child.rotation = val.rotation;
				val2.transform.position = child.position;
				((Component)obj).GetComponent<EntranceTeleport>().entrancePointAudio = temporaryAudioSource.audioSource;
			}
		}

		private static Transform PickDoor(Transform root, Transform original, int seed)
		{
			if (random == null)
			{
				return original;
			}
			double num = random.NextDouble();
			if (num < (double)((float)fakeChance / 100f))
			{
				List<Transform> list = FindMimics(root, new List<Transform>());
				if (list.Count == 0)
				{
					num = random.NextDouble();
					tempLoc = realExitTPData.ToArray()[(int)Mathf.Floor((float)num * (float)realExitTPData.Count)];
					return original;
				}
				num = random.NextDouble();
				return list.ToArray()[(int)Mathf.Floor((float)num * (float)list.Count)];
			}
			num = random.NextDouble();
			tempLoc = realExitTPData.ToArray()[(int)Mathf.Floor((float)num * (float)realExitTPData.Count)];
			return original;
		}

		private static List<Transform> FindMimics(Transform findFrom, List<Transform> current)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			if (((Object)((Component)findFrom).gameObject).name == "MimicDoor(Clone)")
			{
				current.Add(findFrom);
			}
			foreach (Transform item in findFrom)
			{
				Transform findFrom2 = item;
				FindMimics(findFrom2, current);
			}
			return current;
		}
	}
}
namespace IsThisTheWayICame.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("IsThisTheWayICame.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] networker
		{
			get
			{
				object @object = ResourceManager.GetObject("networker", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}