Decompiled source of RoboFizzarolli v1.0.0

BepInEx/plugins/ModelReplacementAPI.dll

Decompiled 2 years ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LCThirdPerson;
using Microsoft.CodeAnalysis;
using ModelReplacement.AvatarBodyUpdater;
using MoreCompany.Cosmetics;
using UnityEngine;
using UnityEngine.Pool;
using _3rdPerson.Helper;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ModelReplacementAPI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("https://github.com/BunyaPineTree/LethalCompany_ModelReplacementAPI")]
[assembly: AssemblyProduct("meow.ModelReplacementAPI")]
[assembly: AssemblyCopyright("Copyright © meow 2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6390E70C-AB5E-42ED-BA29-F173942DC3A9")]
[assembly: AssemblyFileVersion("1.5.0")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.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 ModelReplacement
{
	public abstract class BodyReplacementBase : MonoBehaviour
	{
		public bool renderLocalDebug = false;

		public bool renderBase = false;

		public bool renderModel = false;

		protected GameObject replacementModel;

		protected GameObject deadBody = null;

		protected GameObject replacementDeadBody = null;

		private MeshRenderer nameTagObj = null;

		private MeshRenderer nameTagObj2 = null;

		private bool moreCompanyCosmeticsReparented = false;

		private static readonly string[] shaderPrefixWhitelist = new string[5] { "HDRP/", "GUI/", "Sprites/", "UI/", "Unlit/" };

		private bool localPlayer => (ulong)StartOfRound.Instance.thisClientPlayerId == controller.playerClientId;

		public AvatarUpdater avatar { get; private set; }

		public PlayerControllerB controller { get; private set; }

		public string suitName { get; set; } = "";


		public AvatarUpdater ragdollAvatar { get; private set; }

		protected abstract GameObject LoadAssetsAndReturnModel();

		protected virtual void AddModelScripts()
		{
		}

		private void Awake()
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			controller = ((Component)this).GetComponent<PlayerControllerB>();
			ModelReplacementAPI.Instance.Logger.LogInfo((object)("Awake " + controller.playerUsername));
			replacementModel = LoadAssetsAndReturnModel();
			if ((Object)(object)replacementModel == (Object)null)
			{
				ModelReplacementAPI.Instance.Logger.LogFatal((object)"LoadAssetsAndReturnModel() returned null. Verify that your assetbundle works and your asset name is correct. ");
			}
			Renderer[] componentsInChildren = replacementModel.GetComponentsInChildren<Renderer>();
			Material sharedMaterial = ((Renderer)((Component)controller.thisPlayerModel).GetComponent<SkinnedMeshRenderer>()).sharedMaterial;
			sharedMaterial = new Material(sharedMaterial);
			Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
			List<Material> list = CollectionPool<List<Material>, Material>.Get();
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				val.GetSharedMaterials(list);
				for (int j = 0; j < list.Count; j++)
				{
					Material val2 = list[j];
					if (!dictionary.TryGetValue(val2, out var value))
					{
						value = (dictionary[val2] = GetReplacementMaterial(sharedMaterial, val2));
					}
					list[j] = value;
				}
				val.SetMaterials(list);
			}
			CollectionPool<List<Material>, Material>.Release(list);
			try
			{
				AddModelScripts();
			}
			catch (Exception ex)
			{
				ModelReplacementAPI.Instance.Logger.LogError((object)("Could not set all model scripts.\n Error: " + ex.Message));
			}
			replacementModel = Object.Instantiate<GameObject>(replacementModel);
			GameObject obj = replacementModel;
			((Object)obj).name = ((Object)obj).name + "(" + controller.playerUsername + ")";
			SetRenderers(enabled: false);
			replacementModel.transform.localPosition = new Vector3(0f, 0f, 0f);
			replacementModel.SetActive(true);
			Bounds bounds = ((Renderer)controller.thisPlayerModel).bounds;
			Vector3 extents = ((Bounds)(ref bounds)).extents;
			float y = extents.y;
			bounds = GetBounds();
			float num = y / ((Bounds)(ref bounds)).extents.y;
			Transform transform = replacementModel.transform;
			transform.localScale *= num;
			avatar = new AvatarUpdater();
			ragdollAvatar = new AvatarUpdater();
			avatar.AssignModelReplacement(((Component)controller).gameObject, replacementModel);
			MeshRenderer[] componentsInChildren2 = ((Component)controller).gameObject.GetComponentsInChildren<MeshRenderer>();
			nameTagObj = componentsInChildren2.Where((MeshRenderer x) => ((Object)((Component)x).gameObject).name == "LevelSticker").First();
			nameTagObj2 = componentsInChildren2.Where((MeshRenderer x) => ((Object)((Component)x).gameObject).name == "BetaBadge").First();
			ModelReplacementAPI.Instance.Logger.LogInfo((object)("AwakeEnd " + controller.playerUsername));
			AfterAwake();
		}

		private void Update()
		{
			if (!renderLocalDebug)
			{
				if (RenderBodyReplacement())
				{
					SetRenderers(enabled: true);
					((Renderer)controller.thisPlayerModel).enabled = false;
					((Renderer)controller.thisPlayerModelLOD1).enabled = false;
					((Renderer)controller.thisPlayerModelLOD2).enabled = false;
					((Renderer)nameTagObj).enabled = false;
					((Renderer)nameTagObj2).enabled = false;
				}
				else
				{
					SetRenderers(enabled: false);
				}
			}
			else
			{
				SkinnedMeshRenderer[] componentsInChildren = ((Component)controller).gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Renderer val = (Renderer)(object)componentsInChildren[i];
					val.enabled = renderBase;
				}
				SetRenderers(renderModel);
			}
			GameObject val2 = null;
			try
			{
				val2 = ((Component)controller.deadBody).gameObject;
			}
			catch
			{
			}
			if (Object.op_Implicit((Object)(object)val2) && (Object)(object)replacementDeadBody == (Object)null)
			{
				CreateAndParentRagdoll(controller.deadBody);
			}
			if (Object.op_Implicit((Object)(object)replacementDeadBody) && (Object)(object)val2 == (Object)null)
			{
				Object.Destroy((Object)(object)replacementDeadBody);
				replacementDeadBody = null;
			}
			avatar.UpdateModel();
			ragdollAvatar.UpdateModel();
			AttemptReparentMoreCompanyCosmetics();
			AfterUpdate();
		}

		private void OnDestroy()
		{
			ModelReplacementAPI.Instance.Logger.LogInfo((object)("Destroy body component for " + controller.playerUsername));
			((Renderer)controller.thisPlayerModel).enabled = true;
			((Renderer)controller.thisPlayerModelLOD1).enabled = true;
			((Renderer)controller.thisPlayerModelLOD2).enabled = true;
			((Renderer)nameTagObj).enabled = true;
			((Renderer)nameTagObj2).enabled = true;
			AttemptUnparentMoreCompanyCosmetics();
			Object.Destroy((Object)(object)replacementModel);
			Object.Destroy((Object)(object)replacementDeadBody);
		}

		protected virtual Material GetReplacementMaterial(Material gameMaterial, Material modelMaterial)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (shaderPrefixWhitelist.Any((string prefix) => ((Object)modelMaterial.shader).name.StartsWith(prefix)))
			{
				return modelMaterial;
			}
			Material val = new Material(gameMaterial);
			val.color = modelMaterial.color;
			val.mainTexture = modelMaterial.mainTexture;
			val.mainTextureOffset = modelMaterial.mainTextureOffset;
			val.mainTextureScale = modelMaterial.mainTextureScale;
			val.SetShaderKeywords(modelMaterial.GetShaderKeywords());
			val.SetEnabledKeywords(modelMaterial.GetEnabledKeywords());
			return val;
		}

		private void CreateAndParentRagdoll(DeadBodyInfo bodyinfo)
		{
			deadBody = ((Component)bodyinfo).gameObject;
			SkinnedMeshRenderer componentInChildren = deadBody.GetComponentInChildren<SkinnedMeshRenderer>();
			replacementDeadBody = Object.Instantiate<GameObject>(replacementModel);
			GameObject obj = replacementDeadBody;
			((Object)obj).name = ((Object)obj).name + "(Ragdoll)";
			ragdollAvatar.AssignModelReplacement(deadBody, replacementDeadBody);
			Renderer[] componentsInChildren = replacementDeadBody.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				val.enabled = true;
			}
			((Renderer)componentInChildren).enabled = false;
			GameObject[] bodyBloodDecals = bodyinfo.bodyBloodDecals;
			foreach (GameObject val2 in bodyBloodDecals)
			{
				Transform parent = val2.transform.parent;
				Transform avatarTransformFromBoneName = ragdollAvatar.GetAvatarTransformFromBoneName(((Object)parent).name);
				if (Object.op_Implicit((Object)(object)avatarTransformFromBoneName))
				{
					Object.Instantiate<GameObject>(val2, avatarTransformFromBoneName);
				}
			}
		}

		private void SetRenderers(bool enabled)
		{
			Renderer[] componentsInChildren = replacementModel.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				val.enabled = enabled;
			}
		}

		public bool RenderBodyReplacement()
		{
			if (!localPlayer)
			{
				return true;
			}
			if (ModelReplacementAPI.thirdPersonPresent)
			{
				return DangerousViewState();
			}
			if (ModelReplacementAPI.LCthirdPersonPresent)
			{
				return DangerousLCViewState();
			}
			return false;
		}

		private Bounds GetBounds()
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			IEnumerable<Bounds> source = from r in replacementModel.GetComponentsInChildren<SkinnedMeshRenderer>()
				select ((Renderer)r).bounds;
			Bounds val = source.OrderByDescending((Bounds x) => ((Bounds)(ref x)).max.x).First();
			float x2 = ((Bounds)(ref val)).max.x;
			val = source.OrderByDescending((Bounds x) => ((Bounds)(ref x)).max.y).First();
			float y = ((Bounds)(ref val)).max.y;
			val = source.OrderByDescending((Bounds x) => ((Bounds)(ref x)).max.z).First();
			float z = ((Bounds)(ref val)).max.z;
			val = source.OrderBy((Bounds x) => ((Bounds)(ref x)).min.x).First();
			float x3 = ((Bounds)(ref val)).min.x;
			val = source.OrderBy((Bounds x) => ((Bounds)(ref x)).min.y).First();
			float y2 = ((Bounds)(ref val)).min.y;
			val = source.OrderBy((Bounds x) => ((Bounds)(ref x)).min.z).First();
			float z2 = ((Bounds)(ref val)).min.z;
			((Bounds)(ref result)).SetMinMax(new Vector3(x3, y2, z2), new Vector3(z, y, z));
			return result;
		}

		private bool DangerousViewState()
		{
			return ThirdPersonCamera.ViewState;
		}

		private bool DangerousLCViewState()
		{
			return ThirdPersonPlugin.Instance.Enabled;
		}

		private void AttemptUnparentMoreCompanyCosmetics()
		{
			if (ModelReplacementAPI.moreCompanyPresent && moreCompanyCosmeticsReparented)
			{
				DangerousUnparent();
			}
		}

		private void AttemptReparentMoreCompanyCosmetics()
		{
			if (ModelReplacementAPI.moreCompanyPresent && !moreCompanyCosmeticsReparented)
			{
				DangerousParent();
			}
		}

		private void DangerousUnparent()
		{
			CosmeticApplication[] componentsInChildren = ((Component)controller).gameObject.GetComponentsInChildren<CosmeticApplication>();
			if (!componentsInChildren.Any())
			{
				return;
			}
			CosmeticApplication[] array = componentsInChildren;
			foreach (CosmeticApplication val in array)
			{
				foreach (CosmeticInstance spawnedCosmetic in val.spawnedCosmetics)
				{
					((Component)spawnedCosmetic).transform.parent = null;
				}
				moreCompanyCosmeticsReparented = false;
			}
		}

		private void DangerousParent()
		{
			CosmeticApplication[] componentsInChildren = ((Component)controller).gameObject.GetComponentsInChildren<CosmeticApplication>();
			if (componentsInChildren.Any())
			{
				CosmeticApplication[] array = componentsInChildren;
				foreach (CosmeticApplication val in array)
				{
					Transform avatarTransformFromBoneName = avatar.GetAvatarTransformFromBoneName("spine.004");
					Transform avatarTransformFromBoneName2 = avatar.GetAvatarTransformFromBoneName("spine.003");
					Transform avatarTransformFromBoneName3 = avatar.GetAvatarTransformFromBoneName("arm.R_lower");
					Transform avatarTransformFromBoneName4 = avatar.GetAvatarTransformFromBoneName("spine");
					Transform avatarTransformFromBoneName5 = avatar.GetAvatarTransformFromBoneName("shin.L");
					Transform avatarTransformFromBoneName6 = avatar.GetAvatarTransformFromBoneName("shin.R");
					val.head = avatarTransformFromBoneName;
					val.chest = avatarTransformFromBoneName2;
					val.lowerArmRight = avatarTransformFromBoneName3;
					val.hip = avatarTransformFromBoneName4;
					val.shinLeft = avatarTransformFromBoneName5;
					val.shinRight = avatarTransformFromBoneName6;
					val.RefreshAllCosmeticPositions();
					moreCompanyCosmeticsReparented = true;
				}
				Console.WriteLine(" reparent done");
			}
		}

		protected virtual void AfterStart()
		{
		}

		private void Start()
		{
			AfterStart();
		}

		protected virtual void AfterAwake()
		{
		}

		protected virtual void AfterUpdate()
		{
		}
	}
	public static class PluginInfo
	{
		public const string GUID = "meow.ModelReplacementAPI";

		public const string NAME = "ModelReplacementAPI";

		public const string VERSION = "1.5.0";

		public const string WEBSITE = "https://github.com/BunyaPineTree/LethalCompany_ModelReplacementAPI";
	}
	[BepInPlugin("meow.ModelReplacementAPI", "ModelReplacementAPI", "1.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ModelReplacementAPI : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(GrabbableObject))]
		public class LocateHeldObjectsOnModelReplacementPatch
		{
			[HarmonyPatch("LateUpdate")]
			[HarmonyPostfix]
			public static void LateUpdatePatch(ref GrabbableObject __instance)
			{
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0103: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0120: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)__instance.parentObject == (Object)null) && !((Object)(object)__instance.playerHeldBy == (Object)null))
				{
					BodyReplacementBase component = ((Component)__instance.playerHeldBy).gameObject.GetComponent<BodyReplacementBase>();
					if (!((Object)(object)component == (Object)null) && component.RenderBodyReplacement() && (!component.renderLocalDebug || component.renderModel))
					{
						Transform itemHolder = component.avatar.itemHolder;
						itemHolder.localPosition = component.avatar.itemHolderPositionOffset;
						((Component)__instance).transform.rotation = itemHolder.rotation * component.avatar.itemHolderRotationOffset;
						((Component)__instance).transform.Rotate(__instance.itemProperties.rotationOffset);
						((Component)__instance).transform.position = itemHolder.position;
						Vector3 positionOffset = __instance.itemProperties.positionOffset;
						positionOffset = itemHolder.rotation * positionOffset;
						Transform transform = ((Component)__instance).transform;
						transform.position += positionOffset;
					}
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound))]
		public class RepairBrokenBodyReplacementsPatch
		{
			[HarmonyPatch("ReviveDeadPlayers")]
			[HarmonyPostfix]
			public static void ReviveDeadPlayersPatch(ref StartOfRound __instance)
			{
				PlayerControllerB[] allPlayerScripts = __instance.allPlayerScripts;
				foreach (PlayerControllerB val in allPlayerScripts)
				{
					if (val.isPlayerDead && !((Object)(object)((Component)val).gameObject.GetComponent<BodyReplacementBase>() == (Object)null))
					{
						Console.WriteLine("Reinstantiating model replacement for " + val.playerUsername + " ");
						Type type = ((object)((Component)val).gameObject.GetComponent<BodyReplacementBase>()).GetType();
						Object.Destroy((Object)(object)((Component)val).gameObject.GetComponent<BodyReplacementBase>());
						((Component)val).gameObject.AddComponent(type);
					}
				}
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB))]
		public class SetRegisteredBodyReplacements
		{
			[HarmonyPatch("Update")]
			[HarmonyPostfix]
			public static void UpdatePatch(ref PlayerControllerB __instance)
			{
				try
				{
					if (__instance.playerSteamId == 0)
					{
						return;
					}
					if (RegisteredModelReplacementOverride != null)
					{
						SetPlayerModelReplacement(__instance, RegisteredModelReplacementOverride);
						return;
					}
					int currentSuitID = __instance.currentSuitID;
					string unlockableName = StartOfRound.Instance.unlockablesList.unlockables[currentSuitID].unlockableName;
					unlockableName = unlockableName.ToLower().Replace(" ", "");
					if (RegisteredModelReplacements.ContainsKey(unlockableName))
					{
						Type type = RegisteredModelReplacements[unlockableName];
						SetPlayerModelReplacement(__instance, type);
					}
					else
					{
						RemovePlayerModelReplacement(__instance);
					}
				}
				catch (Exception)
				{
				}
			}
		}

		public static bool moreCompanyPresent;

		public static bool thirdPersonPresent;

		public static bool LCthirdPersonPresent;

		public static ModelReplacementAPI Instance;

		public ManualLogSource Logger;

		private static Dictionary<string, Type> RegisteredModelReplacements = new Dictionary<string, Type>();

		private static Type RegisteredModelReplacementOverride = null;

		private void Awake()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			Logger = Logger.CreateLogSource("meow.ModelReplacementAPI");
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			moreCompanyPresent = Chainloader.PluginInfos.ContainsKey("me.swipez.melonloader.morecompany");
			thirdPersonPresent = Chainloader.PluginInfos.ContainsKey("verity.3rdperson");
			LCthirdPersonPresent = Chainloader.PluginInfos.ContainsKey("LCThirdPerson");
			Harmony val = new Harmony("meow.ModelReplacementAPI");
			val.PatchAll();
			Logger.LogInfo((object)"Plugin meow.ModelReplacementAPI is loaded!");
		}

		public static void RegisterModelReplacementOverride(Type type)
		{
			if (!type.IsSubclassOf(typeof(BodyReplacementBase)))
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement override type {type.GetType()}, must inherit from BodyReplacementBase");
				return;
			}
			if (RegisteredModelReplacementOverride != null)
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement override, already registered to {RegisteredModelReplacementOverride.GetType()}.");
				return;
			}
			Instance.Logger.LogInfo((object)$"Registering body replacement override type {type.GetType()}.");
			RegisteredModelReplacementOverride = type;
		}

		public static void RegisterSuitModelReplacement(string suitNameToReplace, Type type)
		{
			suitNameToReplace = suitNameToReplace.ToLower().Replace(" ", "");
			if (!type.IsSubclassOf(typeof(BodyReplacementBase)))
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement type {type.GetType()}, must inherit from BodyReplacementBase");
				return;
			}
			if (RegisteredModelReplacements.ContainsKey(suitNameToReplace))
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement type {type.GetType()}, suit name to replace {suitNameToReplace} is already registered.");
				return;
			}
			Instance.Logger.LogInfo((object)$"Registering body replacement type {type.GetType()} to suit name {suitNameToReplace}.");
			RegisteredModelReplacements.Add(suitNameToReplace, type);
		}

		public static void SetPlayerModelReplacement(PlayerControllerB player, Type type)
		{
			if (!type.IsSubclassOf(typeof(BodyReplacementBase)))
			{
				Instance.Logger.LogError((object)("Cannot set body replacement of type " + type.Name + ", must inherit from BodyReplacementBase"));
				return;
			}
			BodyReplacementBase component = ((Component)player.thisPlayerBody).gameObject.GetComponent<BodyReplacementBase>();
			int currentSuitID = player.currentSuitID;
			string unlockableName = StartOfRound.Instance.unlockablesList.unlockables[currentSuitID].unlockableName;
			if ((Object)(object)component != (Object)null)
			{
				if (((object)component).GetType() == type)
				{
					if (!(component.suitName != unlockableName))
					{
						return;
					}
					Console.WriteLine("Suit name mismatch " + component.suitName + " =/ " + unlockableName + ", Destroying");
					Object.Destroy((Object)(object)component);
				}
				else
				{
					Object.Destroy((Object)(object)component);
				}
			}
			BodyReplacementBase bodyReplacementBase = ((Component)player.thisPlayerBody).gameObject.AddComponent(type) as BodyReplacementBase;
			bodyReplacementBase.suitName = unlockableName;
		}

		public static void RemovePlayerModelReplacement(PlayerControllerB player)
		{
			BodyReplacementBase component = ((Component)player.thisPlayerBody).gameObject.GetComponent<BodyReplacementBase>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Object.Destroy((Object)(object)component);
			}
		}

		public static void RefreshAllModelReplacements()
		{
		}
	}
}
namespace ModelReplacement.AvatarBodyUpdater
{
	public class AvatarUpdater
	{
		private SkinnedMeshRenderer playerModelRenderer = null;

