Decompiled source of SpikeTrapFixes v1.1.2

SpikeTrapFixes.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using STFixes.Patches;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Fixes Spike Traps")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SpikeTrapFixes")]
[assembly: AssemblyCopyright("Spookybuddy 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("28f2f16b-6471-4c7e-b0a4-007e3a2450d4")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.1.0.0")]
namespace STFixes
{
	internal class ConfigControl : SyncedInstance<ConfigControl>
	{
		public ConfigEntry<bool> cfgModEnabled;

		public ConfigEntry<bool> cfgSTEnabled;

		public ConfigEntry<STFixModBase.EnumOptions> cfgTypes;

		public ConfigEntry<bool> cfgClamp;

		public ConfigEntry<float> cfgMin;

		public ConfigEntry<float> cfgMax;

		public ConfigEntry<bool> cfgScan;

		public ConfigEntry<bool> cfgMove;

		public ConfigEntry<int> cfgRange;

		internal bool Mod
		{
			get
			{
				if (cfgModEnabled.Value)
				{
					return true;
				}
				return false;
			}
			set
			{
				cfgModEnabled.Value = value;
			}
		}

		internal bool Traps
		{
			get
			{
				if (cfgSTEnabled.Value)
				{
					return true;
				}
				return false;
			}
			set
			{
				cfgSTEnabled.Value = value;
			}
		}

		internal STFixModBase.EnumOptions Types
		{
			get
			{
				if (cfgTypes == null)
				{
					return (STFixModBase.EnumOptions)((ConfigEntryBase)cfgTypes).DefaultValue;
				}
				return cfgTypes.Value;
			}
			set
			{
				cfgTypes.Value = value;
			}
		}

		internal bool Clamp
		{
			get
			{
				if (cfgClamp.Value)
				{
					return true;
				}
				return false;
			}
			set
			{
				cfgClamp.Value = value;
			}
		}

		internal float Minimum
		{
			get
			{
				if (cfgMin.Value > 0.7f)
				{
					return cfgMin.Value;
				}
				return (float)((ConfigEntryBase)cfgMin).DefaultValue;
			}
			set
			{
				cfgMin.Value = value;
			}
		}

		internal float Maximum
		{
			get
			{
				if (cfgMax.Value > cfgMin.Value)
				{
					return cfgMax.Value;
				}
				return (float)((ConfigEntryBase)cfgMax).DefaultValue;
			}
			set
			{
				cfgMax.Value = value;
			}
		}

		internal bool Scans
		{
			get
			{
				if (cfgScan.Value)
				{
					return true;
				}
				return false;
			}
			set
			{
				cfgScan.Value = value;
			}
		}

		internal bool Move
		{
			get
			{
				if (cfgMove.Value)
				{
					return true;
				}
				return false;
			}
			set
			{
				cfgMove.Value = value;
			}
		}

		internal int ScanRange
		{
			get
			{
				if (cfgRange.Value > 1)
				{
					return cfgRange.Value;
				}
				return (int)((ConfigEntryBase)cfgRange).DefaultValue;
			}
			set
			{
				cfgRange.Value = value;
			}
		}

