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();
}
}
}
}