		private Animator replacementAnimator = null;

		private bool hasUpperChest = false;

		private Vector3 rootPositionOffset = new Vector3(0f, 0f, 0f);

		private Vector3 rootScale = new Vector3(1f, 1f, 1f);

		private static Dictionary<string, HumanBodyBones> modelToAvatarBone = new Dictionary<string, HumanBodyBones>
		{
			{
				"spine",
				(HumanBodyBones)0
			},
			{
				"spine.001",
				(HumanBodyBones)7
			},
			{
				"shoulder.L",
				(HumanBodyBones)11
			},
			{
				"arm.L_upper",
				(HumanBodyBones)13
			},
			{
				"arm.L_lower",
				(HumanBodyBones)15
			},
			{
				"hand.L",
				(HumanBodyBones)17
			},
			{
				"finger5.L",
				(HumanBodyBones)36
			},
			{
				"finger5.L.001",
				(HumanBodyBones)37
			},
			{
				"finger4.L",
				(HumanBodyBones)33
			},
			{
				"finger4.L.001",
				(HumanBodyBones)34
			},
			{
				"finger3.L",
				(HumanBodyBones)30
			},
			{
				"finger3.L.001",
				(HumanBodyBones)31
			},
			{
				"finger2.L",
				(HumanBodyBones)27
			},
			{
				"finger2.L.001",
				(HumanBodyBones)28
			},
			{
				"finger1.L",
				(HumanBodyBones)24
			},
			{
				"finger1.L.001",
				(HumanBodyBones)26
			},
			{
				"shoulder.R",
				(HumanBodyBones)12
			},
			{
				"arm.R_upper",
				(HumanBodyBones)14
			},
			{
				"arm.R_lower",
				(HumanBodyBones)16
			},
			{
				"hand.R",
				(HumanBodyBones)18
			},
			{
				"finger5.R",
				(HumanBodyBones)51
			},
			{
				"finger5.R.001",
				(HumanBodyBones)52
			},
			{
				"finger4.R",
				(HumanBodyBones)48
			},
			{
				"finger4.R.001",
				(HumanBodyBones)49
			},
			{
				"finger3.R",
				(HumanBodyBones)45
			},
			{
				"finger3.R.001",
				(HumanBodyBones)46
			},
			{
				"finger2.R",
				(HumanBodyBones)42
			},
			{
				"finger2.R.001",
				(HumanBodyBones)43
			},
			{
				"finger1.R",
				(HumanBodyBones)39
			},
			{
				"finger1.R.001",
				(HumanBodyBones)41
			},
			{
				"spine.004",
				(HumanBodyBones)10
			},
			{
				"thigh.L",
				(HumanBodyBones)1
			},
			{
				"shin.L",
				(HumanBodyBones)3
			},
			{
				"foot.L",
				(HumanBodyBones)5
			},
			{
				"toe.L",
				(HumanBodyBones)19
			},
			{
				"thigh.R",
				(HumanBodyBones)2
			},
			{
				"shin.R",
				(HumanBodyBones)4
			},
			{
				"foot.R",
				(HumanBodyBones)6
			},
			{
				"toe.R",
				(HumanBodyBones)20
			}
		};

