Decompiled source of 45x Suit Variants v3.0.4

45x Suit Variants.dll

Decompiled 4 months ago
using 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.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using LethalNetworkAPI;
using Microsoft.CodeAnalysis;
using ModelReplacement;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[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("45x Suit Variants")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("45x Suit Variants")]
[assembly: AssemblyTitle("45x Suit Variants")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 ffxsuitvariants
{
	internal class SuitRegistry : Dictionary<string, VariantRegistry>
	{
		public string ActiveSuit = "Default";

		public VariantRegistry GetActiveVariantRegistry()
		{
			return base[ActiveSuit];
		}
	}
	internal class SyncData
	{
		public string ActiveSuit;

		public string ActiveVariant;

		public ulong SendingClientID;

		public ulong RequestingClientID;

		public SyncData(string activeSuit, string activeVariant, ulong sendingClientID, ulong requestingClientID = 0uL)
		{
			ActiveSuit = activeSuit;
			ActiveVariant = activeVariant;
			SendingClientID = sendingClientID;
			RequestingClientID = requestingClientID;
			base..ctor();
		}
	}
	internal class VariantRegistry : Dictionary<string, Type>
	{
		public string ActiveVariant = "";

		public Type GetActiveVariantType()
		{
			return base[ActiveVariant];
		}

		public Type NextVariant()
		{
			int num = 0;
			using (Dictionary<string, Type>.Enumerator enumerator = GetEnumerator())
			{
				while (enumerator.MoveNext() && !(enumerator.Current.Key == ActiveVariant))
				{
					num++;
				}
			}
			num++;
			if (num == base.Count)
			{
				num = 0;
			}
			ActiveVariant = this.ElementAt(num).Key;
			return this.ElementAt(num).Value;
		}
	}
	public class VariantSwitchInput : LcInputActions
	{
		public static VariantSwitchInput Instance = new VariantSwitchInput();

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction SwitchSuitVariantKey { get; set; }
	}
	[BepInPlugin("dev.45x.45xsuitvariants", "45x Suit Variants", "3.0.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class FFXSuitVariants : BaseUnityPlugin
	{
		internal static SuitRegistry RegisteredSuits = new SuitRegistry();

		internal static ManualLogSource Logger { get; private set; } = null;


		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Loading Plugin: dev.45x.45xsuitvariants");
			Stopwatch stopwatch = Stopwatch.StartNew();
			Patch();
			stopwatch.Stop();
			Logger.LogInfo((object)string.Format("{0} has loaded! Took {1}ms", "dev.45x.45xsuitvariants", stopwatch.ElapsedMilliseconds));
		}

		internal static void RegisterSuit(string name, Type type)
		{
			if (!RegisteredSuits.ContainsKey(name))
			{
				Logger.LogInfo((object)("Registering parent suit \"" + name + "\"."));
				RegisteredSuits.Add(name, new VariantRegistry());
				RegisteredSuits[name].ActiveVariant = name;
				ModelReplacementAPI.RegisterSuitModelReplacement(name, type);
				RegisterVariant(name, type, name);
			}
			else
			{
				Logger.LogWarning((object)("Trying to register already registered parent suit \"" + name + "\"! Please register this suit with a different name."));
			}
		}

		internal static void RegisterVariant(string name, Type type, string parentName)
		{
			if (RegisteredSuits.ContainsKey(parentName))
			{
				if (!RegisteredSuits[parentName].ContainsKey(name))
				{
					Logger.LogInfo((object)("Registering suit variant \"" + name + "\" under parent suit \"" + parentName + "\"."));
					RegisteredSuits[parentName].Add(name, type);
					if (name != parentName)
					{
						ModelReplacementAPI.RegisterModelReplacementException(type);
					}
				}
				else
				{
					Logger.LogWarning((object)("Trying to register already registered variant \"" + name + "\" under parent suit \"" + parentName + "\"! Please register this variant with a different name or under a different parent."));
				}
			}
			else
			{
				Logger.LogWarning((object)("Trying to register variant (\"" + name + "\") under non-registered parent suit! Please register the parent suit first."));
			}
		}

		internal static void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("dev.45x.45xsuitvariants");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}
	}
}
namespace ffxsuitvariants.Patches
{
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class Patch_PlayerControllerB : MonoBehaviour
	{
		public static PlayerControllerB? LocalPlayerController;

		private static readonly LNetworkMessage<int> GetSuitVariantMessage;

		private static readonly LNetworkMessage<SyncData> ReplyGetSuitVariantMessage;

		internal static readonly LNetworkMessage<SyncData> SwitchSuitVariantMessage;

		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		private static void Awake()
		{
			if (!((Object)(object)HUDManager.Instance != (Object)null))
			{
				return;
			}
			PlayerControllerB[] array = Object.FindObjectsOfType<PlayerControllerB>();
			for (int i = 0; i < array.Length; i++)
			{
				if (((NetworkBehaviour)array[i]).IsOwner)
				{
					LocalPlayerController = array[i];
				}
			}
			VariantSwitchInput.Instance.SwitchSuitVariantKey.performed += OnSuitSwitchKeyPressed;
			GetSuitVariantMessage.SendOtherClients(0);
			if (!((NetworkBehaviour)LocalPlayerController).IsServer)
			{
				GetSuitVariantMessage.SendServer(0);
				if (FFXSuitVariants.RegisteredSuits.ContainsKey(FFXSuitVariants.RegisteredSuits.ActiveSuit) && FFXSuitVariants.RegisteredSuits[FFXSuitVariants.RegisteredSuits.ActiveSuit].ContainsKey(FFXSuitVariants.RegisteredSuits.GetActiveVariantRegistry().ActiveVariant))
				{
					ReplyGetSuitVariantMessage.SendServer(new SyncData(FFXSuitVariants.RegisteredSuits.ActiveSuit, FFXSuitVariants.RegisteredSuits.GetActiveVariantRegistry().ActiveVariant, LethalNetworkExtensions.GetClientId(LocalPlayerController), 0uL));
				}
			}
		}

		public static void OnSuitSwitchKeyPressed(CallbackContext ctx)
		{
			if (!((Object)(object)LocalPlayerController == (Object)null) && ((CallbackContext)(ref ctx)).performed && !LocalPlayerController.isPlayerDead && !LocalPlayerController.isTypingChat && !Object.op_Implicit((Object)(object)LocalPlayerController.inAnimationWithEnemy) && !LocalPlayerController.inTerminalMenu && LocalPlayerController.isInHangarShipRoom)
			{
				SwitchSuitVariant(LocalPlayerController);
			}
		}

		public static void SwitchSuitVariant(PlayerControllerB LocalPlayerController)
		{
			if (FFXSuitVariants.RegisteredSuits.ContainsKey(FFXSuitVariants.RegisteredSuits.ActiveSuit) && FFXSuitVariants.RegisteredSuits.GetActiveVariantRegistry().Count > 1)
			{
				ModelReplacementAPI.SetPlayerModelReplacement(LocalPlayerController, FFXSuitVariants.RegisteredSuits.GetActiveVariantRegistry().NextVariant());
				LocalPlayerController.movementAudio.PlayOneShot(StartOfRound.Instance.changeSuitSFX);
				SwitchSuitVariantMessage.SendOtherClients(new SyncData(FFXSuitVariants.RegisteredSuits.ActiveSuit, FFXSuitVariants.RegisteredSuits.GetActiveVariantRegistry().ActiveVariant, LethalNetworkExtensions.GetClientId(LocalPlayerController), 0uL));
				if (!((NetworkBehaviour)LocalPlayerController).IsServer)
				{
					SwitchSuitVariantMessage.SendServer(new SyncData(FFXSuitVariants.RegisteredSuits.ActiveSuit, FFXSuitVariants.RegisteredSuits.GetActiveVariantRegistry().ActiveVariant, LethalNetworkExtensions.GetClientId(LocalPlayerController), 0uL));
				}
			}
		}

		internal static void OnSwitchSuitVariantReceived(SyncData SyncData, ulong SendingClientID)
		{
			if (SyncData.SendingClientID != LethalNetworkExtensions.GetClientId(LocalPlayerController) && FFXSuitVariants.RegisteredSuits.ContainsKey(SyncData.ActiveSuit))
			{
				if (FFXSuitVariants.RegisteredSuits[SyncData.ActiveSuit].ContainsKey(SyncData.ActiveVariant))
				{
					ModelReplacementAPI.SetPlayerModelReplacement(LethalNetworkExtensions.GetPlayerController(SyncData.SendingClientID), FFXSuitVariants.RegisteredSuits[SyncData.ActiveSuit][SyncData.ActiveVariant]);
				}
				else
				{
					ModelReplacementAPI.SetPlayerModelReplacement(LethalNetworkExtensions.GetPlayerController(SyncData.SendingClientID), FFXSuitVariants.RegisteredSuits[SyncData.ActiveSuit].First().Value);
				}
			}
		}

		internal static void OnGetSuitVariantReceived(int _, ulong SendingClientID)
		{
			ReplyGetSuitVariantMessage.SendOtherClients(new SyncData(FFXSuitVariants.RegisteredSuits.ActiveSuit, FFXSuitVariants.RegisteredSuits.GetActiveVariantRegistry().ActiveVariant, LethalNetworkExtensions.GetClientId(LocalPlayerController), SendingClientID));
		}

		internal static void OnReplyGetSuitVariantReceived(SyncData SyncData, ulong SendingClientID)
		{
			if (SyncData.RequestingClientID == LethalNetworkExtensions.GetClientId(LocalPlayerController) && FFXSuitVariants.RegisteredSuits.ContainsKey(SyncData.ActiveSuit))
			{
				if (FFXSuitVariants.RegisteredSuits[SyncData.ActiveSuit].ContainsKey(SyncData.ActiveVariant))
				{
					ModelReplacementAPI.SetPlayerModelReplacement(LethalNetworkExtensions.GetPlayerController(SyncData.SendingClientID), FFXSuitVariants.RegisteredSuits[SyncData.ActiveSuit][SyncData.ActiveVariant]);
				}
				else
				{
					ModelReplacementAPI.SetPlayerModelReplacement(LethalNetworkExtensions.GetPlayerController(SyncData.SendingClientID), FFXSuitVariants.RegisteredSuits[SyncData.ActiveSuit].First().Value);
				}
			}
		}

		static Patch_PlayerControllerB()
		{
			Action<int, ulong> action = OnGetSuitVariantReceived;
			GetSuitVariantMessage = LNetworkMessage<int>.Create("45xGetSuitVariant", (Action<int, ulong>)OnGetSuitVariantReceived, (Action<int>)null, action);
			Action<SyncData, ulong> action2 = OnReplyGetSuitVariantReceived;
			ReplyGetSuitVariantMessage = LNetworkMessage<SyncData>.Create("45xReplyGetSuitVariant", (Action<SyncData, ulong>)OnReplyGetSuitVariantReceived, (Action<SyncData>)null, action2);
			action2 = OnSwitchSuitVariantReceived;
			SwitchSuitVariantMessage = LNetworkMessage<SyncData>.Create("45xSwitchSuitVariant", (Action<SyncData, ulong>)OnSwitchSuitVariantReceived, (Action<SyncData>)null, action2);
		}
	}
	[HarmonyPatch(typeof(UnlockableSuit))]
	internal class Patch_UnlockableSuit
	{
		private static LNetworkMessage<int> RemoveSuitVariantMessage;

		[HarmonyPatch("SwitchSuitToThis")]
		[HarmonyPostfix]
		public static void SwitchSuitToThis(ref UnlockableSuit __instance, PlayerControllerB playerWhoTriggered)
		{
			if (FFXSuitVariants.RegisteredSuits.ContainsKey(FFXSuitVariants.RegisteredSuits.ActiveSuit))
			{
				FFXSuitVariants.RegisteredSuits.GetActiveVariantRegistry().ActiveVariant = FFXSuitVariants.RegisteredSuits.GetActiveVariantRegistry().ElementAt(0).Key;
			}
			FFXSuitVariants.RegisteredSuits.ActiveSuit = StartOfRound.Instance.unlockablesList.unlockables[__instance.suitID].unlockableName;
			ModelReplacementAPI.RemovePlayerModelReplacement(playerWhoTriggered);
			RemoveSuitVariantMessage.SendOtherClients(0);
			if (!((NetworkBehaviour)Patch_PlayerControllerB.LocalPlayerController).IsServer)
			{
				RemoveSuitVariantMessage.SendServer(0);
			}
		}

		internal static void OnRemoveSuitVariantReceived(int _, ulong SendingClientID)
		{
			if ((Object)(object)LethalNetworkExtensions.GetPlayerController(SendingClientID) != (Object)null)
			{
				ModelReplacementAPI.RemovePlayerModelReplacement(LethalNetworkExtensions.GetPlayerController(SendingClientID));
			}
		}

		static Patch_UnlockableSuit()
		{
			Action<int, ulong> action = OnRemoveSuitVariantReceived;
			RemoveSuitVariantMessage = LNetworkMessage<int>.Create("45xRemoveSuitVariant", (Action<int, ulong>)OnRemoveSuitVariantReceived, (Action<int>)null, action);
		}
	}
}
namespace ffxsuitvariants.API
{
	public class SuitVariantsAPI
	{
		public static void RegisterSuit(string name, Type type, string parentName = "")
		{
			if (name == "")
			{
				FFXSuitVariants.Logger.LogWarning((object)"Please specify a name when trying to register a suit or variant!");
			}
			else if (type == null)
			{
				FFXSuitVariants.Logger.LogWarning((object)"Please specify a type when trying to register a suit or variant!");
			}
			else if (parentName != "")
			{
				FFXSuitVariants.RegisterVariant(name, type, parentName);
			}
			else
			{
				FFXSuitVariants.RegisterSuit(name, type);
			}
		}

		public static void RegisterSuits<K, V>(string parentName = "", params (string name, Type type)[] suits)
		{
			if (parentName != "")
			{
				for (int i = 0; i < suits.Length; i++)
				{
					var (text, type) = suits[i];
					if (text == "")
					{
						FFXSuitVariants.Logger.LogWarning((object)"Please specify a name when trying to register a suit or variant!");
						break;
					}
					if (type == null)
					{
						FFXSuitVariants.Logger.LogWarning((object)"Please specify a type when trying to register a suit or variant!");
						break;
					}
					FFXSuitVariants.RegisterVariant(text, type, parentName);
				}
				return;
			}
			for (int j = 0; j < suits.Length; j++)
			{
				var (text2, type2) = suits[j];
				if (text2 == "")
				{
					FFXSuitVariants.Logger.LogWarning((object)"Please specify a name when trying to register a suit or variant!");
					break;
				}
				if (type2 == null)
				{
					FFXSuitVariants.Logger.LogWarning((object)"Please specify a type when trying to register a suit or variant!");
					break;
				}
				FFXSuitVariants.RegisterSuit(text2, type2);
			}
		}

		public static void RegisterSuits<K, V>((string name, Type type) parentSuit, params (string name, Type type)[] suits)
		{
			if (parentSuit.name != "")
			{
				if (parentSuit.type != null)
				{
					FFXSuitVariants.RegisterSuit(parentSuit.name, parentSuit.type);
					for (int i = 0; i < suits.Length; i++)
					{
						var (text, type) = suits[i];
						if (text == "")
						{
							FFXSuitVariants.Logger.LogWarning((object)"Please specify a name when trying to register a suit or variant!");
							break;
						}
						if (type == null)
						{
							FFXSuitVariants.Logger.LogWarning((object)"Please specify a type when trying to register a suit or variant!");
							break;
						}
						FFXSuitVariants.RegisterVariant(text, type, parentSuit.name);
					}
				}
				else
				{
					FFXSuitVariants.Logger.LogWarning((object)"Please specify a type when trying to register a suit or variant!");
				}
			}
			else
			{
				FFXSuitVariants.Logger.LogWarning((object)"Please specify a name when trying to register a suit or variant!");
			}
		}

		public static string GetCurrentSuitName()
		{
			return FFXSuitVariants.RegisteredSuits.ActiveSuit;
		}

		public static string GetCurrentVariantName()
		{
			if (FFXSuitVariants.RegisteredSuits.ContainsKey(FFXSuitVariants.RegisteredSuits.ActiveSuit))
			{
				return FFXSuitVariants.RegisteredSuits.GetActiveVariantRegistry().ActiveVariant;
			}
			return "";
		}
	}
}