Decompiled source of ModelReplacementAPI Custom v0.0.0

ModelReplacementAPI.dll

Decompiled a year ago
using System;
using System.Collections;
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.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LCThirdPerson;
using Microsoft.CodeAnalysis;
using ModelReplacement;
using ModelReplacement.AvatarBodyUpdater;
using ModelReplacement.Monobehaviors;
using ModelReplacement.Monobehaviors.Enemies;
using ModelReplacement.Scripts;
using ModelReplacement.Scripts.Enemies;
using ModelReplacement.Scripts.Player;
using MoreCompany;
using MoreCompany.Cosmetics;
using Steamworks.Data;
using TooManyEmotes;
using TooManyEmotes.Patches;
using Unity.Collections;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
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("2.4.18")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.4.18.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;
		}
	}
}
[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)
			{
				ModelReplacementAPI.ResetPlayerModelReplacement(val);
			}
		}
	}
}
namespace ModelReplacement
{
	public static class PluginInfo
	{
		public const string GUID = "meow.ModelReplacementAPI";

		public const string NAME = "ModelReplacementAPI";

		public const string VERSION = "2.4.18";

		public const string WEBSITE = "https://github.com/BunyaPineTree/LethalCompany_ModelReplacementAPI";
	}
	[BepInPlugin("meow.ModelReplacementAPI", "ModelReplacementAPI", "2.4.18")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ModelReplacementAPI : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(PlayerControllerB))]
		public class PlayerControllerBPatch
		{
			[HarmonyPatch("Update")]
			[HarmonyPatch("OnDisable")]
			[HarmonyPostfix]
			public static void ManageRegistryBodyReplacements(ref PlayerControllerB __instance)
			{
				try
				{
					ManageBodyReplacements(__instance);
				}
				catch (Exception arg)
				{
					Instance.Logger.LogError((object)$"Exception in ManageRegistryBodyReplacements: {arg}");
				}
			}

			private static void ManageBodyReplacements(PlayerControllerB player)
			{
				if ((Object)(object)StartOfRound.Instance.allPlayerScripts[player.playerClientId] != (Object)(object)player)
				{
					return;
				}
				BodyReplacementBase component = ((Component)player.thisPlayerBody).gameObject.GetComponent<BodyReplacementBase>();
				if ((Object)(object)component != (Object)null && RegisteredModelReplacementExceptions.Contains(((object)component).GetType()))
				{
					return;
				}
				if (RegisteredModelReplacementOverride != null)
				{
					SetPlayerModelReplacement(player, RegisteredModelReplacementOverride);
					return;
				}
				int num = player.currentSuitID;
				List<UnlockableItem> unlockables = StartOfRound.Instance.unlockablesList.unlockables;
				if (num > unlockables.Count)
				{
					throw new Exception($"Suit ID {num} is out of range of the suit list, which has {unlockables.Count} elements.");
				}
				if (num >= unlockables.Count)
				{
					num = 0;
				}
				string key = unlockables[num].unlockableName.ToLower().Replace(" ", "");
				if (RegisteredModelReplacements.ContainsKey(key))
				{
					SetPlayerModelReplacement(player, RegisteredModelReplacements[key]);
				}
				else if (RegisteredModelReplacementDefault != null)
				{
					SetPlayerModelReplacement(player, RegisteredModelReplacementDefault);
				}
				else
				{
					RemovePlayerModelReplacement(player);
				}
			}
		}

		public static ConfigFile config;

		public static bool moreCompanyPresent;

		public static bool thirdPersonPresent;

		public static bool LCthirdPersonPresent;

		public static bool mirrorDecorPresent;

		public static bool tooManyEmotesPresent;

		public static bool recordingCameraPresent;

		public static bool MRAPI_NetworkingPresent;

		public static ModelReplacementAPI Instance = null;

		public ManualLogSource Logger;

		private static List<Type> RegisteredModelReplacementExceptions = new List<Type>();

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

		private static Type RegisteredModelReplacementOverride = null;

		private static Type RegisteredModelReplacementDefault = null;

		private static HashSet<ulong> blackListedSteamIDs = new HashSet<ulong>();

		public static ConfigEntry<bool> EnforceViewModelGeneration { get; private set; }

		private static int steamLobbyID
		{
			get
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				int result;
				if (!GameNetworkManager.Instance.currentLobby.HasValue)
				{
					result = -1;
				}
				else
				{
					Lobby value = GameNetworkManager.Instance.currentLobby.Value;
					result = (int)((Lobby)(ref value)).Id.Value;
				}
				return result;
			}
		}

		public static bool IsLan => steamLobbyID == -1;

		private static void InitConfig()
		{
			EnforceViewModelGeneration = config.Bind<bool>("Debug Settings", "Generate Viewmodels by default", true, "Enable to generate a viewmodel for all model replacements, regardless of the individual model's settings.");
		}

		private void Awake()
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			config = ((BaseUnityPlugin)this).Config;
			InitConfig();
			Logger = Logger.CreateLogSource("meow.ModelReplacementAPI");
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			moreCompanyPresent = IsPluginPresent("me.swipez.melonloader.morecompany");
			thirdPersonPresent = IsPluginPresent("verity.3rdperson");
			LCthirdPersonPresent = IsPluginPresent("LCThirdPerson");
			mirrorDecorPresent = IsPluginPresent("quackandcheese.mirrordecor");
			tooManyEmotesPresent = IsPluginPresent("FlipMods.TooManyEmotes");
			recordingCameraPresent = IsPluginPresent("com.graze.gorillatag.placeablecamera");
			MRAPI_NetworkingPresent = IsPluginPresent("meow.ModelReplacementAPI.Networking");
			Harmony val = new Harmony("meow.ModelReplacementAPI");
			val.PatchAll();
			Logger.LogInfo((object)"Plugin meow.ModelReplacementAPI is loaded!");
		}

		private static bool IsPluginPresent(string pluginName)
		{
			return Chainloader.PluginInfos.ContainsKey(pluginName);
		}

		public static void RegisterModelReplacementDefault(Type type)
		{
			RegisterModelReplacement(type, ref RegisteredModelReplacementDefault, "default");
		}

		public static void RegisterModelReplacementOverride(Type type)
		{
			RegisterModelReplacement(type, ref RegisteredModelReplacementOverride, "override");
		}

		public static void RegisterModelReplacementException(Type type)
		{
			RegisterModelReplacement(type, RegisteredModelReplacementExceptions, "exception");
		}

		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}, must inherit from BodyReplacementBase");
				return;
			}
			if (RegisteredModelReplacements.ContainsKey(suitNameToReplace))
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement type {type}, suit name to replace {suitNameToReplace} is already registered.");
				return;
			}
			Instance.Logger.LogInfo((object)$"Registering body replacement type {type} to suit name {suitNameToReplace}.");
			RegisteredModelReplacements.Add(suitNameToReplace, type);
		}

		private static void RegisterModelReplacement(Type type, ref Type registeredType, string logType)
		{
			if (!type.IsSubclassOf(typeof(BodyReplacementBase)))
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement {logType} type {type}, must inherit from BodyReplacementBase");
				return;
			}
			if (registeredType != null)
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement {logType}, already registered to {registeredType}.");
				return;
			}
			Instance.Logger.LogInfo((object)$"Registering body replacement {logType} type {type}.");
			registeredType = type;
		}

		private static void RegisterModelReplacement(Type type, List<Type> registeredList, string logType)
		{
			if (!type.IsSubclassOf(typeof(BodyReplacementBase)))
			{
				Instance.Logger.LogError((object)$"Cannot register body replacement {logType} type {type}, must inherit from BodyReplacementBase");
				return;
			}
			Instance.Logger.LogInfo((object)$"Registering body replacement {logType} type {type}.");
			if (!registeredList.Contains(type))
			{
				registeredList.Add(type);
			}
		}

		public static void RegisterPlayerBlackList(ulong steamID, bool blackListed)
		{
			if (blackListed)
			{
				blackListedSteamIDs.Add(steamID);
			}
			else if (blackListedSteamIDs.Contains(steamID))
			{
				blackListedSteamIDs.Remove(steamID);
			}
		}

		public static void RegisterPlayerBlackList(PlayerControllerB player, bool blackListed)
		{
			RegisterPlayerBlackList(player.playerSteamId, blackListed);
			RemovePlayerModelReplacement(player);
		}

		public static void ResetPlayerModelReplacement(PlayerControllerB player)
		{
			BodyReplacementBase component = ((Component)player).gameObject.GetComponent<BodyReplacementBase>();
			if (!((Object)(object)component == (Object)null))
			{
				Instance.Logger.LogInfo((object)("Reinstantiating model replacement for " + player.playerUsername));
				Type type = ((object)component).GetType();
				component.IsActive = false;
				Object.Destroy((Object)(object)component);
				((Component)player).gameObject.AddComponent(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"));
			}
			else
			{
				if ((!IsLan && player.playerSteamId == 0) || blackListedSteamIDs.Contains(player.playerSteamId))
				{
					return;
				}
				BodyReplacementBase bodyReplacementBase = default(BodyReplacementBase);
				bool flag = ((Component)player).gameObject.TryGetComponent<BodyReplacementBase>(ref bodyReplacementBase);
				int currentSuitID = player.currentSuitID;
				string unlockableName = StartOfRound.Instance.unlockablesList.unlockables[currentSuitID].unlockableName;
				if (flag)
				{
					if (((object)bodyReplacementBase).GetType() == type && bodyReplacementBase.suitName == unlockableName)
					{
						return;
					}
					Instance.Logger.LogInfo((object)$"Model Replacement Change detected {((object)bodyReplacementBase).GetType()} => {type}, changing model.");
					bodyReplacementBase.IsActive = false;
					Object.Destroy((Object)(object)bodyReplacementBase);
				}
				Instance.Logger.LogInfo((object)$"Suit Change detected {bodyReplacementBase?.suitName} => {unlockableName}, Replacing {type}.");
				BodyReplacementBase bodyReplacementBase2 = ((Component)player).gameObject.AddComponent(type) as BodyReplacementBase;
				bodyReplacementBase2.suitName = unlockableName;
			}
		}

		public static bool GetPlayerModelReplacement(PlayerControllerB player, out BodyReplacementBase modelReplacement)
		{
			try
			{
				modelReplacement = ((Component)player).gameObject.GetComponent<BodyReplacementBase>();
				return (Object)(object)modelReplacement != (Object)null;
			}
			catch (Exception arg)
			{
				Instance.Logger.LogError((object)$"Error in GetPlayerModelReplacement, returning false {arg}");
				modelReplacement = null;
				return false;
			}
		}

		public static bool GetPlayerModelReplacement(PlayerControllerB player)
		{
			try
			{
				return (Object)(object)((Component)player).gameObject.GetComponent<BodyReplacementBase>() != (Object)null;
			}
			catch (Exception arg)
			{
				Instance.Logger.LogError((object)$"Error in GetPlayerModelReplacement, returning false {arg}");
				return false;
			}
		}

		public static void RemovePlayerModelReplacement(PlayerControllerB player)
		{
			BodyReplacementBase component = ((Component)player).gameObject.GetComponent<BodyReplacementBase>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.IsActive = false;
				Object.Destroy((Object)(object)component);
			}
		}
	}
	public abstract class BodyReplacementBase : MonoBehaviour
	{
		public class RaycastTarget : MonoBehaviour
		{
			public PlayerControllerB controller = null;

			public BodyReplacementBase bodyReplacement = null;

			public GameObject modelObj = null;

			private void Update()
			{
				if ((Object)(object)bodyReplacement == (Object)null && !((Object)(object)modelObj != (Object)null))
				{
				}
			}
		}

		public static List<BodyReplacementBase> allBodies;

		public ViewStateManager viewState = null;

		public MoreCompanyCosmeticManager cosmeticManager = null;

		public GameObject replacementModel;

		public GameObject replacementViewModel;

		public BoxCollider nameTagCollider = null;

		public GrabbableObject heldItem = null;

		public GameObject deadBody = null;

		public GameObject replacementDeadBody = null;

		public GameObject replacementModelShadow = null;

		private MaterialHelper matHelper = null;

		private int danceNumber = 0;

		private int previousDanceNumber = 0;

		public AvatarUpdater cosmeticAvatar = null;

		public bool IsActive = true;

		public bool UseNoPostProcessing = false;

		public bool DontConvertUnsupportedShaders = false;

		public bool GenerateViewModel = false;

		public bool RemoveHelmet = false;

		public bool DebugRenderPlayer = false;

		public bool DebugRenderModel = false;

		private bool emoteOngoing = false;

		public AvatarUpdater avatar { get; private set; }

		public ViewModelUpdater viewModelAvatar { get; private set; }

		public PlayerControllerB controller { get; private set; }

		public AvatarUpdater ragdollAvatar { get; private set; }

		public AvatarUpdater shadowAvatar { get; private set; }

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


		protected abstract GameObject LoadAssetsAndReturnModel();

		protected virtual GameObject LoadAssetsAndReturnViewModel()
		{
			return null;
		}

		protected virtual GameObject LoadAssetsAndReturnRagdoll(CauseOfDeath causeOfDeath)
		{
			return null;
		}

		protected virtual AvatarUpdater GetAvatarUpdater()
		{
			return new AvatarUpdater();
		}

		protected virtual ViewModelUpdater GetViewModelUpdater()
		{
			return new ViewModelUpdater();
		}

		protected virtual void AddModelScripts()
		{
		}

		protected internal virtual void OnHitEnemy(bool dead)
		{
			Console.WriteLine("PLAYER HIT ENEMY " + controller.playerUsername);
		}

		protected internal virtual void OnHitAlly(PlayerControllerB ally, bool dead)
		{
			Console.WriteLine("PLAYER HIT ALLY " + controller.playerUsername);
		}

		protected internal virtual void OnDamageTaken(bool dead)
		{
			Console.WriteLine("PLAYER TAKE DAMAGE  " + controller.playerUsername);
		}

		protected internal virtual void OnDamageTakenByAlly(PlayerControllerB ally, bool dead)
		{
			Console.WriteLine("PLAYER TAKE DAMAGE BY ALLY " + controller.playerUsername);
		}

		protected internal virtual void OnDeath()
		{
			Console.WriteLine("PLAYER DEATH " + controller.playerUsername + " ");
		}

		protected internal virtual void OnEmoteStart(int emoteId)
		{
			Console.WriteLine($"PLAYER EMOTE START {controller.playerUsername} ID {emoteId}");
		}

		protected internal virtual void OnEmoteEnd()
		{
			Console.WriteLine("PLAYER EMOTE END " + controller.playerUsername);
		}

		private GameObject LoadModelReplacement()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_008a: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: 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_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: 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_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = LoadAssetsAndReturnModel();
			if ((Object)(object)val == (Object)null)
			{
				ModelReplacementAPI.Instance.Logger.LogFatal((object)"LoadAssetsAndReturnModel() returned null. Verify that your assetbundle works and your asset name is correct. ");
			}
			Animator componentInChildren = val.GetComponentInChildren<Animator>();
			OffsetBuilder component = ((Component)componentInChildren).gameObject.GetComponent<OffsetBuilder>();
			UseNoPostProcessing = component.UseNoPostProcessing;
			GenerateViewModel = component.GenerateViewModel;
			RemoveHelmet = component.RemoveHelmet;
			Vector3 rootScale = component.rootScale;
			Material sharedMaterial = ((Renderer)((Component)controller.thisPlayerModel).GetComponent<SkinnedMeshRenderer>()).sharedMaterial;
			sharedMaterial = new Material(sharedMaterial);
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>();
			SkinnedMeshRenderer[] componentsInChildren2 = val.GetComponentsInChildren<SkinnedMeshRenderer>();
			Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
			List<Material> list = ListPool<Material>.Get();
			Renderer[] array = componentsInChildren;
			foreach (Renderer val2 in array)
			{
				val2.renderingLayerMask = 513u;
				val2.GetSharedMaterials(list);
				for (int j = 0; j < list.Count; j++)
				{
					Material val3 = list[j];
					if (!dictionary.TryGetValue(val3, out var value))
					{
						value = (dictionary[val3] = matHelper.GetReplacementMaterial(sharedMaterial, val3));
					}
					list[j] = value;
				}
				val2.SetMaterials(list);
			}
			ListPool<Material>.Release(list);
			SkinnedMeshRenderer[] array2 = componentsInChildren2;
			foreach (SkinnedMeshRenderer val4 in array2)
			{
				val4.updateWhenOffscreen = true;
			}
			Camera[] componentsInChildren3 = val.GetComponentsInChildren<Camera>();
			foreach (Camera val5 in componentsInChildren3)
			{
				((Behaviour)val5).enabled = false;
			}
			float num = 1.465f;
			Bounds bounds = GetBounds(val);
			float num2 = num / ((Bounds)(ref bounds)).extents.y;
			Transform transform = val.transform;
			transform.localScale *= num2;
			Vector3 localScale = val.transform.localScale;
			val.transform.localScale = Vector3.Scale(localScale, rootScale);
			val = Object.Instantiate<GameObject>(val);
			GameObject obj = val;
			((Object)obj).name = ((Object)obj).name + "(" + controller.playerUsername + ")";
			val.transform.localPosition = new Vector3(0f, 0f, 0f);
			val.SetActive(true);
			return val;
		}

		private GameObject LoadViewModelreplacement()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			if (GenerateViewModel || ModelReplacementAPI.EnforceViewModelGeneration.Value)
			{
				val = Object.Instantiate<GameObject>(replacementModel);
				GameObject obj = val;
				((Object)obj).name = ((Object)obj).name + "(ViewModel)";
				val.transform.localPosition = new Vector3(0f, 0f, 0f);
				val.SetActive(false);
				return MeshHelper.ConvertModelToViewModel(val);
			}
			val = LoadAssetsAndReturnViewModel();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Material sharedMaterial = ((Renderer)((Component)controller.thisPlayerModel).GetComponent<SkinnedMeshRenderer>()).sharedMaterial;
			sharedMaterial = new Material(sharedMaterial);
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>();
			SkinnedMeshRenderer[] componentsInChildren2 = val.GetComponentsInChildren<SkinnedMeshRenderer>();
			Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
			List<Material> list = ListPool<Material>.Get();
			Renderer[] array = componentsInChildren;
			foreach (Renderer val2 in array)
			{
				val2.GetSharedMaterials(list);
				for (int j = 0; j < list.Count; j++)
				{
					Material val3 = list[j];
					if (!dictionary.TryGetValue(val3, out var value))
					{
						value = (dictionary[val3] = matHelper.GetReplacementMaterial(sharedMaterial, val3));
					}
					list[j] = value;
				}
				val2.SetMaterials(list);
			}
			ListPool<Material>.Release(list);
			SkinnedMeshRenderer[] array2 = componentsInChildren2;
			foreach (SkinnedMeshRenderer val4 in array2)
			{
				val4.updateWhenOffscreen = true;
			}
			Camera[] componentsInChildren3 = val.GetComponentsInChildren<Camera>();
			foreach (Camera val5 in componentsInChildren3)
			{
				((Behaviour)val5).enabled = false;
			}
			val = Object.Instantiate<GameObject>(val);
			GameObject obj2 = val;
			((Object)obj2).name = ((Object)obj2).name + "(" + controller.playerUsername + ")(ViewModel)";
			val.transform.localPosition = new Vector3(0f, 0f, 0f);
			val.SetActive(false);
			return val;
		}

		private GameObject LoadRagdollReplacement(CauseOfDeath causeOfDeath)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: 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_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = LoadAssetsAndReturnRagdoll(causeOfDeath);
			if ((Object)(object)val == (Object)null)
			{
				val = Object.Instantiate<GameObject>(replacementModel);
				GameObject obj = val;
				((Object)obj).name = ((Object)obj).name + "(Ragdoll)";
				return val;
			}
			Animator componentInChildren = val.GetComponentInChildren<Animator>();
			OffsetBuilder component = ((Component)componentInChildren).gameObject.GetComponent<OffsetBuilder>();
			Vector3 rootScale = component.rootScale;
			Material sharedMaterial = ((Renderer)((Component)controller.thisPlayerModel).GetComponent<SkinnedMeshRenderer>()).sharedMaterial;
			sharedMaterial = new Material(sharedMaterial);
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>();
			SkinnedMeshRenderer[] componentsInChildren2 = val.GetComponentsInChildren<SkinnedMeshRenderer>();
			Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
			List<Material> list = ListPool<Material>.Get();
			Renderer[] array = componentsInChildren;
			foreach (Renderer val2 in array)
			{
				val2.GetSharedMaterials(list);
				for (int j = 0; j < list.Count; j++)
				{
					Material val3 = list[j];
					if (!dictionary.TryGetValue(val3, out var value))
					{
						value = (dictionary[val3] = matHelper.GetReplacementMaterial(sharedMaterial, val3));
					}
					list[j] = value;
				}
				val2.SetMaterials(list);
				val2.shadowCastingMode = (ShadowCastingMode)1;
				((Component)val2).gameObject.layer = viewState.VisibleLayer;
			}
			ListPool<Material>.Release(list);
			SkinnedMeshRenderer[] array2 = componentsInChildren2;
			foreach (SkinnedMeshRenderer val4 in array2)
			{
				val4.updateWhenOffscreen = true;
			}
			Camera[] componentsInChildren3 = val.GetComponentsInChildren<Camera>();
			foreach (Camera val5 in componentsInChildren3)
			{
				((Behaviour)val5).enabled = false;
			}
			float num = 1.465f;
			Bounds bounds = GetBounds(val);
			float num2 = num / ((Bounds)(ref bounds)).extents.y;
			Transform transform = val.transform;
			transform.localScale *= num2;
			Vector3 localScale = val.transform.localScale;
			val.transform.localScale = Vector3.Scale(localScale, rootScale);
			val = Object.Instantiate<GameObject>(val);
			GameObject obj2 = val;
			((Object)obj2).name = ((Object)obj2).name + "(" + controller.playerUsername + ")(Ragdoll)";
			val.transform.localPosition = new Vector3(0f, 0f, 0f);
			val.SetActive(true);
			return val;
		}

		protected virtual void Awake()
		{
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Expected O, but got Unknown
			controller = ((Component)this).GetComponent<PlayerControllerB>();
			ModelReplacementAPI.Instance.Logger.LogInfo((object)$"Awake {controller.playerUsername} {this}");
			viewState = ((Component)this).GetComponent<ViewStateManager>();
			cosmeticManager = ((Component)this).GetComponent<MoreCompanyCosmeticManager>();
			matHelper = new MaterialHelper();
			replacementModel = LoadModelReplacement();
			try
			{
				AddModelScripts();
			}
			catch (Exception ex)
			{
				ModelReplacementAPI.Instance.Logger.LogError((object)("Could not set all model scripts.\n Error: " + ex.Message));
			}
			if (viewState.localPlayer)
			{
				replacementModelShadow = Object.Instantiate<GameObject>(replacementModel);
				GameObject obj = replacementModelShadow;
				((Object)obj).name = ((Object)obj).name + "(Shadow)";
				Renderer[] componentsInChildren = replacementModelShadow.GetComponentsInChildren<Renderer>();
				foreach (Renderer val in componentsInChildren)
				{
					val.shadowCastingMode = (ShadowCastingMode)3;
					((Component)val).gameObject.layer = viewState.VisibleLayer;
				}
			}
			replacementViewModel = LoadViewModelreplacement();
			avatar = GetAvatarUpdater();
			shadowAvatar = GetAvatarUpdater();
			viewModelAvatar = GetViewModelUpdater();
			ragdollAvatar = new AvatarUpdater();
			cosmeticAvatar = avatar;
			avatar.AssignModelReplacement(((Component)controller).gameObject, replacementModel);
			shadowAvatar.AssignModelReplacement(((Component)controller).gameObject, replacementModelShadow);
			viewModelAvatar.AssignViewModelReplacement(((Component)controller).gameObject, replacementViewModel);
			SetAvatarRenderers(enabled: true);
			viewState.ReportBodyReplacementAddition(this);
			cosmeticManager.ReportBodyReplacementAddition(this);
			GameObject val2 = new GameObject("MRAPINameCollider");
			val2.layer = 23;
			val2.transform.SetParent(replacementModel.transform);
			nameTagCollider = val2.AddComponent<BoxCollider>();
			((Collider)nameTagCollider).isTrigger = true;
			RaycastTarget raycastTarget = val2.AddComponent<RaycastTarget>();
			raycastTarget.controller = controller;
			raycastTarget.bodyReplacement = this;
			raycastTarget.modelObj = replacementModel;
			allBodies.Add(this);
			ModelReplacementAPI.Instance.Logger.LogInfo((object)("AwakeEnd " + controller.playerUsername));
		}

		protected virtual void Start()
		{
		}

		public virtual void LateUpdate()
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			try
			{
				val = ((Component)controller.deadBody).gameObject;
			}
			catch
			{
			}
			if (Object.op_Implicit((Object)(object)val) && (Object)(object)replacementDeadBody == (Object)null)
			{
				cosmeticAvatar = ragdollAvatar;
				CreateAndParentRagdoll(controller.deadBody);
				OnDeath();
			}
			if (Object.op_Implicit((Object)(object)replacementDeadBody) && (Object)(object)val == (Object)null)
			{
				cosmeticAvatar = avatar;
				Object.Destroy((Object)(object)replacementDeadBody);
				replacementDeadBody = null;
			}
			if (Object.op_Implicit((Object)(object)val) && !val.activeInHierarchy && (Object)(object)replacementDeadBody != (Object)null)
			{
				replacementDeadBody.SetActive(false);
			}
			avatar.Update();
			shadowAvatar.Update();
			ragdollAvatar.Update();
			viewModelAvatar.Update();
			cosmeticManager.UpdateModelReplacement();
			if ((Object)(object)replacementModel != (Object)null)
			{
				Bounds bounds = GetBounds(replacementModel);
				nameTagCollider.center = ((Bounds)(ref bounds)).center;
				nameTagCollider.size = ((Bounds)(ref bounds)).size;
			}
			previousDanceNumber = danceNumber;
			if (!((Object)(object)controller.playerBodyAnimator != (Object)null))
			{
				return;
			}
			AnimatorStateInfo currentAnimatorStateInfo = controller.playerBodyAnimator.GetCurrentAnimatorStateInfo(1);
			int fullPathHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash;
			if (controller.performingEmote)
			{
				switch (fullPathHash)
				{
				case -462656950:
					danceNumber = 1;
					break;
				case 2103786480:
					danceNumber = 2;
					break;
				default:
					danceNumber = 3;
					break;
				}
			}
			else
			{
				danceNumber = 0;
			}
			if (ModelReplacementAPI.tooManyEmotesPresent)
			{
				danceNumber = SafeGetEmoteID(danceNumber);
			}
			if (danceNumber != previousDanceNumber)
			{
				if (previousDanceNumber == 0)
				{
					((MonoBehaviour)this).StartCoroutine(WaitForDanceNumberChange());
				}
				else if (danceNumber == 0)
				{
					OnEmoteEnd();
				}
				else if (!emoteOngoing)
				{
					OnEmoteStart(danceNumber);
				}
			}
		}

		static BodyReplacementBase()
		{
			allBodies = new List<BodyReplacementBase>();
			RenderPipelineManager.beginContextRendering += ReallyLateUpdate;
		}

		public static void ReallyLateUpdate(ScriptableRenderContext context, List<Camera> cameras)
		{
			for (int i = 0; i < allBodies.Count; i++)
			{
				try
				{
					BodyReplacementBase bodyReplacementBase = allBodies[i];
					if (Object.op_Implicit((Object)(object)bodyReplacementBase) && ((Behaviour)bodyReplacementBase).isActiveAndEnabled && Object.op_Implicit((Object)(object)bodyReplacementBase.viewModelAvatar.replacementViewModel))
					{
						bodyReplacementBase.UpdateItemTransform();
					}
				}
				catch (Exception value)
				{
					Console.WriteLine(value);
				}
			}
		}

		protected virtual void OnDestroy()
		{
			ModelReplacementAPI.Instance.Logger.LogInfo((object)("Destroy body component for " + controller.playerUsername));
			allBodies.Remove(this);
			Object.Destroy((Object)(object)replacementModel);
			Object.Destroy((Object)(object)replacementModelShadow);
			Object.Destroy((Object)(object)replacementViewModel);
			Object.Destroy((Object)(object)replacementDeadBody);
		}

		public void UpdateItemTransform()
		{
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)heldItem))
			{
				return;
			}
			if ((Object)(object)heldItem.parentObject == (Object)null || (Object)(object)heldItem.playerHeldBy != (Object)(object)controller || (Object)(object)controller.ItemSlots[controller.currentItemSlot] != (Object)(object)heldItem)
			{
				heldItem = null;
				return;
			}
			if (viewState.GetViewState() == ViewState.FirstPerson)
			{
				if (heldItem.itemProperties.twoHandedAnimation)
				{
					((Component)heldItem).transform.Translate((viewModelAvatar.ItemOffsetLeft + viewModelAvatar.ItemOffsetRight) / 2f, (Space)0);
				}
				else
				{
					((Component)heldItem).transform.Translate(viewModelAvatar.ItemOffsetRight, (Space)0);
				}
			}
			else
			{
				if (viewState.localPlayer)
				{
					((Component)heldItem).transform.rotation = controller.serverItemHolder.rotation;
					((Component)heldItem).transform.Rotate(heldItem.itemProperties.rotationOffset);
					((Component)heldItem).transform.position = controller.serverItemHolder.position + controller.serverItemHolder.rotation * heldItem.itemProperties.positionOffset;
				}
				if (heldItem.itemProperties.twoHandedAnimation)
				{
					((Component)heldItem).transform.Translate((avatar.ItemOffsetLeft + avatar.ItemOffsetRight) / 2f, (Space)0);
				}
				else
				{
					((Component)heldItem).transform.Translate(avatar.ItemOffsetRight, (Space)0);
				}
			}
			GrabbableObject obj = heldItem;
			JetpackItem val = (JetpackItem)(object)((obj is JetpackItem) ? obj : null);
			if (val != null)
			{
				Quaternion val2 = avatar.lowerSpine.rotation * avatar.jetpackRotOffset;
				val.backPart.rotation = val2;
				val.backPart.Rotate(val.backPartRotationOffset);
				val.backPart.position = avatar.lowerSpine.position + val2 * val.backPartPositionOffset;
			}
		}

		private static List<Transform> GetAllTransforms(Transform parent)
		{
			List<Transform> list = new List<Transform>();
			BuildTransformList(list, parent);
			return list;
		}

		private static void BuildTransformList(ICollection<Transform> transforms, Transform parent)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if ((Object)(object)parent == (Object)null)
			{
				return;
			}
			foreach (Transform item in parent)
			{
				Transform val = item;
				transforms.Add(val);
				BuildTransformList(transforms, val);
			}
		}

		private void CreateAndParentRagdoll(DeadBodyInfo bodyinfo)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			deadBody = ((Component)bodyinfo).gameObject;
			deadBody.layer = ViewStateManager.ragdollLayer;
			SkinnedMeshRenderer componentInChildren = deadBody.GetComponentInChildren<SkinnedMeshRenderer>();
			replacementDeadBody = LoadRagdollReplacement(bodyinfo.causeOfDeath);
			ragdollAvatar.AssignModelReplacement(deadBody, replacementDeadBody);
			foreach (Transform allTransform in GetAllTransforms(replacementDeadBody.transform))
			{
				((Component)allTransform).gameObject.layer = ViewStateManager.ragdollLayer;
			}
			Renderer[] componentsInChildren = replacementDeadBody.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				val.enabled = true;
				val.shadowCastingMode = (ShadowCastingMode)1;
				((Component)val).gameObject.layer = viewState.VisibleLayer;
				val.renderingLayerMask = 513u;
			}
			((Renderer)componentInChildren).enabled = false;
			Console.WriteLine("Ragdoll Creation.");
			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);
				}
			}
		}

		public void SetAvatarRenderers(bool enabled)
		{
			Renderer[] componentsInChildren = replacementModel.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				val.enabled = enabled;
			}
			if ((Object)(object)replacementViewModel != (Object)null)
			{
				Renderer[] componentsInChildren2 = replacementViewModel.GetComponentsInChildren<Renderer>();
				foreach (Renderer val2 in componentsInChildren2)
				{
					val2.enabled = enabled;
				}
			}
		}

		private Bounds GetBounds(GameObject model)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: 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_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			IEnumerable<Bounds> source = from r in model.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(x2, y, z));
			return result;
		}

		private IEnumerator WaitForDanceNumberChange()
		{
			if (emoteOngoing)
			{
				yield break;
			}
			emoteOngoing = true;
			for (int frame = 0; frame < 20; frame++)
			{
				if (danceNumber == 0)
				{
					emoteOngoing = false;
					yield break;
				}
				yield return (object)new WaitForEndOfFrame();
			}
			if (danceNumber != 0)
			{
				emoteOngoing = false;
				OnEmoteStart(danceNumber);
			}
		}

		private int SafeGetEmoteID(int currentID)
		{
			return DangerousGetEmoteID(currentID);
		}

		private int DangerousGetEmoteID(int currentID)
		{
			UnlockableEmote currentlyPlayingEmote = PlayerPatcher.GetCurrentlyPlayingEmote(controller);
			if (currentlyPlayingEmote == null)
			{
				return currentID;
			}
			if (currentlyPlayingEmote.emoteId == 1)
			{
				return -1;
			}
			if (currentlyPlayingEmote.emoteId == 2)
			{
				return -2;
			}
			if (currentlyPlayingEmote.emoteId == 3)
			{
				return -3;
			}
			return currentlyPlayingEmote.emoteId;
		}
	}
	public enum ViewState
	{
		None,
		ThirdPerson,
		FirstPerson,
		Debug
	}
	public class ViewStateManager : ManagerBase
	{
		private static int CullingMaskThirdPerson = 0;

		public static int CullingMaskFirstPerson = 0;

		private static int CullingNoPostExcluded = 0;

		public static int modelLayer = 23;

		public static int armsLayer = 4;

		public static int visibleLayer = 0;

		private static int invisibleLayer = 31;

		public static int NoPostModelLayer = 17;

		public static int NoPostVisibleLayer = 27;

		public static int ragdollLayer = 20;

		private MeshRenderer nameTagObj = null;

		private MeshRenderer nameTagObj2 = null;

		private Renderer Hud = null;

		private MeshRenderer helmet = null;

		private bool HUDDefault = true;

		private bool UseNoPostProcessing => bodyReplacementExists && bodyReplacement.UseNoPostProcessing;

		public int ModelLayer => UseNoPostProcessing ? NoPostModelLayer : modelLayer;

		public int ArmsLayer => armsLayer;

		public int VisibleLayer => UseNoPostProcessing ? NoPostVisibleLayer : visibleLayer;

		public int InvisibleLayer => invisibleLayer;

		protected override void Awake()
		{
			base.Awake();
			MeshRenderer[] componentsInChildren = ((Component)controller).gameObject.GetComponentsInChildren<MeshRenderer>();
			nameTagObj = componentsInChildren.Where((MeshRenderer x) => ((Object)((Component)x).gameObject).name == "LevelSticker").First();
			nameTagObj2 = componentsInChildren.Where((MeshRenderer x) => ((Object)((Component)x).gameObject).name == "BetaBadge").First();
			helmet = GameObject.Find("Systems/Rendering/PlayerHUDHelmetModel").GetComponentInChildren<MeshRenderer>();
			Hud = ((Component)((Component)controller.localVisor).transform.GetChild(0)).GetComponent<Renderer>();
			HUDDefault = Hud.enabled;
			int num = (1 << modelLayer) + (1 << NoPostModelLayer);
			int num2 = 1 << armsLayer;
			int num3 = (1 << visibleLayer) + (1 << NoPostVisibleLayer);
			int num4 = (1 << NoPostModelLayer) + (1 << NoPostVisibleLayer);
			CullingMaskFirstPerson = controller.gameplayCamera.cullingMask;
			CullingMaskFirstPerson |= num2;
			CullingMaskFirstPerson &= ~num;
			CullingMaskFirstPerson |= num3;
			CullingMaskThirdPerson = controller.gameplayCamera.cullingMask;
			CullingMaskThirdPerson &= ~num2;
			CullingMaskThirdPerson |= num;
			CullingMaskThirdPerson |= num3;
			CullingNoPostExcluded = int.MaxValue;
			CullingNoPostExcluded &= ~num4;
			int[] obj = new int[6] { 0, 21, 3, 14, 22, 6 };
			obj[0] = ragdollLayer;
			int[] array = obj;
			int[] array2 = array;
			foreach (int num5 in array2)
			{
			}
		}

		public void Start()
		{
			RendererPatches();
		}

		public override void ReportBodyReplacementAddition(BodyReplacementBase replacement)
		{
			base.ReportBodyReplacementAddition(replacement);
			PatchViewState();
		}

		public override void UpdatePlayer()
		{
			ViewState viewState = GetViewState();
			SetPlayerRenderers(enabled: true, helmetShadow: true);
			controller.gameplayCamera.cullingMask = CullingMaskFirstPerson;
			switch (viewState)
			{
			case ViewState.None:
				SetArmLayers(InvisibleLayer);
				SetPlayerLayers(invisibleLayer);
				if (base.localPlayer)
				{
					Hud.enabled = false;
				}
				break;
			case ViewState.FirstPerson:
				SetArmLayers(ArmsLayer);
				SetPlayerLayers(modelLayer);
				if (base.localPlayer)
				{
					Hud.enabled = HUDDefault;
				}
				break;
			case ViewState.ThirdPerson:
				SetArmLayers(InvisibleLayer);
				SetPlayerLayers(visibleLayer);
				if (ModelReplacementAPI.LCthirdPersonPresent)
				{
					controller.gameplayCamera.cullingMask = CullingMaskThirdPerson;
				}
				if (base.localPlayer)
				{
					Hud.enabled = false;
				}
				break;
			}
		}

		public override void UpdateModelReplacement()
		{
			ViewState viewState = GetViewState();
			SetPlayerRenderers(enabled: false, helmetShadow: false);
			SetPlayerLayers(modelLayer);
			SetShadowModel(enabled: false);
			controller.gameplayCamera.cullingMask = CullingMaskFirstPerson;
			switch (viewState)
			{
			case ViewState.None:
				SetArmLayers(InvisibleLayer);
				SetAvatarLayers(InvisibleLayer, (ShadowCastingMode)0);
				break;
			case ViewState.FirstPerson:
				SetArmLayers(ArmsLayer);
				SetAvatarLayers(ModelLayer, (ShadowCastingMode)1);
				SetShadowModel(enabled: true);
				if (base.localPlayer)
				{
					Hud.enabled = !bodyReplacement.RemoveHelmet && HUDDefault;
				}
				break;
			case ViewState.ThirdPerson:
				SetArmLayers(InvisibleLayer);
				SetAvatarLayers(VisibleLayer, (ShadowCastingMode)1);
				if (ModelReplacementAPI.LCthirdPersonPresent)
				{
					controller.gameplayCamera.cullingMask = CullingMaskThirdPerson;
				}
				if (base.localPlayer)
				{
					Hud.enabled = false;
				}
				break;
			}
		}

		public ViewState GetViewState()
		{
			if (!controller.isPlayerControlled)
			{
				return ViewState.None;
			}
			if ((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)(object)controller)
			{
				return ViewState.ThirdPerson;
			}
			if (ModelReplacementAPI.thirdPersonPresent && Safe3rdPersonActive())
			{
				return ViewState.ThirdPerson;
			}
			if (ModelReplacementAPI.LCthirdPersonPresent && SafeLCActive())
			{
				return ViewState.ThirdPerson;
			}
			if (ModelReplacementAPI.recordingCameraPresent && SafeRecCamActive())
			{
				return ViewState.ThirdPerson;
			}
			if (ModelReplacementAPI.tooManyEmotesPresent && SafeTMEActive())
			{
				return ViewState.ThirdPerson;
			}
			return ViewState.FirstPerson;
		}

		public void SetPlayerRenderers(bool enabled, bool helmetShadow)
		{
			if (base.localPlayer)
			{
				((Renderer)helmet).shadowCastingMode = (ShadowCastingMode)(helmetShadow ? 1 : 0);
			}
			((Renderer)controller.thisPlayerModel).enabled = enabled;
			((Renderer)controller.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)1;
			((Renderer)controller.thisPlayerModelLOD1).enabled = enabled;
			((Renderer)controller.thisPlayerModelLOD1).shadowCastingMode = (ShadowCastingMode)3;
			((Renderer)controller.thisPlayerModelLOD2).enabled = false;
			((Renderer)nameTagObj).enabled = enabled;
			((Renderer)nameTagObj2).enabled = enabled;
		}

		public void SetPlayerLayers(int layer)
		{
			((Component)controller.thisPlayerModel).gameObject.layer = layer;
			((Component)controller.thisPlayerModelLOD1).gameObject.layer = visibleLayer;
			((Component)controller.thisPlayerModelLOD2).gameObject.layer = visibleLayer;
			((Component)nameTagObj).gameObject.layer = layer;
			((Component)nameTagObj2).gameObject.layer = layer;
		}

		public void SetAvatarLayers(int layer, ShadowCastingMode mode)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)replacementModel == (Object)null))
			{
				Renderer[] componentsInChildren = replacementModel.GetComponentsInChildren<Renderer>();
				Renderer[] array = componentsInChildren;
				foreach (Renderer val in array)
				{
					val.shadowCastingMode = mode;
					((Component)val).gameObject.layer = layer;
				}
			}
		}

		public void SetArmLayers(int layer)
		{
			if (Object.op_Implicit((Object)(object)replacementViewModel))
			{
				((Component)controller.thisPlayerModelArms).gameObject.layer = InvisibleLayer;
				Renderer[] componentsInChildren = replacementViewModel.GetComponentsInChildren<Renderer>();
				Renderer[] array = componentsInChildren;
				foreach (Renderer val in array)
				{
					((Component)val).gameObject.layer = layer;
					val.shadowCastingMode = (ShadowCastingMode)0;
				}
			}
			else
			{
				((Component)controller.thisPlayerModelArms).gameObject.layer = layer;
			}
		}

		public void SetShadowModel(bool enabled)
		{
			if (!((Object)(object)bodyReplacement.replacementModelShadow == (Object)null))
			{
				bodyReplacement.replacementModelShadow.SetActive(enabled);
			}
		}

		public void RendererPatches()
		{
			PatchViewState();
			if (ModelReplacementAPI.recordingCameraPresent)
			{
				SafeFixRecordingCamera();
			}
			if (ModelReplacementAPI.thirdPersonPresent)
			{
				SafeFix3rdPerson();
			}
			if (!ModelReplacementAPI.LCthirdPersonPresent)
			{
			}
		}

		public static void PatchViewState()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			CustomPass val = GameObject.Find("Systems/Rendering/CustomPass").GetComponent<CustomPassVolume>().customPasses.First();
			((DrawRenderersCustomPass)((val is DrawRenderersCustomPass) ? val : null)).layerMask = LayerMask.op_Implicit(CullingNoPostExcluded);
			Camera[] array = Object.FindObjectsOfType<Camera>();
			int num = 1 << modelLayer;
			int num2 = 1 << visibleLayer;
			int num3 = 1 << NoPostModelLayer;
			int num4 = 1 << NoPostVisibleLayer;
			int num5 = 8;
			Camera[] array2 = array;
			foreach (Camera val2 in array2)
			{
				int cullingMask = val2.cullingMask;
				if ((cullingMask & num) != 0 && (cullingMask & num3) == 0)
				{
					val2.cullingMask += num3;
				}
				if ((cullingMask & num2) != 0 && (cullingMask & num4) == 0)
				{
					val2.cullingMask += num4;
				}
			}
			Camera component = GameObject.Find("Environment/HangarShip/Cameras/FrontDoorSecurityCam/SecurityCamera").GetComponent<Camera>();
			if ((component.cullingMask & (1 << modelLayer)) == 0)
			{
				component.cullingMask += 1 << modelLayer;
			}
			Camera component2 = GameObject.Find("Environment/HangarShip/Cameras/ShipCamera").GetComponent<Camera>();
			if ((component2.cullingMask & (1 << modelLayer)) == 0)
			{
				component2.cullingMask += 1 << modelLayer;
			}
		}

		public bool Safe3rdPersonActive()
		{
			return DangerousViewState3rdPerson();
		}

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

		public bool SafeLCActive()
		{
			return DangerousLCViewState();
		}

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

		public bool SafeRecCamActive()
		{
			IEnumerable<Camera> source = from x in Object.FindObjectsOfType<Camera>()
				where ((Object)((Component)x).gameObject).name == "ThridPersonCam"
				select x;
			if (!source.Any())
			{
				return false;
			}
			return ((Behaviour)source.First()).enabled;
		}

		private void SafeFixRecordingCamera()
		{
			((MonoBehaviour)this).StartCoroutine(DangerousFixRecordingCamera());
		}

		private IEnumerator DangerousFixRecordingCamera()
		{
			for (int frame = 0; frame < 20; frame++)
			{
				yield return (object)new WaitForEndOfFrame();
			}
			IEnumerable<Camera> a = from x in Object.FindObjectsOfType<Camera>()
				where ((Object)((Component)x).gameObject).name == "ThridPersonCam"
				select x;
			a.First().cullingMask = CullingMaskThirdPerson;
		}

		private void SafeFix3rdPerson()
		{
			DangerousFix3rdPerson();
		}

		private void DangerousFix3rdPerson()
		{
			ThirdPersonCamera.GetCamera.cullingMask = CullingMaskThirdPerson;
		}

		private bool SafeTMEActive()
		{
			return DangerousTMEViewState();
		}

		private bool DangerousTMEViewState()
		{
			try
			{
				return ((Behaviour)Traverse.Create(typeof(ThirdPersonEmoteController)).Field("emoteCamera").GetValue<Camera>()).enabled;
			}
			catch
			{
				return false;
			}
		}
	}
}
namespace ModelReplacement.AvatarBodyUpdater
{
	public class AvatarUpdater
	{
		protected SkinnedMeshRenderer playerModelRenderer = null;

		protected Animator replacementAnimator = null;

		protected GameObject player = null;

		protected GameObject replacement = null;

		protected bool hasUpperChest = false;

		protected Vector3 rootPositionOffset = Vector3.zero;

		protected 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 Transform lowerSpine { get; private set; } = null;


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


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


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


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


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


		public Vector3 ItemOffsetLeft => CustomHandTransformLeft.position - HandTransformLeft.position;

		public Vector3 ItemOffsetRight => CustomHandTransformRight.position - HandTransformRight.position;

		public virtual void AssignModelReplacement(GameObject player, GameObject replacement)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)replacement == (Object)null)
			{
				return;
			}
			PlayerControllerB component = player.GetComponent<PlayerControllerB>();
			playerModelRenderer = (Object.op_Implicit((Object)(object)component) ? component.thisPlayerModel : player.GetComponentInChildren<SkinnedMeshRenderer>());
			if ((Object)(object)playerModelRenderer == (Object)null)
			{
				ModelReplacementAPI.Instance.Logger.LogFatal((object)"Failed to start AvatarBodyUpdater");
				return;
			}
			this.player = player;
			replacementAnimator = replacement.GetComponentInChildren<Animator>();
			this.replacement = replacement;
			OffsetBuilder component2 = ((Component)replacementAnimator).gameObject.GetComponent<OffsetBuilder>();
			rootPositionOffset = component2.rootPositionOffset;
			Transform boneTransform = replacementAnimator.GetBoneTransform((HumanBodyBones)54);
			hasUpperChest = (Object)(object)boneTransform != (Object)null;
			lowerSpine = GetAvatarTransformFromBoneName("spine.001");
			RotationOffset component3 = ((Component)lowerSpine).GetComponent<RotationOffset>();
			if (Object.op_Implicit((Object)(object)component3))
			{
				jetpackRotOffset = Quaternion.Inverse(component3.offset);
			}
			HandTransformLeft = GetPlayerTransformFromBoneName("hand.L");
			HandTransformRight = GetPlayerTransformFromBoneName("hand.R");
			CustomHandTransformLeft = GetAvatarTransformFromBoneName("hand.L");
			CustomHandTransformRight = GetAvatarTransformFromBoneName("hand.R");
		}

		protected virtual void UpdateModel()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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)
			replacement.transform.SetPositionAndRotation(((Component)playerModelRenderer).transform.position, ((Component)playerModelRenderer).transform.rotation);
			Transform avatarTransformFromBoneName = GetAvatarTransformFromBoneName("spine");
			Transform playerTransformFromBoneName = GetPlayerTransformFromBoneName("spine");
			avatarTransformFromBoneName.position = playerTransformFromBoneName.position + playerTransformFromBoneName.TransformVector(rootPositionOffset);
			Transform[] bones = playerModelRenderer.bones;
			foreach (Transform val in bones)
			{
				Transform avatarTransformFromBoneName2 = GetAvatarTransformFromBoneName(((Object)val).name);
				if (!((Object)(object)avatarTransformFromBoneName2 == (Object)null))
				{
					avatarTransformFromBoneName2.rotation = val.rotation;
					RotationOffset component = ((Component)avatarTransformFromBoneName2).GetComponent<RotationOffset>();
					if (Object.op_Implicit((Object)(object)component))
					{
						avatarTransformFromBoneName2.rotation *= component.offset;
					}
				}
			}
		}

		public void Update()
		{
			if (!((Object)(object)replacement == (Object)null) && !((Object)(object)playerModelRenderer == (Object)null) && !((Object)(object)replacementAnimator == (Object)null))
			{
				UpdateModel();
			}
		}

		public Transform GetAvatarTransformFromBoneName(string boneName)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			if (boneName == "spine.002")
			{
				return hasUpperChest ? replacementAnimator.GetBoneTransform((HumanBodyBones)8) : null;
			}
			if (boneName == "spine.003")
			{
				return hasUpperChest ? replacementAnimator.GetBoneTransform((HumanBodyBones)54) : replacementAnimator.GetBoneTransform((HumanBodyBones)8);
			}
			if (boneName.Contains("PlayerRagdoll"))
			{
				return replacementAnimator.GetBoneTransform((HumanBodyBones)0);
			}
			HumanBodyBones value;
			return modelToAvatarBone.TryGetValue(boneName, out value) ? replacementAnimator.GetBoneTransform(value) : null;
		}

		public Transform GetPlayerTransformFromBoneName(string boneName)
		{
			Transform[] bones = playerModelRenderer.bones;
			Transform val = ((IEnumerable<Transform>)bones).FirstOrDefault((Func<Transform, bool>)((Transform x) => ((Object)x).name == boneName));
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			if (boneName == "spine")
			{
				return ((IEnumerable<Transform>)bones).FirstOrDefault((Func<Transform, bool>)((Transform x) => ((Object)x).name.Contains("PlayerRagdoll")));
			}
			return null;
		}
	}
	public class RotationOffset : MonoBehaviour
	{
		public Quaternion offset = Quaternion.identity;

		public bool RenderMCC = true;

		public Vector3 MCCPosition = Vector3.zero;

		public Quaternion MCCRotation = Quaternion.identity;

		public Vector3 MCCScale = Vector3.one;
	}
	public class OffsetBuilder : MonoBehaviour
	{
		public Vector3 rootPositionOffset = new Vector3(0f, 0f, 0f);

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

		public Vector3 itemPositonOffset = new Vector3(0f, 0f, 0f);

		public Quaternion itemRotationOffset = Quaternion.identity;

		public GameObject itemHolder = null;

		public bool UseNoPostProcessing = false;

		public bool GenerateViewModel = false;

		public bool RemoveHelmet = false;

		public GameObject ViewModel = null;
	}
}
namespace ModelReplacement.Scripts
{
	public class MaterialHelper
	{
		private static readonly string[] shaderPrefixWhitelist = new string[9] { "HDRP/", "GUI/", "Sprites/", "UI/", "Unlit/", "Toon", "lilToon", "Shader Graphs/", "Hidden/" };

		public virtual Material GetReplacementMaterial(Material gameMaterial, Material modelMaterial)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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;
			}
			ModelReplacementAPI.Instance.Logger.LogInfo((object)("Creating replacement material for material " + ((Object)modelMaterial).name + " / shader " + ((Object)modelMaterial.shader).name));
			Material val = new Material(gameMaterial);
			val.color = modelMaterial.color;
			val.mainTexture = modelMaterial.mainTexture;
			val.mainTextureOffset = modelMaterial.mainTextureOffset;
			val.mainTextureScale = modelMaterial.mainTextureScale;
			val.EnableKeyword("_EMISSION");
			val.EnableKeyword("_NORMALMAP");
			val.EnableKeyword("_SPECGLOSSMAP");
			val.SetFloat("_NormalScale", 0f);
			HDMaterial.ValidateMaterial(val);
			return val;
		}
	}
	public static class MeshHelper
	{
		public static int[] ConvertByteArrayToIntArray(byte[] bytes, int stride, int count)
		{
			int[] array = new int[count];
			int num = 0;
			for (int i = 0; i < count; i++)
			{
				int num2 = 0;
				for (int j = 0; j < stride; j++)
				{
					num2 += bytes[num + j] << 8 * j;
				}
				array[i] = num2;
				num += stride;
			}
			return array;
		}

		public static byte[] ConvertIntArrayToByteArray(int[] ints, int stride, int count)
		{
			List<byte> list = new List<byte>();
			for (int i = 0; i < count; i++)
			{
				for (int j = 0; j < stride; j++)
				{
					list.Add((byte)(ints[i] >> 8 * j));
				}
			}
			return list.ToArray();
		}

		public static GameObject ConvertModelToViewModel(GameObject TempReplacementViewModel)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			Animator componentInChildren = TempReplacementViewModel.GetComponentInChildren<Animator>();
			HashSet<Transform> hashSet = new HashSet<Transform>();
			foreach (HumanBodyBones viewModelHumanBone in ViewModelUpdater.ViewModelHumanBones)
			{
				Transform boneTransform = componentInChildren.GetBoneTransform(viewModelHumanBone);
				if ((Object)(object)boneTransform != (Object)null)
				{
					hashSet.Add(boneTransform);
					Transform[] componentsInChildren = ((Component)boneTransform).GetComponentsInChildren<Transform>();
					foreach (Transform item in componentsInChildren)
					{
						hashSet.Add(item);
					}
				}
			}
			SkinnedMeshRenderer[] componentsInChildren2 = TempReplacementViewModel.GetComponentsInChildren<SkinnedMeshRenderer>();
			foreach (SkinnedMeshRenderer val in componentsInChildren2)
			{
				val.sharedMesh = Object.Instantiate<Mesh>(val.sharedMesh);
				Mesh sharedMesh = val.sharedMesh;
				bool[] array = new bool[val.bones.Length];
				for (int k = 0; k < val.bones.Length; k++)
				{
					array[k] = hashSet.Contains(val.bones[k]);
				}
				NativeArray<byte> bonesPerVertex = sharedMesh.GetBonesPerVertex();
				NativeArray<BoneWeight1> allBoneWeights = sharedMesh.GetAllBoneWeights();
				int num = 0;
				bool[] array2 = new bool[sharedMesh.vertexCount];
				for (int l = 0; l < sharedMesh.vertexCount; l++)
				{
					array2[l] = true;
					for (int m = 0; m < bonesPerVertex[l]; m++)
					{
						if (array2[l])
						{
							BoneWeight1 val2 = allBoneWeights[num];
							if (!array[((BoneWeight1)(ref val2)).boneIndex])
							{
								array2[l] = false;
							}
						}
						num++;
					}
				}
				GraphicsBuffer indexBuffer = sharedMesh.GetIndexBuffer();
				int num2 = indexBuffer.stride * indexBuffer.count;
				byte[] array3 = new byte[num2];
				indexBuffer.GetData((Array)array3);
				int[] array4 = ConvertByteArrayToIntArray(array3, indexBuffer.stride, indexBuffer.count);
				Dictionary<int, int> dictionary = new Dictionary<int, int>();
				Dictionary<int, int> dictionary2 = new Dictionary<int, int>();
				List<int> list = new List<int>();
				for (int n = 0; n < sharedMesh.subMeshCount; n++)
				{
					dictionary.Add(n, list.Count);
					dictionary2.Add(n, 0);
					SubMeshDescriptor subMesh = sharedMesh.GetSubMesh(n);
					int indexStart = ((SubMeshDescriptor)(ref subMesh)).indexStart;
					int indexCount = ((SubMeshDescriptor)(ref subMesh)).indexCount;
					for (int num3 = indexStart; num3 < indexStart + indexCount; num3 += 3)
					{
						if (array2[array4[num3]] && array2[array4[num3 + 1]] && array2[array4[num3 + 2]])
						{
							list.Add(array4[num3]);
							list.Add(array4[num3 + 1]);
							list.Add(array4[num3 + 2]);
							dictionary2[n] += 3;
						}
					}
				}
				byte[] data = ConvertIntArrayToByteArray(list.ToArray(), indexBuffer.stride, list.Count);
				sharedMesh.SetIndexBufferParams(list.Count, sharedMesh.indexFormat);
				indexBuffer.SetData((Array)data);
				for (int num4 = 0; num4 < sharedMesh.subMeshCount; num4++)
				{
					sharedMesh.SetSubMesh(num4, new SubMeshDescriptor(dictionary[num4], dictionary2[num4], (MeshTopology)0), (MeshUpdateFlags)0);
				}
				indexBuffer.Release();
			}
			return TempReplacementViewModel;
		}
	}
	public static class Vector3Helper
	{
		public static void MoveSmoothly(this Vector3 from, Vector3 to)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			from = Vector3.Lerp(from, to, 0.1f);
		}
	}
}
namespace ModelReplacement.Scripts.Player
{
	public class ViewModelUpdater
	{
		private Transform armsMetarig;

