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 ClassicSuitRestoration v2.1.3
ClassicSuitRestoration.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; 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.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using LobbyCompatibility.Enums; using LobbyCompatibility.Features; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("ClassicSuitRestoration")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Adds an additional suit similar to the tan suits in the game's announcement teaser.")] [assembly: AssemblyFileVersion("2.1.3.0")] [assembly: AssemblyInformationalVersion("2.1.3+d75d4c3fd3a0241e41d9903f3f656d7ebae981cb")] [assembly: AssemblyProduct("ClassicSuitRestoration")] [assembly: AssemblyTitle("ClassicSuitRestoration")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.1.3.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 ClassicSuitRestoration { internal static class LobbyCompatibility { internal static void Init() { PluginHelper.RegisterPlugin("butterystancakes.lethalcompany.classicsuitrestoration", Version.Parse("2.1.3"), (CompatibilityLevel)2, (VersionStrictness)0); } } [BepInPlugin("butterystancakes.lethalcompany.classicsuitrestoration", "Classic Suit Restoration", "2.1.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal const string PLUGIN_GUID = "butterystancakes.lethalcompany.classicsuitrestoration"; internal const string PLUGIN_NAME = "Classic Suit Restoration"; internal const string PLUGIN_VERSION = "2.1.3"; public static ConfigEntry<bool> configUnlockable; public static ConfigEntry<bool> configOfficial; public static ConfigEntry<bool> configBirthday; private const string GUID_LOBBY_COMPATIBILITY = "BMX.LobbyCompatibility"; private const string GUID_KEEP_UNLOCKS = "butterystancakes.lethalcompany.keepunlocks"; internal static ManualLogSource Logger; private void Awake() { //IL_0095: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility")) { Logger.LogInfo((object)"CROSS-COMPATIBILITY - Lobby Compatibility detected"); LobbyCompatibility.Init(); } configOfficial = ((BaseUnityPlugin)this).Config.Bind<bool>("Suit", "Official", true, "Uses the official brown suit texture from v65.\nNOTE: This texture is official, but it is a recreation in the final game's visual style, and not the actual suit texture from earlier versions of the game."); configBirthday = ((BaseUnityPlugin)this).Config.Bind<bool>("Suit", "Birthday", false, "If using the anniversary suit (from the \"Official\" setting), this will complete the costume by adding back the party hat as well."); configUnlockable = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "Unlockable", false, "Instead of making the suit always available, unlock it once you complete a quota with all other suits on the rack."); new Harmony("butterystancakes.lethalcompany.classicsuitrestoration").PatchAll(); Logger.LogInfo((object)"Classic Suit Restoration v2.1.3 loaded"); } } internal class RestoreClassicSuit { internal static int classicSuitIndex = -1; internal static void InitClassicSuit() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) UnlockablesList val = null; if ((Object)(object)StartOfRound.Instance != (Object)null) { val = StartOfRound.Instance.unlockablesList; } if ((Object)(object)val == (Object)null) { Plugin.Logger.LogWarning((object)"Trying to edit unlockables when StartOfRound is not initialized yet, this shouldn't happen normally"); UnlockablesList[] array = Resources.FindObjectsOfTypeAll<UnlockablesList>(); if (array == null || array.Length < 1) { Plugin.Logger.LogError((object)"Can't find unlockables list"); return; } val = array[0]; } UnlockableItem val2 = ((IEnumerable<UnlockableItem>)val.unlockables).FirstOrDefault((Func<UnlockableItem, bool>)delegate(UnlockableItem unlockable) { Material suitMaterial = unlockable.suitMaterial; return ((suitMaterial != null) ? ((Object)suitMaterial).name : null) == "OldSuit"; }); if (val2 == null) { val2 = new UnlockableItem { suitMaterial = Object.Instantiate<Material>(val.unlockables[0].suitMaterial), headCostumeObject = null }; ((Object)val2.suitMaterial).name = "OldSuit"; val2.unlockableName = "Brown suit"; try { AssetBundle val3 = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "classicsuitrestoration")); Texture val4 = null; if (Plugin.configOfficial.Value) { val4 = val3.LoadAsset<Texture>("ScavengerPlayerModel"); if (Plugin.configBirthday.Value || (DateTime.Today.Month == 10 && DateTime.Today.Day == 23)) { val2.headCostumeObject = val3.LoadAsset<GameObject>("PartyHatContainer"); } } else { val4 = val3.LoadAsset<Texture>("OldSuitMockUp"); val2.suitMaterial.SetColor("_BaseColor", Color.white); val2.suitMaterial.SetTexture("_NormalMap", val3.LoadAsset<Texture>("ScavengerPlayerModel 1")); } val2.suitMaterial.SetTexture("_MainTex", val4); val2.suitMaterial.SetTexture("_BaseColorMap", val4); val3.Unload(false); } catch (Exception ex) { Plugin.Logger.LogError((object)"Failed to acquire suit texture from asset bundle"); Plugin.Logger.LogError((object)ex.Message); } classicSuitIndex = val.unlockables.Count; val.unlockables.Add(val2); } else { Plugin.Logger.LogWarning((object)"Tried to add classic suit to unlockables list twice"); classicSuitIndex = val.unlockables.IndexOf(val2); } } internal static void SpawnClassicSuit() { InitClassicSuit(); if (classicSuitIndex <= 0 || !((NetworkBehaviour)StartOfRound.Instance).IsServer || StartOfRound.Instance.isChallengeFile || StartOfRound.Instance.SpawnedShipUnlockables.ContainsKey(classicSuitIndex)) { return; } UnlockableSuit[] array = Object.FindObjectsByType<UnlockableSuit>((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { if (array[i].syncedSuitID.Value == classicSuitIndex) { Plugin.Logger.LogWarning((object)"Tried to spawn another classic suit on the rack while one already existed"); return; } } StartOfRound.Instance.SpawnUnlockable(classicSuitIndex, false); } internal static void UnlockClassicSuit() { if (Plugin.configUnlockable.Value && ((NetworkBehaviour)StartOfRound.Instance).IsServer && !StartOfRound.Instance.isChallengeFile) { ES3.Save<bool>("ClassicSuitRestoration_Unlocked", true, GameNetworkManager.Instance.currentSaveFileName); } SpawnClassicSuit(); } internal static bool HasAllOtherSuits() { List<int> list = new List<int>(); UnlockableSuit[] array = Object.FindObjectsByType<UnlockableSuit>((FindObjectsSortMode)0); foreach (UnlockableSuit val in array) { list.Add(val.syncedSuitID.Value); Plugin.Logger.LogDebug((object)$"Player owns suit #{val.syncedSuitID.Value} - \"{StartOfRound.Instance.unlockablesList.unlockables[val.syncedSuitID.Value].unlockableName}\""); } for (int j = 1; j < classicSuitIndex; j++) { if (StartOfRound.Instance.unlockablesList.unlockables[j].unlockableType == 0 && !list.Contains(j)) { Plugin.Logger.LogDebug((object)$"Player doesn't have #{j} - \"{StartOfRound.Instance.unlockablesList.unlockables[j].unlockableName}\""); return false; } } Plugin.Logger.LogInfo((object)"Player will unlock classic suit"); return true; } internal static IEnumerator CheckSuitsAfterDelay() { yield return (object)new WaitForSeconds(2f); if (!Plugin.configUnlockable.Value) { SpawnClassicSuit(); } else if (HasAllOtherSuits()) { UnlockClassicSuit(); } } } public static class PluginInfo { public const string PLUGIN_GUID = "ClassicSuitRestoration"; public const string PLUGIN_NAME = "ClassicSuitRestoration"; public const string PLUGIN_VERSION = "2.1.3"; } } namespace ClassicSuitRestoration.Patches { [HarmonyPatch] internal class ClassicSuitRestorationPatches { [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPostfix] public static void StartOfRoundPostAwake() { RestoreClassicSuit.InitClassicSuit(); } [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPostfix] public static void StartOfRoundPostStart() { if (!Plugin.configUnlockable.Value || ES3.Load<bool>("ClassicSuitRestoration_Unlocked", GameNetworkManager.Instance.currentSaveFileName, false)) { RestoreClassicSuit.SpawnClassicSuit(); } } [HarmonyPatch(typeof(StartOfRound), "ResetShip")] [HarmonyPostfix] public static void PostResetShip(StartOfRound __instance) { if (((NetworkBehaviour)__instance).IsServer && (Object)(object)GameNetworkManager.Instance != (Object)null) { ES3.DeleteKey("ClassicSuitRestoration_Unlocked", GameNetworkManager.Instance.currentSaveFileName); } ((MonoBehaviour)__instance).StartCoroutine(RestoreClassicSuit.CheckSuitsAfterDelay()); } [HarmonyPatch(typeof(UnlockableSuit), "Update")] [HarmonyPrefix] public static void UnlockableSuitPreUpdate(UnlockableSuit __instance) { if ((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)NetworkManager.Singleton != (Object)null && !NetworkManager.Singleton.ShutdownInProgress && __instance.suitID != __instance.syncedSuitID.Value && __instance.syncedSuitID.Value >= StartOfRound.Instance.unlockablesList.unlockables.Count) { RestoreClassicSuit.InitClassicSuit(); } } [HarmonyPatch(typeof(UnlockableSuit), "SwitchSuitForPlayer")] [HarmonyPrefix] public static void PreSwitchSuitForPlayer(ref int suitID) { if (suitID >= StartOfRound.Instance.unlockablesList.unlockables.Count) { RestoreClassicSuit.InitClassicSuit(); suitID = RestoreClassicSuit.classicSuitIndex; } } [HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")] [HarmonyPostfix] public static void PostSetNewProfitQuota() { if (Plugin.configUnlockable.Value && RestoreClassicSuit.HasAllOtherSuits()) { RestoreClassicSuit.UnlockClassicSuit(); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }