Decompiled source of LCTransition v1.1.0

LCTransition.dll

Decompiled 4 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Resources;
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 LCTransition;
using LethalExpansionCore.Utils;
using Microsoft.CodeAnalysis;
using ModelReplacement;
using ThiccCompany.Replacements;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.SceneManagement;

[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: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ModelReplacementAPI")]
[assembly: IgnoresAccessChecksTo("UnityEngine")]
[assembly: AssemblyCompany("LCTransition")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Allows MTF transitioning in Lethal Company")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("LCTransition")]
[assembly: AssemblyTitle("LCTransition")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializable<NetworkData>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<NetworkData>();
	}
}
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 LCTransition
{
	[BepInPlugin("LCTransition", "LCTransition", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static Dictionary<string, Type> FemModels = new Dictionary<string, Type>();

		public static ManualLogSource logger;

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin LCTransition is loaded!");
			Harmony val = new Harmony("LCTransition");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			val.PatchAll();
			NetcodeWeaver();
			OverrideThiccCompanyConfig();
			SceneManager.sceneLoaded += OnSceneLoaded;
			logger = ((BaseUnityPlugin)this).Logger;
		}

		private void NetcodeWeaver()
		{
			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);
					}
				}
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			CustomiseBlahajSettings();
		}

		private void OverrideThiccCompanyConfig()
		{
			foreach (var (key, type2) in ModelReplacementAPI.RegisteredModelReplacements)
			{
				if (type2.Assembly == typeof(DefaultOrangeReplacement).Assembly)
				{
					FemModels.Add(key, type2);
				}
			}
			ModelReplacementAPI.RegisteredModelReplacements.Clear();
			ModelReplacementAPI.RegisteredModelReplacementDefault = null;
			ModelReplacementAPI.RegisteredModelReplacementExceptions.Clear();
			ModelReplacementAPI.RegisteredModelReplacementOverride = null;
		}

		private void CustomiseBlahajSettings()
		{
			if (AssetGather.Instance.scraps.ContainsKey("blahaj"))
			{
				AssetGather.Instance.scraps["blahaj"].twoHanded = true;
			}
		}
	}
	public struct NetworkData : IEquatable<NetworkData>, INetworkSerializable
	{
		public ulong steamId;

		public bool feminised;

		public NetworkData(ulong steamId)
		{
			feminised = false;
			this.steamId = steamId;
		}

		public bool Equals(NetworkData other)
		{
			return steamId == other.steamId && feminised == other.feminised;
		}

		public unsafe void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			((BufferSerializer<ulong>*)(&serializer))->SerializeValue<ulong>(ref steamId, default(ForPrimitives));
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref feminised, default(ForPrimitives));
		}
	}
	public struct ServerData
	{
		public ulong steamId;

		public int feminisationLevels;

		public ServerData(ulong steamId)
		{
			feminisationLevels = 0;
			this.steamId = steamId;
		}
	}
	public class NetworkHandler : NetworkBehaviour
	{
		private const int FEMINISATION_THRESHOLD = 5400;

		public NetworkList<NetworkData> networkData = new NetworkList<NetworkData>();

		public Dictionary<ulong, ServerData> serverData = new Dictionary<ulong, ServerData>();

		private Type defaultFemModel;

		public static NetworkHandler Instance { get; private set; }

		public void Awake()
		{
			defaultFemModel = typeof(DefaultOrangeReplacement);
			foreach (Type value in Plugin.FemModels.Values)
			{
				ModelReplacementAPI.RegisterModelReplacementException(value);
			}
		}

		public override void OnNetworkSpawn()
		{
			if ((NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) && (Object)(object)Instance != (Object)null)
			{
				((Component)Instance).gameObject.GetComponent<NetworkObject>().Despawn(true);
			}
			Instance = this;
			((NetworkBehaviour)this).OnNetworkSpawn();
			Load();
		}

		private IDictionary<ulong, int> getNetworkDataIndexesBySteamId()
		{
			Dictionary<ulong, int> dictionary = new Dictionary<ulong, int>();
			for (int i = 0; i < networkData.Count; i++)
			{
				dictionary[networkData[i].steamId] = i;
			}
			return dictionary;
		}

		public void Update()
		{
			PlayerControllerB[] array = Object.FindObjectsOfType<PlayerControllerB>();
			IDictionary<ulong, int> networkDataIndexesBySteamId = getNetworkDataIndexesBySteamId();
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				PlayerControllerB[] array2 = array;
				foreach (PlayerControllerB val in array2)
				{
					if (!networkDataIndexesBySteamId.ContainsKey(val.playerSteamId))
					{
						NetworkData networkData = new NetworkData(val.playerSteamId);
						this.networkData.Add(networkData);
						networkDataIndexesBySteamId[val.playerSteamId] = this.networkData.Count - 1;
					}
					if (!serverData.ContainsKey(val.playerSteamId))
					{
						serverData[val.playerSteamId] = new ServerData(val.playerSteamId);
					}
					int num = networkDataIndexesBySteamId[val.playerSteamId];
					GrabbableObject currentlyHeldObjectServer = val.currentlyHeldObjectServer;
					if (!val.isPlayerDead && (Object)(object)currentlyHeldObjectServer != (Object)null && ((Object)currentlyHeldObjectServer.itemProperties).name == "blahaj")
					{
						ServerData value = serverData[val.playerSteamId];
						value.feminisationLevels++;
						serverData[val.playerSteamId] = value;
					}
					if (val.isPlayerDead)
					{
						NetworkData networkData2 = this.networkData[num];
						networkData2.feminised = false;
						this.networkData[num] = networkData2;
						ServerData value2 = serverData[val.playerSteamId];
						value2.feminisationLevels = 0;
						serverData[val.playerSteamId] = value2;
					}
					if (!val.isPlayerDead && val.isPlayerAlone)
					{
						NetworkData networkData3 = this.networkData[num];
						if (serverData[val.playerSteamId].feminisationLevels >= 5400)
						{
							networkData3.feminised = true;
							this.networkData[num] = networkData3;
						}
					}
				}
			}
			PlayerControllerB[] array3 = array;
			BodyReplacementBase val4 = default(BodyReplacementBase);
			foreach (PlayerControllerB val2 in array3)
			{
				int num2 = networkDataIndexesBySteamId[val2.playerSteamId];
				if (this.networkData[num2].feminised)
				{
					UnlockableItem val3 = StartOfRound.Instance.unlockablesList.unlockables[val2.currentSuitID];
					Type type = defaultFemModel;
					string key = val3.unlockableName.ToLower().Replace(" ", "");
					bool flag = Plugin.FemModels.ContainsKey(key);
					if (flag)
					{
						type = Plugin.FemModels[key];
					}
					ModelReplacementAPI.SetPlayerModelReplacement(val2, type);
					if (!flag && ModelReplacementAPI.GetPlayerModelReplacement(val2, ref val4))
					{
						((Renderer)val4.replacementModel.GetComponentInChildren<SkinnedMeshRenderer>()).material = val3.suitMaterial;
						((Renderer)val4.replacementModelShadow.GetComponentInChildren<SkinnedMeshRenderer>()).material = val3.suitMaterial;
						((Renderer)val4.replacementViewModel.GetComponentInChildren<SkinnedMeshRenderer>()).material = val3.suitMaterial;
						if ((Object)(object)val4.replacementDeadBody != (Object)null)
						{
							((Renderer)val4.replacementDeadBody.GetComponentInChildren<SkinnedMeshRenderer>()).material = val3.suitMaterial;
						}
					}
				}
				else
				{
					ModelReplacementAPI.RemovePlayerModelReplacement(val2);
				}
			}
		}

		public void Save()
		{
			GameNetworkManager instance = GameNetworkManager.Instance;
			if (instance.isHostingGame)
			{
				ES3.Save<Dictionary<ulong, ServerData>>("LCTransition_ServerData", serverData, instance.currentSaveFileName);
			}
		}

		public void Load()
		{
			GameNetworkManager instance = GameNetworkManager.Instance;
			if (!instance.isHostingGame)
			{
				return;
			}
			serverData = ES3.Load<Dictionary<ulong, ServerData>>("LCTransition_ServerData", instance.currentSaveFileName, new Dictionary<ulong, ServerData>());
			IDictionary<ulong, int> networkDataIndexesBySteamId = getNetworkDataIndexesBySteamId();
			foreach (KeyValuePair<ulong, ServerData> serverDatum in serverData)
			{
				bool flag = serverDatum.Value.feminisationLevels >= 5400;
				Plugin.logger.LogInfo((object)string.Format("Player {0} has feminisation level {1} and {2} feminised", serverDatum.Key, serverDatum.Value.feminisationLevels, flag ? "is" : "isn't"));
				if (networkDataIndexesBySteamId.ContainsKey(serverDatum.Key))
				{
					int num = networkDataIndexesBySteamId[serverDatum.Key];
					NetworkData networkData = this.networkData[num];
					networkData.feminised = flag;
					this.networkData[num] = networkData;
				}
				else
				{
					this.networkData.Add(new NetworkData
					{
						steamId = serverDatum.Key,
						feminised = flag
					});
				}
			}
		}

		public override void OnDestroy()
		{
			Instance = null;
			((NetworkBehaviour)this).OnDestroy();
		}

		protected override void __initializeVariables()
		{
			if (networkData == null)
			{
				throw new Exception("NetworkHandler.networkData cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)networkData).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)networkData, "networkData");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)networkData);
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected internal override string __getTypeName()
		{
			return "NetworkHandler";
		}
	}
	[HarmonyPatch]
	public class NetworkObjectManager
	{
		private static GameObject networkPrefab;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		public static void Init()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			if (!((Object)(object)networkPrefab != (Object)null))
			{
				AssetBundle val = AssetBundle.LoadFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("LCTransition.Resources.transitionassets"));
				networkPrefab = (GameObject)val.LoadAsset("TransitionNetworkHandler");
				networkPrefab.AddComponent<NetworkHandler>();
				NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		private static void SpawnNetworkHandler()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if ((NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) && !((Object)(object)networkPrefab == (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(networkPrefab, Vector3.zero, Quaternion.identity);
				val.GetComponent<NetworkObject>().Spawn(false);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "SaveGame")]
		private static void Save()
		{
			NetworkHandler.Instance.Save();
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LCTransition";

		public const string PLUGIN_NAME = "LCTransition";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}
namespace LCTransition.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("LCTransition.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] transitionassets
		{
			get
			{
				object @object = ResourceManager.GetObject("transitionassets", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}