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 LethalExtras v1.0.4
BepinEx/plugins/LethalExtras/LethalExtras.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; 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 LethalExtras.Patches; using LethalExtras.UnlockableItems; using LethalLib.Modules; using Microsoft.CodeAnalysis; 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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LethalExtras")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Extra stuff for Lethal Company")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("LethalExtras")] [assembly: AssemblyTitle("LethalExtras")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] internal class <Module> { static <Module>() { } } 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 LethalExtras { public class Config { public bool blahajEnabled; public bool redArgemiaEnabled; public bool blueArgemiaEnabled; public bool greenArgemiaEnabled; public bool dingusEnabled; public bool medstationEnabled; public int medstationPrice; public int medstationCharges; public bool IsLoaded { get; private set; } = false; public List<ConfigEntryBase> configEntries { get; private set; } = new List<ConfigEntryBase>(); public void Load() { blahajEnabled = AddBoolConfig("Scrap", "BlahajEnabled", defaultValues: true, "If enabled, adds blahaj to scrap pool."); redArgemiaEnabled = AddBoolConfig("Scrap", "RedArgemiaEnabled", defaultValues: true, "If enabled, adds Red Argemia Plush to scrap pool."); blueArgemiaEnabled = AddBoolConfig("Scrap", "BlueArgemiaEnabled", defaultValues: true, "If enabled, adds Blue Argemia Plush to scrap pool."); greenArgemiaEnabled = AddBoolConfig("Scrap", "GreenArgemiaEnabled", defaultValues: true, "If enabled, adds Green Argemia Plush to scrap pool."); dingusEnabled = AddBoolConfig("Scrap", "DingusEnabled", defaultValues: true, "If enabled, adds dingus to scrap pool."); medstationEnabled = AddBoolConfig("Unlockables", "MedstationEnabled", defaultValues: true, "If enabled, adds the medstation unlockable."); medstationPrice = AddIntConfig("Unlockables", "MedstationPrice", 600, "Sets the price of the medstation"); medstationCharges = AddIntConfig("Unlockables", "MedstationCharges", 200, "Sets the maximum healing capacity of the medstation"); IsLoaded = true; } private bool AddBoolConfig(string section, string key, bool defaultValues, string definition) { ConfigEntry<bool> val = Plugin.Instance.Config.Bind<bool>(section, key, defaultValues, definition); configEntries.Add((ConfigEntryBase)(object)val); return val.Value; } private int AddIntConfig(string section, string key, int defaultValue, string definition) { ConfigEntry<int> val = Plugin.Instance.Config.Bind<int>(section, key, defaultValue, definition); configEntries.Add((ConfigEntryBase)(object)val); return val.Value; } public void SyncConfig(string serialized) { } public void SerializeConfig() { } } [BepInPlugin("joe1359.lethalextras", "LethalExtras", "1.0.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string ModGUID = "lethalextras"; public const string ModName = "LethalExtras"; public const string ModVersion = "1.0.4"; public static AssetBundle MainAssets; public static List<UnlockableItem> unlockables = new List<UnlockableItem>(); public static BaseUnityPlugin Instance { get; private set; } public static Config ModConfig { get; private set; } public static ManualLogSource logger { get; private set; } private Plugin() { HarmonyPatcher.ApplyHarmonyPatches(); } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = (BaseUnityPlugin)(object)this; } PatchNetcode(); if (ModConfig == null) { ModConfig = new Config(); ModConfig.Load(); } logger = Logger.CreateLogSource("lethalextras"); logger.LogInfo((object)"Plugin LethalExtras is loaded!"); MainAssets = AssetBundle.LoadFromFile(Assembly.GetExecutingAssembly().Location.Replace("LethalExtras.dll", "lethalextras")); InitializeScrap(); InitializeUnlockables(); } public void InitializeScrap() { InitializeScrapItem("Assets/LethalExtras/scrap/blahaj/blahaj.asset", 5, (LevelTypes)510, ModConfig.blahajEnabled); InitializeScrapItem("Assets/LethalExtras/scrap/ArgemiaPlush/RedArgemiaPlush.asset", 20, (LevelTypes)510, ModConfig.redArgemiaEnabled); InitializeScrapItem("Assets/LethalExtras/scrap/ArgemiaPlush/BlueArgemiaPlush.asset", 10, (LevelTypes)44, ModConfig.blueArgemiaEnabled); InitializeScrapItem("Assets/LethalExtras/scrap/ArgemiaPlush/GreenArgemiaPlush.asset", 2, (LevelTypes)448, ModConfig.greenArgemiaEnabled); InitializeScrapItem("Assets/LethalExtras/scrap/maxwell/dingus.asset", 4, (LevelTypes)510, ModConfig.dingusEnabled); } public void InitializeUnlockables() { AddUnlockableItem("Medstation", "Assets/LethalExtras/buyable/placeable/medstation/MedstationContainer.prefab", LethalExtras.UnlockableItems.UnlockableItems.UnlockableTypes.Placeable, ModConfig.medstationEnabled, ModConfig.medstationPrice); } private UnlockableItem AddUnlockableItem(string unlockableName, string asset, LethalExtras.UnlockableItems.UnlockableItems.UnlockableTypes unlockableType, bool enabled = true, int price = 0) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown GameObject val = LoadPrefabFromAsset(asset); if ((Object)(object)val == (Object)null) { return null; } if (!enabled) { return null; } UnlockableItem val2 = new UnlockableItem(); val2.unlockableName = unlockableName; val2.prefabObject = val; val2.unlockableType = (int)unlockableType; val2.alwaysInStock = true; val2.IsPlaceable = true; Unlockables.RegisterUnlockable(val2, (StoreType)1, (TerminalNode)null, (TerminalNode)null, (TerminalNode)null, price); logger.LogInfo((object)("Loading unlockable: " + unlockableName)); return val2; } private GameObject LoadPrefabFromAsset(string asset) { if ((Object)(object)MainAssets == (Object)null) { return null; } GameObject val = MainAssets.LoadAsset<GameObject>(asset); if ((Object)(object)val == (Object)null) { return null; } NetworkPrefabs.RegisterNetworkPrefab(val); return val; } private Item LoadItemFromAsset(string asset) { if ((Object)(object)MainAssets == (Object)null) { return null; } Item val = MainAssets.LoadAsset<Item>(asset); if ((Object)(object)val == (Object)null) { return null; } NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab); return val; } private Item CreateItemVariant(Item item, string name, int value, string mesh = null, string material = null) { if ((Object)(object)item == (Object)null) { return null; } Item val = Object.Instantiate<Item>(item); val.itemName = name; val.creditsWorth = value; if (mesh != null) { MeshFilter component = val.spawnPrefab.GetComponent<MeshFilter>(); Mesh[] meshVariants = val.meshVariants; foreach (Mesh val2 in meshVariants) { if (((Object)val2).name == mesh) { component.mesh = val2; break; } } } if (material != null) { MeshRenderer component2 = val.spawnPrefab.GetComponent<MeshRenderer>(); Material[] materialVariants = val.materialVariants; foreach (Material val3 in materialVariants) { if (((Object)val3).name == material) { ((Renderer)component2).material = val3; break; } } } NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab); return val; } private void RegisterScrapItem(Item item, int rarity, LevelTypes levelTypes) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)item == (Object)null)) { Items.RegisterScrap(item, rarity, levelTypes); logger.LogInfo((object)("Adding scrap item variant: " + ((Object)item).name)); } } private Item InitializeScrapItem(string asset, int rarity, LevelTypes levelTypes, bool enabled = true) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)MainAssets == (Object)null) { return null; } Item val = LoadItemFromAsset(asset); logger.LogInfo((object)("Loading item: " + val.itemName)); if (!enabled) { return null; } Items.RegisterScrap(val, rarity, levelTypes); logger.LogInfo((object)("Adding to scrap pool: " + val.itemName)); return val; } private Item RegisterShopItem(Item item, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = 0) { if ((Object)(object)item == (Object)null) { return null; } Items.RegisterShopItem(item, price); logger.LogInfo((object)("Adding shop item: " + item.itemName)); return item; } private Item InitializeShopItem(string asset, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = 0) { if ((Object)(object)MainAssets == (Object)null) { return null; } Item val = LoadItemFromAsset(asset); Items.RegisterShopItem(val, price); logger.LogInfo((object)("Adding shop item: " + asset)); return val; } private void PatchNetcode() { 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); } } } } } public static class PluginInfo { public const string PLUGIN_GUID = "LethalExtras"; public const string PLUGIN_NAME = "LethalExtras"; public const string PLUGIN_VERSION = "0.1.0"; } } namespace LethalExtras.UnlockableItems { public class Medstation : NetworkBehaviour { private NetworkVariable<int> maxCharges = new NetworkVariable<int>(Plugin.ModConfig.medstationCharges, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); private NetworkVariable<int> charges = new NetworkVariable<int>(Plugin.ModConfig.medstationCharges, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); public Transform healthCylinderTransform; public InteractTrigger medstationTrigger; public AudioClip medstationStartSFX; public AudioClip medstationInProgressSFX; public AudioClip medstationEndSFX; public AudioSource medstationAudio; private int unlockableId; private string dataKey; private MedstationState medstationState = MedstationState.WAITING; private void Awake() { if (!((Object)(object)this == (Object)null)) { } } public override void OnNetworkSpawn() { ((NetworkVariableBase)maxCharges).Initialize((NetworkBehaviour)(object)this); ((NetworkVariableBase)charges).Initialize((NetworkBehaviour)(object)this); dataKey = "LethalExtrasData_Unlockables_MedstationCharges"; if (ES3.KeyExists(dataKey, GameNetworkManager.Instance.currentSaveFileName)) { charges.Value = ES3.Load<int>(dataKey, GameNetworkManager.Instance.currentSaveFileName, charges.Value); } } private void Update() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)this == (Object)null) { return; } if (medstationTrigger.interactable) { float num = (float)charges.Value / (float)maxCharges.Value; int num2 = (int)(num * 100f); medstationTrigger.holdTip = $"[Charges: {num2}%]"; healthCylinderTransform.localScale = new Vector3(1f, num, 1f); } if (charges.Value > 0) { medstationTrigger.interactable = true; if (medstationTrigger.isBeingHeldByPlayer) { medstationState = MedstationState.HEALING; } else { medstationState = MedstationState.WAITING; } } else { medstationTrigger.disabledHoverTip = "[No charges remaining]"; charges.Value = 0; } } private void OnDisable() { } public void PressMedstationOnLocalClient() { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) PressMedstationServerRpc(); } [ServerRpc(RequireOwnership = false)] public void PressMedstationServerRpc(ServerRpcParams serverRpcParams = default(ServerRpcParams)) { //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_00de: 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) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(1486470394u, serverRpcParams, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 1486470394u, serverRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { NetworkManager networkManager2 = ((NetworkBehaviour)this).NetworkManager; if (!((Object)(object)networkManager2 == (Object)null) && networkManager2.IsListening) { ulong senderClientId = serverRpcParams.Receive.SenderClientId; HealPlayerServer(senderClientId); HealPlayerClientRpc(senderClientId); } } } [ClientRpc] public void HealPlayerClientRpc(ulong clientId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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(2759607538u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, clientId); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2759607538u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost) || !((NetworkBehaviour)this).IsClient) { return; } int num = 5; PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if (localPlayerController.actualClientId == clientId && localPlayerController.health != 100) { if (charges.Value <= num && charges.Value > 0) { num = charges.Value; } num = Math.Min(num, 100 - localPlayerController.health); localPlayerController.health += num; if (localPlayerController.health == 100) { localPlayerController.MakeCriticallyInjured(false); } HUDManager.Instance.UpdateHealthUI(localPlayerController.health, true); } } private void HealPlayerServer(ulong clientId) { if (!((NetworkBehaviour)this).IsHost) { return; } int num = 5; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (val.actualClientId != clientId || val.health == 100) { continue; } if (val.health != 100) { if (charges.Value <= num && charges.Value > 0) { num = charges.Value; } num = Math.Min(num, 100 - val.health); val.health += num; val.MakeCriticallyInjured(false); NetworkVariable<int> obj = charges; obj.Value -= num; ES3.Save<int>(dataKey, charges.Value, GameNetworkManager.Instance.currentSaveFileName); } break; } } private void PressButtonEffects() { if (medstationState == MedstationState.WAITING) { medstationAudio.PlayOneShot(medstationStartSFX); } else if (medstationState == MedstationState.HEALING) { medstationAudio.PlayOneShot(medstationInProgressSFX); } } public void LoadCharges() { if (((NetworkBehaviour)this).IsHost) { dataKey = "LethalExtrasData_Unlockables_MedstationCharges"; if (ES3.KeyExists(dataKey, GameNetworkManager.Instance.currentSaveFileName)) { charges.Value = ES3.Load<int>(dataKey, GameNetworkManager.Instance.currentSaveFileName, charges.Value); } } } public void SetCharges(int charges) { if (((NetworkBehaviour)this).IsHost) { Plugin.logger.LogInfo((object)$"before - {this.charges.Value}"); if (charges > maxCharges.Value) { charges = maxCharges.Value; } this.charges.Value = charges; Plugin.logger.LogInfo((object)$"after - {this.charges.Value}"); } } private bool CanUseMedstation() { return false; } protected override void __initializeVariables() { if (maxCharges == null) { throw new Exception("Medstation.maxCharges cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)maxCharges).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)maxCharges, "maxCharges"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)maxCharges); if (charges == null) { throw new Exception("Medstation.charges cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)charges).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)charges, "charges"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)charges); ((NetworkBehaviour)this).__initializeVariables(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_Medstation() { //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(1486470394u, new RpcReceiveHandler(__rpc_handler_1486470394)); NetworkManager.__rpc_func_table.Add(2759607538u, new RpcReceiveHandler(__rpc_handler_2759607538)); } private static void __rpc_handler_1486470394(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ServerRpcParams server = rpcParams.Server; target.__rpc_exec_stage = (__RpcExecStage)1; ((Medstation)(object)target).PressMedstationServerRpc(server); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2759607538(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { ulong clientId = default(ulong); ByteUnpacker.ReadValueBitPacked(reader, ref clientId); target.__rpc_exec_stage = (__RpcExecStage)2; ((Medstation)(object)target).HealPlayerClientRpc(clientId); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "Medstation"; } } public enum MedstationState { WAITING, HEALING } public class UnlockableItems { public enum UnlockableTypes { Suit, Placeable } } } namespace LethalExtras.Patches { public class HarmonyPatcher { private static Harmony instance; public const string InstanceId = "LethalExtras"; public static bool IsPatched { get; private set; } internal static void ApplyHarmonyPatches() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown if (!IsPatched) { if (instance == null) { instance = new Harmony("LethalExtras"); } instance.PatchAll(Assembly.GetExecutingAssembly()); IsPatched = true; } } internal static void RemoveHarmonyPatches() { if (instance != null && IsPatched) { instance.UnpatchSelf(); IsPatched = false; } } } [HarmonyPatch(typeof(RoundManager))] internal class RoundManagerPatch { [HarmonyPatch("GeneratedFloorPostProcessing")] [HarmonyPrefix] private static void GeneratedFloorPostProcessingPatch(ref RoundManager __instance) { if (!((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsHost) { string text = "LethalExtrasData_Unlockables_MedstationCharges"; if (ES3.KeyExists(text, GameNetworkManager.Instance.currentSaveFileName)) { ES3.Save<int>(text, Plugin.ModConfig.medstationCharges, GameNetworkManager.Instance.currentSaveFileName); } Medstation[] array = Object.FindObjectsOfType<Medstation>(); Medstation[] array2 = array; foreach (Medstation medstation in array2) { medstation.LoadCharges(); } } } } }