		private Animator viewModelAnimator;

		private bool hasShoulder = true;

		protected static Dictionary<string, HumanBodyBones> modelToAvatarBone = new Dictionary<string, HumanBodyBones>
		{
			{
				"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
			}
		};

		protected static List<string> ArmTransformNames = new List<string>
		{
			"shoulder.L", "arm.L_upper", "arm.L_lower", "hand.L", "finger5.L", "finger5.L.001", "finger4.L", "finger4.L.001", "finger3.L", "finger3.L.001",
			"finger2.L", "finger2.L.001", "finger1.L", "finger1.L.001", "shoulder.R", "arm.R_upper", "arm.R_lower", "hand.R", "finger5.R", "finger5.R.001",
			"finger4.R", "finger4.R.001", "finger3.R", "finger3.R.001", "finger2.R", "finger2.R.001", "finger1.R", "finger1.R.001"
		};

		public static List<HumanBodyBones> ViewModelHumanBones = new List<HumanBodyBones>
		{
			(HumanBodyBones)11,
			(HumanBodyBones)13,
			(HumanBodyBones)15,
			(HumanBodyBones)17,
			(HumanBodyBones)36,
			(HumanBodyBones)37,
			(HumanBodyBones)33,
			(HumanBodyBones)34,
			(HumanBodyBones)30,
			(HumanBodyBones)31,
			(HumanBodyBones)27,
			(HumanBodyBones)28,
			(HumanBodyBones)24,
			(HumanBodyBones)26,
			(HumanBodyBones)12,
			(HumanBodyBones)14,
			(HumanBodyBones)16,
			(HumanBodyBones)18,
			(HumanBodyBones)51,
			(HumanBodyBones)52,
			(HumanBodyBones)48,
			(HumanBodyBones)49,
			(HumanBodyBones)45,
			(HumanBodyBones)46,
			(HumanBodyBones)42,
			(HumanBodyBones)43,
			(HumanBodyBones)39,
			(HumanBodyBones)41
		};

