Decompiled source of EasterEggFixes v2.0.1

EasterEggFixes.dll

Decompiled 2 months 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 EggFixes.Patches;
using GameNetcodeStuff;
using HarmonyLib;
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("Egg")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EasterEggFixes")]
[assembly: AssemblyCopyright("Spookybuddy 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("28f2f16b-6471-4c7e-b0a4-007e3a2450d4")]
[assembly: AssemblyFileVersion("2.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("2.0.0.0")]
namespace EggFixes
{
	internal class ConfigControl : SyncedInstance<ConfigControl>
	{
		public ConfigEntry<bool> cfgEnabled;

		public ConfigEntry<EasterEggFixesModBase.EggSettings> cfgExplodeWhen;

		public ConfigEntry<int> cfgChance;

		internal bool Enabled
		{
			get
			{
				if (cfgEnabled != null)
				{
					return cfgEnabled.Value;
				}
				return true;
			}
			set
			{
				cfgEnabled.Value = value;
			}
		}

		internal EasterEggFixesModBase.EggSettings ExplodeWhen
		{
			get
			{
				if (cfgExplodeWhen == null)
				{
					return (EasterEggFixesModBase.EggSettings)((ConfigEntryBase)cfgExplodeWhen).DefaultValue;
				}
				return cfgExplodeWhen.Value;
			}
			set
			{
				cfgExplodeWhen.Value = value;
			}
		}

		internal int Chance
		{
			get
			{
				if (cfgChance.Value > 0 && cfgChance.Value < 100)
				{
					return cfgChance.Value;
				}
				return (int)((ConfigEntryBase)cfgChance).DefaultValue;
			}
			set
			{
				cfgChance.Value = value;
			}
		}

		public ConfigControl(ConfigFile cfg)
		{
			InitInstance(this);
			cfgEnabled = cfg.Bind<bool>("Eggs", "Enabled", true, "Turn the mod on.");
			cfgExplodeWhen = cfg.Bind<EasterEggFixesModBase.EggSettings>("Eggs", "Explode When", EasterEggFixesModBase.EggSettings.ExplodeOnThrow, "When should the eggs explode?");
			cfgChance = cfg.Bind<int>("Eggs", "Chance to Explode", 16, "The percent chance for the eggs to explode when set to 'ChanceToExplode'. \nRanges from 1 - 99");
		}
	}
	[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)
			{
				EasterEggFixesModBase.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)
			{
				EasterEggFixesModBase.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("EasterEggFixes_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;
			}
			EasterEggFixesModBase.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("EasterEggFixes_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3);
			}
			catch (Exception arg)
			{
				EasterEggFixesModBase.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))
			{
				EasterEggFixesModBase.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))
			{
				EasterEggFixesModBase.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);
			EasterEggFixesModBase.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("EasterEggFixes_OnRequestConfigSync", new HandleNamedMessageDelegate(OnRequestSync));
				Synced = true;
			}
			else
			{
				Synced = false;
				MessageManager.RegisterNamedMessageHandler("EasterEggFixes_OnReceiveConfigSync", new HandleNamedMessageDelegate(OnReceiveSync));
				RequestSync();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
		public static void PlayerLeave()
		{
			SyncedInstance<ConfigControl>.RevertSync();
		}
	}
	[BepInPlugin("EasterEggFixes", "EasterEggFixes", "2.0.1")]
	public class EasterEggFixesModBase : BaseUnityPlugin
	{
		internal enum EggSettings
		{
			ExplodeOnThrow,
			AlwaysExplode,
			NeverExplode,
			ChanceToExplode
		}

		public const string modGUID = "EasterEggFixes";

		private const string modName = "EasterEggFixes";

		private const string modVersion = "2.0.1";

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

		internal ConfigControl Configuration;

		internal static EasterEggFixesModBase Instance;

		internal static ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("EasterEggFixes");
			Configuration = new ConfigControl(((BaseUnityPlugin)this).Config);
			harmony.PatchAll(typeof(EasterEggFixesModBase));
			harmony.PatchAll(typeof(StunGrenadeItemPatch));
			harmony.PatchAll(typeof(PlayerControllerBPatch));
			mls.LogInfo((object)"Easter Egg Fixes was loaded.");
		}
	}
}
namespace EggFixes.Patches
{
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerControllerBPatch
	{
		[HarmonyPatch("DiscardHeldObject")]
		[HarmonyPrefix]
		private static bool ThrowPrep(bool placeObject, NetworkObject parentObjectTo, Vector3 placePosition, PlayerControllerB __instance)
		{
			//IL_0056: 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_005f: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<ConfigControl>.Instance.Enabled || SyncedInstance<ConfigControl>.Instance.ExplodeWhen != 0)
			{
				return true;
			}
			if (__instance.currentlyHeldObjectServer.itemProperties.itemName.Equals("Easter egg") && placeObject && (Object)(object)parentObjectTo == (Object)null && placePosition != default(Vector3))
			{
				EasterEggFixesModBase.mls.LogWarning((object)"Egg Thrown!");
				__instance.playerBodyAnimator.SetBool("cancelHolding", true);
				__instance.playerBodyAnimator.SetTrigger("Throw");
				((Behaviour)HUDManager.Instance.itemSlotIcons[__instance.currentItemSlot]).enabled = false;
				((Behaviour)HUDManager.Instance.holdingTwoHandedItem).enabled = false;
				placePosition = ((!__instance.isInElevator) ? StartOfRound.Instance.propsContainer.InverseTransformPoint(placePosition) : StartOfRound.Instance.elevatorTransform.InverseTransformPoint(placePosition));
				__instance.SetObjectAsNoLongerHeld(__instance.isInElevator, __instance.isInHangarShipRoom, placePosition, __instance.currentlyHeldObjectServer, (int)((Component)__instance).transform.localEulerAngles.y);
				__instance.currentlyHeldObjectServer.DiscardItemOnClient();
				MethodInfo method = typeof(PlayerControllerB).GetMethod("ThrowObjectServerRpc", BindingFlags.Instance | BindingFlags.NonPublic);
				NetworkObjectReference val = NetworkObjectReference.op_Implicit(((Component)__instance.currentlyHeldObjectServer).gameObject.GetComponent<NetworkObject>());
				object[] parameters = new object[5] { val, __instance.isInElevator, __instance.isInHangarShipRoom, placePosition, -211 };
				method.Invoke(__instance, parameters);
				return false;
			}
			return true;
		}

		[HarmonyPatch("ThrowObjectServerRpc")]
		[HarmonyPrefix]
		private static void ThrowFix(NetworkObjectReference grabbedObject, bool droppedInElevator, bool droppedInShipRoom, Vector3 targetFloorPosition, int floorYRot, PlayerControllerB __instance)
		{
			if ((Object)(object)__instance.currentlyHeldObjectServer == (Object)null || !SyncedInstance<ConfigControl>.Instance.Enabled || SyncedInstance<ConfigControl>.Instance.ExplodeWhen != 0 || !__instance.currentlyHeldObjectServer.itemProperties.itemName.Equals("Easter egg"))
			{
				return;
			}
			if (floorYRot == -211)
			{
				EasterEggFixesModBase.mls.LogInfo((object)"BOOM!");
				StunGrenadeItem val = default(StunGrenadeItem);
				if (((Component)__instance.currentlyHeldObjectServer).TryGetComponent<StunGrenadeItem>(ref val))
				{
					val.chanceToExplode = 111f;
					val.SetExplodeOnThrowServerRpc();
				}
				else
				{
					EasterEggFixesModBase.mls.LogError((object)"Threw an egg that did not have the StunGrenadeItem script!");
				}
			}
			else
			{
				EasterEggFixesModBase.mls.LogInfo((object)"Dropped Egg!");
			}
		}
	}
	[HarmonyPatch(typeof(StunGrenadeItem))]
	internal class StunGrenadeItemPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void StartFix(StunGrenadeItem __instance)
		{
			if (SyncedInstance<ConfigControl>.Instance.Enabled && __instance.chanceToExplode != 100f)
			{
				switch (SyncedInstance<ConfigControl>.Instance.ExplodeWhen)
				{
				case EasterEggFixesModBase.EggSettings.AlwaysExplode:
					__instance.chanceToExplode = 111f;
					EasterEggFixesModBase.mls.LogInfo((object)"Eggs Always Explode");
					break;
				case EasterEggFixesModBase.EggSettings.ChanceToExplode:
					__instance.chanceToExplode = SyncedInstance<ConfigControl>.Instance.Chance;
					EasterEggFixesModBase.mls.LogInfo((object)"Eggs Sometimes Explode");
					break;
				default:
					__instance.chanceToExplode = -1f;
					EasterEggFixesModBase.mls.LogInfo((object)"Fixed an Egg");
					break;
				}
			}
		}

		[HarmonyPatch("EquipItem")]
		[HarmonyPostfix]
		private static void EquipFix(StunGrenadeItem __instance)
		{
			if (SyncedInstance<ConfigControl>.Instance.Enabled && __instance.chanceToExplode != 100f)
			{
				switch (SyncedInstance<ConfigControl>.Instance.ExplodeWhen)
				{
				case EasterEggFixesModBase.EggSettings.AlwaysExplode:
					__instance.chanceToExplode = 111f;
					EasterEggFixesModBase.mls.LogInfo((object)"Egg will Always Explode");
					break;
				case EasterEggFixesModBase.EggSettings.ChanceToExplode:
					__instance.chanceToExplode = SyncedInstance<ConfigControl>.Instance.Chance;
					EasterEggFixesModBase.mls.LogInfo((object)("Egg will explode " + SyncedInstance<ConfigControl>.Instance.Chance + "%"));
					break;
				default:
					__instance.chanceToExplode = -1f;
					EasterEggFixesModBase.mls.LogInfo((object)"Picked up an Egg");
					break;
				}
				__instance.SetExplodeOnThrowServerRpc();
			}
		}
	}
}