		public ConfigControl(ConfigFile cfg)
		{
			InitInstance(this);
			cfgModEnabled = cfg.Bind<bool>("Enabled", "Mod Enabled", true, "Turn the mod on.");
			cfgSTEnabled = cfg.Bind<bool>("Enabled", "Traps Enabled", true, "When disabled turns the spike traps into harmless decor.");
			cfgTypes = cfg.Bind<STFixModBase.EnumOptions>("Enabled", "Trap types", STFixModBase.EnumOptions.Both, "What types of traps should spawn.");
			cfgClamp = cfg.Bind<bool>("Clamp", "Enabled", true, "Enable the slam rate limits listed below. \n\nWhen disabled the spike traps will use the values they spawned with.");
			cfgMin = cfg.Bind<float>("Clamp", "Minimum", 1.5f, "The fastest slam interval. \n\nBase game's quickest possible is 0.71 sec.");
			cfgMax = cfg.Bind<float>("Clamp", "Maximum", 25f, "The slowest slam interval. \n\nBase game's slowest possible is 26.15 sec.");
			cfgScan = cfg.Bind<bool>("Scan Node", "Enabled", true, "Add a scanable node to the spike traps, similar to landmines and turrets. \n\nBase game does not have a scan node.");
			cfgMove = cfg.Bind<bool>("Scan Node", "Move with spikes", true, "The scan node will move with the spikes. Otherwise it will remain in a fixed position.");
			cfgRange = cfg.Bind<int>("Scan Node", "Range", 9, "The max distance the scan node can be scanned.");
		}
	}
	[BepInPlugin("SpikeTrapFixes", "SpikeTrapFixes", "1.1.2")]
	public class STFixModBase : BaseUnityPlugin
	{
		internal enum EnumOptions
		{
			IntervalOnly,
			DetectionOnly,
			Both
		}

		public const string modGUID = "SpikeTrapFixes";

		private const string modName = "SpikeTrapFixes";

		private const string modVersion = "1.1.2";

		private readonly Harmony harmony = new Harmony("SpikeTrapFixes");

		internal ConfigControl Configuration;

		internal static STFixModBase Instance;

		internal static ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("SpikeTrapFixes");
			Configuration = new ConfigControl(((BaseUnityPlugin)this).Config);
			harmony.PatchAll(typeof(STFixModBase));
			harmony.PatchAll(typeof(SpikeRoofTrapPatch));
			harmony.PatchAll(typeof(ConfigControl));
			mls.LogInfo((object)"Spike Trap Fixes was loaded.");
		}
	}
	[Serializable]
	public class SyncedInstance<T>
	{
		[NonSerialized]
		protected static int IntSize = 4;

		internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager;

		internal static bool IsClient => NetworkManager.Singleton.IsClient;

		internal static bool IsHost => NetworkManager.Singleton.IsHost;

		public static T Default { get; private set; }

		public static T Instance { get; private set; }

		public static bool Synced { get; internal set; }

		protected void InitInstance(T instance)
		{
			Default = instance;
			Instance = instance;
			IntSize = 4;
		}

		internal static void SyncInstance(byte[] data)
		{
			Instance = DeserializeFromBytes(data);
			Synced = true;
		}

		internal static void RevertSync()
		{
			Instance = Default;
			Synced = false;
		}

		public static byte[] SerializeToBytes(T val)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			MemoryStream memoryStream = new MemoryStream();
			try
			{
				binaryFormatter.Serialize(memoryStream, val);
				return memoryStream.ToArray();
			}
			catch (Exception arg)
			{
				STFixModBase.mls.LogError((object)$"Error serializing instance: {arg}");
				return null;
			}
		}

		public static T DeserializeFromBytes(byte[] data)
		{
			BinaryFormatter binaryFormatter = new BinaryFormatter();
			MemoryStream serializationStream = new MemoryStream(data);
			try
			{
				return (T)binaryFormatter.Deserialize(serializationStream);
			}
			catch (Exception arg)
			{
				STFixModBase.mls.LogError((object)$"Error deserializing instance: {arg}");
				return default(T);
			}
		}

		public static void RequestSync()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (IsClient)
			{
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(IntSize, (Allocator)2, -1);
				MessageManager.SendNamedMessage("SpikeTrapFixes_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
			}
		}

		public static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHost)
			{
				return;
			}
			STFixModBase.mls.LogInfo((object)$"Config sync request received from client: {clientId}");
			byte[] array = SerializeToBytes(Instance);
			int num = array.Length;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num + IntSize, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				MessageManager.SendNamedMessage("SpikeTrapFixes_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3);
			}
			catch (Exception arg)
			{
				STFixModBase.mls.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
			}
		}

		public static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (!((FastBufferReader)(ref reader)).TryBeginRead(IntSize))
			{
				STFixModBase.mls.LogError((object)"Config sync error: Could not begin reading buffer.");
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				STFixModBase.mls.LogError((object)"Config sync error: Host could not sync.");
				return;
			}
			byte[] data = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
			SyncInstance(data);
			STFixModBase.mls.LogInfo((object)"Successfully synced config with host.");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "SteamMatchmaking_OnLobbyMemberJoined")]
		public static void InitializeLocalPlayer()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			if (IsHost)
			{
				MessageManager.RegisterNamedMessageHandler("SpikeTrapFixes_OnRequestConfigSync", new HandleNamedMessageDelegate(OnRequestSync));
				Synced = true;
			}
			else
			{
				Synced = false;
				MessageManager.RegisterNamedMessageHandler("SpikeTrapFixes_OnReceiveConfigSync", new HandleNamedMessageDelegate(OnReceiveSync));
				RequestSync();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		public static void PlayerLeave()
		{
			SyncedInstance<ConfigControl>.RevertSync();
		}
	}
}
namespace STFixes.Patches
{
	[HarmonyPatch(typeof(SpikeRoofTrap))]
	internal class SpikeRoofTrapPatch
	{
		internal static readonly Vector3 moving = new Vector3(-0.48f, 0f, -0.378f);