		public GameObject replacementViewModel { get; private set; } = null;


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


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


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


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


		public Vector3 ItemOffsetLeft => CustomHandTransformLeft.position - HandTransformLeft.position;

		public Vector3 ItemOffsetRight => CustomHandTransformRight.position - HandTransformRight.position;

		public virtual void AssignViewModelReplacement(GameObject player, GameObject replacementViewModel)
		{
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)replacementViewModel == (Object)null))
			{
				PlayerControllerB component = player.GetComponent<PlayerControllerB>();
				this.replacementViewModel = replacementViewModel;
				viewModelAnimator = replacementViewModel.GetComponentInChildren<Animator>();
				armsMetarig = component.playerModelArmsMetarig;
				List<string> list = new List<string> { "shoulder.L", "arm.L_upper", "arm.L_lower", "hand.L" };
				if ((Object)(object)GetViewModelTransformFromBoneName("shoulder.L") == (Object)null || (Object)(object)GetViewModelTransformFromBoneName("shoulder.R") == (Object)null)
				{
					hasShoulder = false;
				}
				float num = 0f;
				float num2 = 0f;
				for (int i = ((!hasShoulder) ? 1 : 0); i < list.Count - 1; i++)
				{
					Transform armTransformFromBoneName = GetArmTransformFromBoneName(list[i]);
					Transform armTransformFromBoneName2 = GetArmTransformFromBoneName(list[i + 1]);
					float num3 = num;
					Vector3 val = armTransformFromBoneName2.position - armTransformFromBoneName.position;
					num = num3 + ((Vector3)(ref val)).magnitude;
					Transform viewModelTransformFromBoneName = GetViewModelTransformFromBoneName(list[i]);
					Transform viewModelTransformFromBoneName2 = GetViewModelTransformFromBoneName(list[i + 1]);
					float num4 = num2;
					val = viewModelTransformFromBoneName2.position - viewModelTransformFromBoneName.position;
					num2 = num4 + ((Vector3)(ref val)).magnitude;
				}
				HandTransformLeft = GetArmTransformFromBoneName("hand.L");
				HandTransformRight = GetArmTransformFromBoneName("hand.R");
				CustomHandTransformLeft = GetViewModelTransformFromBoneName("hand.L");
				CustomHandTransformRight = GetViewModelTransformFromBoneName("hand.R");
				Transform transform = replacementViewModel.transform;
				transform.localScale *= num / num2;
				replacementViewModel.SetActive(true);
			}
		}

		protected virtual void UpdateViewModel()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			replacementViewModel.transform.SetPositionAndRotation(armsMetarig.position, armsMetarig.rotation);
			GetViewModelTransformFromBoneName("arm.L_upper").position = GetArmTransformFromBoneName("arm.L_upper").position;
			GetViewModelTransformFromBoneName("arm.R_upper").position = GetArmTransformFromBoneName("arm.R_upper").position;
			if (hasShoulder)
			{
				GetViewModelTransformFromBoneName("shoulder.L").position = GetArmTransformFromBoneName("shoulder.L").position;
				GetViewModelTransformFromBoneName("shoulder.R").position = GetArmTransformFromBoneName("shoulder.R").position;
			}
			foreach (string armTransformName in ArmTransformNames)
			{
				Transform armTransformFromBoneName = GetArmTransformFromBoneName(armTransformName);
				Transform viewModelTransformFromBoneName = GetViewModelTransformFromBoneName(armTransformName);
				if (Object.op_Implicit((Object)(object)armTransformFromBoneName) && Object.op_Implicit((Object)(object)viewModelTransformFromBoneName))
				{
					viewModelTransformFromBoneName.rotation = armTransformFromBoneName.rotation;
					RotationOffset component = ((Component)viewModelTransformFromBoneName).GetComponent<RotationOffset>();
					if (Object.op_Implicit((Object)(object)component))
					{
						viewModelTransformFromBoneName.rotation *= component.offset;
					}
				}
			}
		}

		public void Update()
		{
			if (!((Object)(object)replacementViewModel == (Object)null))
			{
				UpdateViewModel();
			}
		}

		public Transform GetViewModelTransformFromBoneName(string boneName)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			HumanBodyBones value;
			return modelToAvatarBone.TryGetValue(boneName, out value) ? viewModelAnimator.GetBoneTransform(value) : null;
		}

		public Transform GetArmTransformFromBoneName(string boneName)
		{
			return ((IEnumerable<Transform>)((Component)armsMetarig).gameObject.GetComponentsInChildren<Transform>()).FirstOrDefault((Func<Transform, bool>)((Transform x) => ((Object)x).name == boneName));
		}
	}
}
namespace ModelReplacement.Scripts.Enemies
{
	public class MaskedAvatarUpdater
	{
		protected SkinnedMeshRenderer enemyModelRenderer = null;