		public Vector3 itemHolderPositionOffset { get; private set; } = Vector3.zero;


		public Quaternion itemHolderRotationOffset { get; private set; } = Quaternion.identity;


		public Transform itemHolder { get; private set; } = null;


		public void AssignModelReplacement(GameObject player, GameObject replacement)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB component = player.GetComponent<PlayerControllerB>();
			if (Object.op_Implicit((Object)(object)component))
			{
				playerModelRenderer = component.thisPlayerModel;
			}
			else
			{
				playerModelRenderer = player.GetComponentInChildren<SkinnedMeshRenderer>();
			}
			if ((Object)(object)playerModelRenderer == (Object)null)
			{
				Console.WriteLine("failed to start AvatarBodyUpdater");
				return;
			}
			replacementAnimator = replacement.GetComponentInChildren<Animator>();
			OffsetBuilder component2 = ((Component)replacementAnimator).gameObject.GetComponent<OffsetBuilder>();
			itemHolderPositionOffset = component2.itemPositonOffset;
			itemHolderRotationOffset = component2.itemRotationOffset;
			itemHolder = component2.itemHolder.transform;
			rootPositionOffset = component2.rootPositionOffset;
			rootScale = component2.rootScale;
			Transform boneTransform = replacementAnimator.GetBoneTransform((HumanBodyBones)54);
			hasUpperChest = (Object)(object)boneTransform != (Object)null;
		}