		internal static readonly Vector3 still = new Vector3(0f, 3f, 1.8f);

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void BeginningFix(SpikeRoofTrap __instance)
		{
			ConfigControl instance = SyncedInstance<ConfigControl>.Instance;
			if (!instance.Mod)
			{
				STFixModBase.mls.LogWarning((object)"Mod disabled.");
			}
			else if (!instance.Traps)
			{
				Object.Destroy((Object)(object)__instance);
				STFixModBase.mls.LogInfo((object)"Removed script from spike trap.");
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartFix(SpikeRoofTrap __instance, ref float ___slamInterval, ref bool ___slamOnIntervals)
		{
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			ConfigControl instance = SyncedInstance<ConfigControl>.Instance;
			if (!instance.Mod)
			{
				return;
			}
			if (!instance.Traps)
			{
				Object.Destroy((Object)(object)__instance);
				return;
			}
			if (!instance.Types.Equals(STFixModBase.EnumOptions.Both))
			{
				STFixModBase.mls.LogInfo((object)("Changing trap to " + instance.Types));
				___slamOnIntervals = instance.Types.Equals(STFixModBase.EnumOptions.IntervalOnly);
			}
			if (instance.Clamp && !instance.Types.Equals(STFixModBase.EnumOptions.DetectionOnly))
			{
				if (___slamInterval < instance.Minimum)
				{
					STFixModBase.mls.LogInfo((object)("Raised interval from " + ___slamInterval + "sec to " + instance.Minimum + "sec."));
				}
				if (___slamInterval > instance.Maximum)
				{
					STFixModBase.mls.LogInfo((object)("Lowered interval from " + ___slamInterval + "sec to " + instance.Maximum + "sec."));
				}
				___slamInterval = Mathf.Clamp(___slamInterval, instance.Minimum, instance.Maximum);
			}
			if (instance.Scans)
			{
				GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
				if (instance.Move)
				{
					val.transform.parent = __instance.stickingPointsContainer;
					val.transform.localPosition = moving;
				}
				else
				{
					val.transform.parent = __instance.laserEye;
					val.transform.localPosition = still;
				}
				val.tag = "DoNotSet";
				val.layer = 22;
				Object.Destroy((Object)(object)val.GetComponent<MeshFilter>());
				Object.Destroy((Object)(object)val.GetComponent<MeshRenderer>());
				ScanNodeProperties val2 = val.AddComponent<ScanNodeProperties>();
				val2.maxRange = instance.ScanRange;
				val2.minRange = 1;
				val2.requiresLineOfSight = true;
				val2.headerText = "Spike Trap";
				val2.subText = "";
				val2.scrapValue = 0;
				val2.creatureScanID = -1;
				val2.nodeType = 1;
				STFixModBase.mls.LogInfo((object)"Added scan node to spike trap.");
			}
		}
	}
}