		protected Animator replacementAnimator = null;

		protected GameObject enemy = null;

		protected GameObject replacement = null;

		protected bool hasUpperChest = false;

		protected Vector3 rootPositionOffset = Vector3.zero;

		protected 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 virtual void AssignModelReplacement(GameObject enemy, GameObject replacement)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			MaskedPlayerEnemy component = enemy.GetComponent<MaskedPlayerEnemy>();
			enemyModelRenderer = component.rendererLOD0;
			this.enemy = enemy;
			replacementAnimator = replacement.GetComponentInChildren<Animator>();
			this.replacement = replacement;
			OffsetBuilder component2 = ((Component)replacementAnimator).gameObject.GetComponent<OffsetBuilder>();
			ItemHolderPositionOffset = component2.itemPositonOffset;
			ItemHolderRotationOffset = component2.itemRotationOffset;
			ItemHolder = component2.itemHolder.transform;
			rootPositionOffset = component2.rootPositionOffset;
			Transform boneTransform = replacementAnimator.GetBoneTransform((HumanBodyBones)54);
			hasUpperChest = (Object)(object)boneTransform != (Object)null;
		}

		protected virtual void UpdateModel()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			Transform[] bones = enemyModelRenderer.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;
					}
				}
			}
			Transform avatarTransformFromBoneName2 = GetAvatarTransformFromBoneName("spine");
			Transform playerTransformFromBoneName = GetPlayerTransformFromBoneName("spine");
			avatarTransformFromBoneName2.position = playerTransformFromBoneName.position + playerTransformFromBoneName.TransformVector(rootPositionOffset);
		}

		public void Update()
		{
			if (!((Object)(object)enemyModelRenderer == (Object)null) && !((Object)(object)replacementAnimator == (Object)null))
			{
				UpdateModel();
			}
		}

		public Transform GetAvatarTransformFromBoneName(string boneName)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (boneName == "spine.002")
			{
				return hasUpperChest ? replacementAnimator.GetBoneTransform((HumanBodyBones)8) : null;
			}
			if (boneName == "spine.003")
			{
				return hasUpperChest ? replacementAnimator.GetBoneTransform((HumanBodyBones)54) : replacementAnimator.GetBoneTransform((HumanBodyBones)8);
			}
			HumanBodyBones value;
			return modelToAvatarBone.TryGetValue(boneName, out value) ? replacementAnimator.GetBoneTransform(value) : null;
		}

		public Transform GetPlayerTransformFromBoneName(string boneName)
		{
			IEnumerable<Transform> source = enemyModelRenderer.bones.Where((Transform x) => ((Object)x).name == boneName);
			if (source.Any())
			{
				return source.First();
			}
			return null;
		}
	}
}
namespace ModelReplacement.Patches
{
	internal class CosmeticPatch
	{
		private static void Postfix()
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if (!ModelReplacementAPI.moreCompanyPresent)
			{
				return;
			}
			CosmeticApplication val = Object.FindObjectOfType<CosmeticApplication>();
			if (CosmeticRegistry.locallySelectedCosmetics.Count <= 0 || val.spawnedCosmetics.Count > 0)
			{
				return;
			}
			foreach (string locallySelectedCosmetic in CosmeticRegistry.locallySelectedCosmetics)
			{
				val.ApplyCosmetic(locallySelectedCosmetic, true);
			}
			foreach (CosmeticInstance spawnedCosmetic in val.spawnedCosmetics)
			{
				Transform transform = ((Component)spawnedCosmetic).transform;
				transform.localScale *= 0.38f;
				SetAllChildrenLayer(((Component)spawnedCosmetic).transform, ViewStateManager.modelLayer);
			}
		}

