Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BuyableHauntedMasks v1.3.0
BuyableHauntedMasks.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalLib.Modules; using Microsoft.CodeAnalysis; using Unity.Collections; 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(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("BuyableHauntedMasks")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCopyright("Copyright © 2023 MegaPiggy")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+3e617f0a5805158c5e5364aa5104a301d3d648a4")] [assembly: AssemblyProduct("BuyableHauntedMasks")] [assembly: AssemblyTitle("BuyableHauntedMasks")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 BuyableHauntedMasks { [BepInDependency("evaisa.lethallib", "0.13.2")] [BepInPlugin("MegaPiggy.BuyableHauntedMasks", "Buyable Haunted Masks", "1.3.0")] public class BuyableHauntedMasks : BaseUnityPlugin { public class ClonedItem : Item { public Item original; } internal class Unflagger : MonoBehaviour { public void Awake() { ((Object)((Component)this).gameObject).hideFlags = (HideFlags)0; } } [HarmonyPatch] internal static class Patches { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnRequestSync; public static HandleNamedMessageDelegate <1>__OnReceiveSync; } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] public static void ServerConnect() { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_003a: 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) //IL_0045: Expected O, but got Unknown if (IsHost) { LoggerInstance.LogInfo((object)"Started hosting, using local settings"); CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager; object obj = <>O.<0>__OnRequestSync; if (obj == null) { HandleNamedMessageDelegate val = OnRequestSync; <>O.<0>__OnRequestSync = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("BuyableHauntedMasks_OnRequestConfigSync", (HandleNamedMessageDelegate)obj); UpdateComedyPrice(); UpdateTragedyPrice(); } else { LoggerInstance.LogInfo((object)"Connected to server, requesting settings"); CustomMessagingManager customMessagingManager2 = NetworkManager.Singleton.CustomMessagingManager; object obj2 = <>O.<1>__OnReceiveSync; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnReceiveSync; <>O.<1>__OnReceiveSync = val2; obj2 = (object)val2; } customMessagingManager2.RegisterNamedMessageHandler("BuyableHauntedMasks_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("BuyableHauntedMasks_OnRequestConfigSync", 0uL, new FastBufferWriter(0, (Allocator)2, -1), (NetworkDelivery)2); } } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "Start")] public static void Start() { LoggerInstance.LogWarning((object)"Game network manager start"); CloneComedy(); CloneTragedy(); } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")] public static void ServerDisconnect() { LoggerInstance.LogInfo((object)"Server disconnect"); ComedyMaskPriceRemote = -1; TragedyMaskPriceRemote = -1; } } private const string modGUID = "MegaPiggy.BuyableHauntedMasks"; private const string modName = "Buyable Haunted Masks"; private const string modVersion = "1.3.0"; private readonly Harmony harmony = new Harmony("MegaPiggy.BuyableHauntedMasks"); private static BuyableHauntedMasks Instance; private static ConfigEntry<int> ComedyMaskPriceConfig; internal static int ComedyMaskPriceRemote = -1; private static ConfigEntry<int> TragedyMaskPriceConfig; internal static int TragedyMaskPriceRemote = -1; private static Dictionary<string, TerminalNode> infoNodes = new Dictionary<string, TerminalNode>(); public static byte CurrentVersionByte = 1; private static ManualLogSource LoggerInstance => ((BaseUnityPlugin)Instance).Logger; public static List<Item> AllItems => Resources.FindObjectsOfTypeAll<Item>().Reverse().ToList(); public static Item Comedy => ((IEnumerable<Item>)AllItems).FirstOrDefault((Func<Item, bool>)((Item item) => ((Object)item).name.Equals("ComedyMask") && (Object)(object)item.spawnPrefab != (Object)null)); public static Item Tragedy => ((IEnumerable<Item>)AllItems).FirstOrDefault((Func<Item, bool>)((Item item) => ((Object)item).name.Equals("TragedyMask") && (Object)(object)item.spawnPrefab != (Object)null)); public static ClonedItem ComedyClone { get; private set; } public static ClonedItem TragedyClone { get; private set; } public static int ComedyMaskPriceLocal => ComedyMaskPriceConfig.Value; public static int ComedyMaskPrice => (ComedyMaskPriceRemote > -1) ? ComedyMaskPriceRemote : ComedyMaskPriceLocal; public static int TragedyMaskPriceLocal => TragedyMaskPriceConfig.Value; public static int TragedyMaskPrice => (TragedyMaskPriceRemote > -1) ? TragedyMaskPriceRemote : TragedyMaskPriceLocal; private static bool IsHost => NetworkManager.Singleton.IsHost; private static ulong LocalClientId => NetworkManager.Singleton.LocalClientId; private void Awake() { if ((Object)(object)Instance == (Object)null) { Object.DontDestroyOnLoad((Object)(object)this); Instance = this; } harmony.PatchAll(); ComedyMaskPriceConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Prices", "ComedyMaskPrice", 30, "Credits needed to buy comedy mask"); TragedyMaskPriceConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Prices", "TragedyMaskPrice", 30, "Credits needed to buy tragedy mask"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Buyable Haunted Masks is loaded with version 1.3.0!"); } private static ClonedItem CloneNonScrap(Item original, int price) { ClonedItem clonedItem = ScriptableObject.CreateInstance<ClonedItem>(); Object.DontDestroyOnLoad((Object)(object)clonedItem); clonedItem.original = original; GameObject val = NetworkPrefabs.CloneNetworkPrefab(original.spawnPrefab, "Buyable" + ((Object)original).name); val.AddComponent<Unflagger>(); Object.DontDestroyOnLoad((Object)(object)val); CopyFields(original, (Item)(object)clonedItem); val.GetComponent<GrabbableObject>().itemProperties = (Item)(object)clonedItem; ((Item)clonedItem).spawnPrefab = val; ((Object)clonedItem).name = "Buyable" + ((Object)original).name; ((Item)clonedItem).creditsWorth = price; ((Item)clonedItem).isScrap = false; return clonedItem; } public static void CopyFields(Item source, Item destination) { FieldInfo[] fields = typeof(Item).GetFields(); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { fieldInfo.SetValue(destination, fieldInfo.GetValue(source)); } } private static TerminalNode CreateInfoNode(string name, string description) { if (infoNodes.ContainsKey(name)) { return infoNodes[name]; } TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); val.clearPreviousText = true; ((Object)val).name = name + "InfoNode"; val.displayText = description + "\n\n"; infoNodes.Add(name, val); return val; } private static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { CloneComedy(); CloneTragedy(); } private static void CloneComedy() { if (!((Object)(object)Comedy == (Object)null) && !((Object)(object)ComedyClone != (Object)null)) { ComedyClone = CloneNonScrap(Comedy, ComedyMaskPrice); AddComedyToShop(); } } private static void AddComedyToShop() { ClonedItem comedyClone = ComedyClone; int comedyMaskPrice = ComedyMaskPrice; Items.RegisterShopItem((Item)(object)comedyClone, (TerminalNode)null, (TerminalNode)null, CreateInfoNode("ComedyMask", "Haunted mask. It has a 65% chance to turn you into zombie every 5 seconds."), comedyMaskPrice); LoggerInstance.LogInfo((object)$"Comedy Mask added to Shop for {ComedyMaskPrice} credits"); } private static void UpdateComedyPrice() { ((Item)ComedyClone).creditsWorth = ComedyMaskPrice; Items.UpdateShopItemPrice((Item)(object)ComedyClone, ComedyMaskPrice); LoggerInstance.LogInfo((object)$"Comedy Mask price updated to {ComedyMaskPrice} credits"); } private static void CloneTragedy() { if (!((Object)(object)Tragedy == (Object)null) && !((Object)(object)TragedyClone != (Object)null)) { TragedyClone = CloneNonScrap(Tragedy, TragedyMaskPrice); AddTragedyToShop(); } } private static void AddTragedyToShop() { ClonedItem tragedyClone = TragedyClone; int tragedyMaskPrice = TragedyMaskPrice; Items.RegisterShopItem((Item)(object)tragedyClone, (TerminalNode)null, (TerminalNode)null, CreateInfoNode("TragedyMask", "Haunted mask. It has a 65% chance to turn you into zombie every 5 seconds. You cannot take this off once you put it on."), tragedyMaskPrice); LoggerInstance.LogInfo((object)$"Tragedy Mask added to Shop for {TragedyMaskPrice} credits"); } private static void UpdateTragedyPrice() { ((Item)TragedyClone).creditsWorth = TragedyMaskPrice; Items.UpdateShopItemPrice((Item)(object)TragedyClone, TragedyMaskPrice); LoggerInstance.LogInfo((object)$"Tragedy Mask price updated to {TragedyMaskPrice} credits"); } public static void WriteData(FastBufferWriter writer) { ((FastBufferWriter)(ref writer)).WriteByte(CurrentVersionByte); ((FastBufferWriter)(ref writer)).WriteBytes(BitConverter.GetBytes(ComedyMaskPriceLocal), -1, 0); ((FastBufferWriter)(ref writer)).WriteBytes(BitConverter.GetBytes(TragedyMaskPriceLocal), -1, 0); } public static void ReadData(FastBufferReader reader) { byte b = default(byte); ((FastBufferReader)(ref reader)).ReadByte(ref b); if (b == CurrentVersionByte) { byte[] value = new byte[4]; ((FastBufferReader)(ref reader)).ReadBytes(ref value, 4, 0); ComedyMaskPriceRemote = BitConverter.ToInt32(value, 0); UpdateComedyPrice(); byte[] value2 = new byte[4]; ((FastBufferReader)(ref reader)).ReadBytes(ref value2, 4, 0); TragedyMaskPriceRemote = BitConverter.ToInt32(value2, 0); UpdateTragedyPrice(); LoggerInstance.LogInfo((object)"Host config set successfully"); return; } throw new Exception("Invalid version byte"); } public static void OnRequestSync(ulong clientID, FastBufferReader reader) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (!IsHost) { return; } LoggerInstance.LogInfo((object)("Sending config to client " + clientID)); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(5, (Allocator)2, 5); try { WriteData(val); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("BuyableHauntedMasks_OnReceiveConfigSync", clientID, val, (NetworkDelivery)2); } catch (Exception arg) { LoggerInstance.LogError((object)$"Failed to send config: {arg}"); } finally { ((FastBufferWriter)(ref val)).Dispose(); } } public static void OnReceiveSync(ulong clientID, FastBufferReader reader) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) LoggerInstance.LogInfo((object)"Received config from host"); try { ReadData(reader); } catch (Exception arg) { LoggerInstance.LogError((object)$"Failed to receive config: {arg}"); ComedyMaskPriceRemote = -1; TragedyMaskPriceRemote = -1; } } } }