Decompiled source of ClassicSuitRestoration v2.1.0

ClassicSuitRestoration.dll

Decompiled a month ago
using 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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
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: 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.0.0")]
[assembly: AssemblyInformationalVersion("2.1.0+1093e4ce631c5fda2461a60cd760b7d57d0d31e9")]
[assembly: AssemblyProduct("ClassicSuitRestoration")]
[assembly: AssemblyTitle("ClassicSuitRestoration")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.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 ClassicSuitRestoration
{
	[BepInPlugin("butterystancakes.lethalcompany.classicsuitrestoration", "Classic Suit Restoration", "2.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string PLUGIN_GUID = "butterystancakes.lethalcompany.classicsuitrestoration";

		private const string PLUGIN_NAME = "Classic Suit Restoration";

		private const string PLUGIN_VERSION = "2.1.0";

		public static ConfigEntry<bool> configUnlockable;

		public static ConfigEntry<bool> configOfficial;

		public static ConfigEntry<bool> configBirthday;

		internal static ManualLogSource Logger;

		private void Awake()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			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 = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Classic Suit Restoration v2.1.0 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_0170: 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";
				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.DayOfYear == new DateTime(2023, 10, 23).DayOfYear)
						{
							val2.unlockableName = "Birthday suit";
							val2.headCostumeObject = val3.LoadAsset<GameObject>("PartyHatContainer");
						}
						else
						{
							val2.unlockableName = "Brown suit";
						}
					}
					else
					{
						val4 = val3.LoadAsset<Texture>("OldSuitMockUp");
						val2.suitMaterial.SetColor("_BaseColor", Color.white);
						val2.suitMaterial.SetTexture("_NormalMap", val3.LoadAsset<Texture>("ScavengerPlayerModel 1"));
						val2.unlockableName = "Classic suit";
					}
					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.FindObjectsOfType<UnlockableSuit>();
			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;
				}
			}
			typeof(StartOfRound).GetMethod("SpawnUnlockable", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(StartOfRound.Instance, new object[1] { classicSuitIndex });
		}

		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.FindObjectsOfType<UnlockableSuit>();
			foreach (UnlockableSuit val in array)
			{
				list.Add(val.syncedSuitID.Value);
				Plugin.Logger.LogInfo((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.LogInfo((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.0";
	}
}
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();
			}
		}
	}
}