		private static void SetAllChildrenLayer(Transform transform, string layerName)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			int layer = LayerMask.NameToLayer(layerName);
			((Component)transform).gameObject.layer = layer;
			foreach (object item in transform)
			{
				SetAllChildrenLayer((Transform)item, layerName);
			}
		}

		private static void SetAllChildrenLayer(Transform transform, int layer)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			((Component)transform).gameObject.layer = layer;
			foreach (object item in transform)
			{
				SetAllChildrenLayer((Transform)item, layer);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyAI))]
	public class EnemyAIPatch
	{
		[HarmonyPatch("HitEnemy")]
		[HarmonyPrefix]
		[HarmonyAfter(new string[] { })]
		public static void HitEnemy(ref EnemyAI __instance, int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false)
		{
			if (!((Object)(object)playerWhoHit == (Object)null))
			{
				BodyReplacementBase component = ((Component)playerWhoHit).gameObject.GetComponent<BodyReplacementBase>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.OnHitEnemy(__instance.isEnemyDead);
				}
			}
		}
	}
	[HarmonyPatch(typeof(GrabbableObject))]
	public class LocateHeldObjectsOnModelReplacementPatch
	{
		[HarmonyPatch("LateUpdate")]
		[HarmonyPostfix]
		public static void LateUpdatePatch(ref GrabbableObject __instance)
		{
			if (!((Object)(object)__instance.parentObject == (Object)null) && !((Object)(object)__instance.playerHeldBy == (Object)null) && !((Object)(object)__instance.playerHeldBy.ItemSlots[__instance.playerHeldBy.currentItemSlot] != (Object)(object)__instance))
			{
				BodyReplacementBase component = ((Component)__instance.playerHeldBy).gameObject.GetComponent<BodyReplacementBase>();
				if (Object.op_Implicit((Object)(object)component) && (Object)(object)component.heldItem != (Object)(object)__instance)
				{
					component.heldItem = __instance;
				}
			}
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy))]
	public class MaskedPlayerEnemyPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void ManageRegistryBodyReplacements(ref EnemyAI __instance)
		{
			try
			{
				((Component)__instance).gameObject.AddComponent<MaskedReplacementBase>();
			}
			catch (Exception arg)
			{
				ModelReplacementAPI.Instance.Logger.LogError((object)$"Exception in Masked ManageRegistryBodyReplacements: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	public class PlayerControllerBPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		public static void StartPatch(ref PlayerControllerB __instance)
		{
			((Component)__instance).gameObject.AddComponent<ViewStateManager>();
			((Component)__instance).gameObject.AddComponent<MoreCompanyCosmeticManager>();
			((Component)((Component)__instance).gameObject.transform.Find("ScavengerModel")).GetComponent<LODGroup>().enabled = false;
		}

		[HarmonyPatch("DamagePlayerFromOtherClientClientRpc")]
		[HarmonyPostfix]
		public static void DamagePlayerFromOtherClientClientRpc(ref PlayerControllerB __instance, int damageAmount, Vector3 hitDirection, int playerWhoHit, int newHealthAmount)
		{
			PlayerControllerB val = __instance.playersManager.allPlayerScripts[playerWhoHit];
			if (Object.op_Implicit((Object)(object)val))
			{
				BodyReplacementBase component = ((Component)val).gameObject.GetComponent<BodyReplacementBase>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.OnHitAlly(__instance, __instance.isPlayerDead);
				}
			}
		}

		[HarmonyPatch("DamagePlayerClientRpc")]
		[HarmonyPostfix]
		public static void DamagePlayerClientRpc(ref PlayerControllerB __instance, int damageNumber, int newHealthAmount)
		{
			if (Object.op_Implicit((Object)(object)__instance))
			{
				BodyReplacementBase component = ((Component)__instance).gameObject.GetComponent<BodyReplacementBase>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.OnDamageTaken(__instance.isPlayerDead);
				}
			}
		}

		[HarmonyPatch("SetHoverTipAndCurrentInteractTrigger")]
		[HarmonyPostfix]
		public static void SetHoverTipAndCurrentInteractTriggerPatch(ref PlayerControllerB __instance)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (!__instance.isGrabbingObjectAnimation && !__instance.isFreeCamera && Physics.Raycast(__instance.interactRay, ref val, 5f, 8388608))
			{
				BodyReplacementBase.RaycastTarget component = ((Component)((RaycastHit)(ref val)).collider).gameObject.GetComponent<BodyReplacementBase.RaycastTarget>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.controller.ShowNameBillboard();
				}
			}
		}

		[HarmonyPatch("SpawnDeadBody")]
		[HarmonyPostfix]
		public static void SpawnDeadBody(int playerId, Vector3 bodyVelocity, int causeOfDeath, PlayerControllerB deadPlayerController, int deathAnimation = 0, Transform overridePosition = null, Vector3 positionOffset = default(Vector3))
		{
			try
			{
				if (!((Object)(object)deadPlayerController == (Object)null))
				{
					SkinnedMeshRenderer[] componentsInChildren = ((Component)deadPlayerController.deadBody).gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
					((Component)deadPlayerController.deadBody).gameObject.layer = ViewStateManager.ragdollLayer;
					SkinnedMeshRenderer[] array = componentsInChildren;
					foreach (SkinnedMeshRenderer val in array)
					{
					}
				}
			}
			catch (NullReferenceException ex)
			{
				Debug.LogError((object)ex);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")]
	internal class PlayerPatch
	{
		[HarmonyAfter(new string[] { "quackandcheese.mirrordecor" })]
		private static void Postfix(ref PlayerControllerB __instance)
		{
			if ((Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				GameObject.Find("Systems/Rendering/PlayerHUDHelmetModel/").GetComponentInChildren<Renderer>().shadowCastingMode = (ShadowCastingMode)0;
				PlayerControllerB val = __instance;
				((Renderer)val.thisPlayerModel).shadowCastingMode = (ShadowCastingMode)1;
				((Component)val.thisPlayerModel).gameObject.layer = ViewStateManager.modelLayer;
				((Component)val.thisPlayerModelLOD1).gameObject.layer = ViewStateManager.visibleLayer;
				((Component)val.thisPlayerModelLOD2).gameObject.layer = ViewStateManager.visibleLayer;
				((Component)val.thisPlayerModelArms).gameObject.layer = ViewStateManager.armsLayer;
				val.gameplayCamera.cullingMask = ViewStateManager.CullingMaskFirstPerson;
			}
		}
	}
}
namespace ModelReplacement.Monobehaviors
{
	public abstract class ManagerBase : MonoBehaviour
	{
		protected bool bodyReplacementExists = false;

		protected BodyReplacementBase bodyReplacement;

		protected PlayerControllerB controller;

		protected GameObject replacementModel;

		protected GameObject replacementViewModel;

		public bool localPlayer => (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)controller;

		protected virtual void Awake()
		{
			controller = ((Component)this).GetComponent<PlayerControllerB>();
		}

		protected virtual void Update()
		{
			if (bodyReplacementExists && (Object)(object)bodyReplacement == (Object)null)
			{
				ReportBodyReplacementRemoval();
			}
			if (bodyReplacementExists)
			{
				UpdateModelReplacement();
			}
			else
			{
				UpdatePlayer();
			}
		}

		public virtual void ReportBodyReplacementAddition(BodyReplacementBase replacement)
		{
			bodyReplacement = replacement;
			replacementModel = replacement.replacementModel;
			replacementViewModel = replacement.replacementViewModel;
			bodyReplacementExists = true;
		}

		public virtual void ReportBodyReplacementRemoval()
		{
			bodyReplacement = null;
			replacementModel = null;
			replacementViewModel = null;
			bodyReplacementExists = false;
		}

		public abstract void UpdatePlayer();

		public abstract void UpdateModelReplacement();
	}
	public class MoreCompanyCosmeticManager : ManagerBase
	{
		internal class CosmeticInstance2
		{
			public Transform modelParent = null;

			public GameObject cosmetic = null;

			public Vector3 positionOffset = Vector3.zero;

			public Quaternion rotationOffset = Quaternion.identity;

			public bool DoRender = false;
		}

		public enum CosmeticType2
		{
			HAT,
			WRIST,
			CHEST,
			R_LOWER_ARM,
			HIP,
			L_SHIN,
			R_SHIN
		}

		private string lastException = "";

		private bool wasUsingAvatarTransforms = false;

		private Dictionary<CosmeticType2, Transform> cosmeticTransformPairs = new Dictionary<CosmeticType2, Transform>();

		private List<CosmeticInstance2> cosmeticInstances = new List<CosmeticInstance2>();

		private AvatarUpdater cosmeticAvatar => bodyReplacement.cosmeticAvatar;

		protected override void Update()
		{
			if (bodyReplacementExists && (Object)(object)bodyReplacement == (Object)null)
			{
				ReportBodyReplacementRemoval();
			}
			if (!bodyReplacementExists)
			{
				UpdatePlayer();
			}
		}

		public override void UpdatePlayer()
		{
			if (ModelReplacementAPI.moreCompanyPresent)
			{
				SafeRenderCosmetics(useAvatarTransforms: false);
			}
		}

		public override void UpdateModelReplacement()
		{
			if (ModelReplacementAPI.moreCompanyPresent)
			{
				SafeRenderCosmetics(useAvatarTransforms: true);
			}
		}

		public override void ReportBodyReplacementAddition(BodyReplacementBase replacement)
		{
			base.ReportBodyReplacementAddition(replacement);
			cosmeticTransformPairs.Clear();
			cosmeticInstances.Clear();
		}

		public override void ReportBodyReplacementRemoval()
		{
			base.ReportBodyReplacementRemoval();
			cosmeticTransformPairs.Clear();
			cosmeticInstances.Clear();
		}

		private void SafeRenderCosmetics(bool useAvatarTransforms)
		{
			try
			{
				DangerousRenderCosmetics(useAvatarTransforms);
			}
			catch (Exception ex)
			{
				lastException = ex.Message;
			}
		}

		private void RefreshCosmetics()
		{
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			if (cosmeticTransformPairs.Count == 0)
			{
				cosmeticTransformPairs.Add(CosmeticType2.HAT, cosmeticAvatar.GetAvatarTransformFromBoneName("spine.004"));
				cosmeticTransformPairs.Add(CosmeticType2.CHEST, cosmeticAvatar.GetAvatarTransformFromBoneName("spine.003"));
				cosmeticTransformPairs.Add(CosmeticType2.R_LOWER_ARM, cosmeticAvatar.GetAvatarTransformFromBoneName("arm.R_lower"));
				cosmeticTransformPairs.Add(CosmeticType2.HIP, cosmeticAvatar.GetAvatarTransformFromBoneName("spine"));
				cosmeticTransformPairs.Add(CosmeticType2.L_SHIN, cosmeticAvatar.GetAvatarTransformFromBoneName("shin.L"));
				cosmeticTransformPairs.Add(CosmeticType2.R_SHIN, cosmeticAvatar.GetAvatarTransformFromBoneName("shin.R"));
			}
			if (cosmeticInstances.Count != 0)
			{
				return;
			}
			CosmeticApplication[] componentsInChildren = ((Component)controller).gameObject.GetComponentsInChildren<CosmeticApplication>();
			CosmeticApplication[] array = componentsInChildren;
			foreach (CosmeticApplication val in array)
			{
				if (val.spawnedCosmetics.Count == 0)
				{
					continue;
				}
				foreach (CosmeticInstance spawnedCosmetic in val.spawnedCosmetics)
				{
					Transform cosmeticTransform = GetCosmeticTransform(spawnedCosmetic.cosmeticType);
					CosmeticInstance2 cosmeticInstance = new CosmeticInstance2();
					cosmeticInstance.modelParent = cosmeticTransform;
					cosmeticInstance.cosmetic = ((Component)spawnedCosmetic).gameObject;
					cosmeticInstance.DoRender = false;
					if (Object.op_Implicit((Object)(object)cosmeticTransform))
					{
						RotationOffset component = ((Component)cosmeticTransform).GetComponent<RotationOffset>();
						if (Object.op_Implicit((Object)(object)component))
						{
							cosmeticInstance.DoRender = component.RenderMCC;
							cosmeticInstance.p