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 "";
}
}
}