		public bool CanUpdateModel()
		{
			if ((Object)(object)playerModelRenderer == (Object)null)
			{
				return false;
			}
			if ((Object)(object)replacementAnimator == (Object)null)
			{
				return false;
			}
			return true;
		}

		public void UpdateModel()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			if (!CanUpdateModel())
			{
				return;
			}
			Transform[] bones = playerModelRenderer.bones;
			foreach (Transform val in bones)
			{
				Transform avatarTransformFromBoneName = GetAvatarTransformFromBoneName(((Object)val).name);
				if (!((Object)(object)avatarTransformFromBoneName == (Object)null))
				{
					avatarTransformFromBoneName.rotation = val.rotation;
					RotationOffset component = ((Component)avatarTransformFromBoneName).GetComponent<RotationOffset>();
					if (Object.op_Implicit((Object)(object)component))
					{
						avatarTransformFromBoneName.rotation *= component.offset;
					}
					if (((Object)val).name == "spine" || ((Object)val).name.Contains("PlayerRagdoll"))
					{
						avatarTransformFromBoneName.position = val.position;
						avatarTransformFromBoneName.position += val.TransformVector(rootPositionOffset);
					}
				}
			}
		}

		public Transform GetAvatarTransformFromBoneName(string boneName)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			if (boneName == "spine.002")
			{
				if (hasUpperChest)
				{
					return replacementAnimator.GetBoneTransform((HumanBodyBones)8);
				}
				return null;
			}
			if (boneName == "spine.003")
			{
				if (hasUpperChest)
				{
					return replacementAnimator.GetBoneTransform((HumanBodyBones)54);
				}
				return replacementAnimator.GetBoneTransform((HumanBodyBones)8);
			}
			if (boneName.Contains("PlayerRagdoll"))
			{
				return replacementAnimator.GetBoneTransform((HumanBodyBones)0);
			}
			if (modelToAvatarBone.ContainsKey(boneName))
			{
				return replacementAnimator.GetBoneTransform(modelToAvatarBone[boneName]);
			}
			return null;
		}
	}
	public class RotationOffset : MonoBehaviour
	{
		public Quaternion offset = Quaternion.identity;
	}
	public class OffsetBuilder : MonoBehaviour
	{
		public Vector3 rootPositionOffset;

		public Vector3 rootScale;

		public Vector3 itemPositonOffset;

		public Quaternion itemRotationOffset;

		public GameObject itemHolder;

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