Decompiled source of Updatedprotogen v1.1.14

Updatedprotogen.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CompanyIssuedProtogen.Patches;
using CompanyIssuedProtogen.Protogen;
using CompanyIssuedProtogen.Tools;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RuntimeNetcodeRPCValidator;
using Steamworks;
using Steamworks.Data;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("Updatedprotogen")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A ScottyFoxArt Lethal Company Mod : Company Issued Protogen! ")]
[assembly: AssemblyFileVersion("1.1.10.0")]
[assembly: AssemblyInformationalVersion("1.1.10")]
[assembly: AssemblyProduct("Updatedprotogen")]
[assembly: AssemblyTitle("Updatedprotogen")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.10.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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;
		}
	}
}
public class WigglyBones : MonoBehaviour
{
	public float damping = 12f;

	private List<Transform> bones = new List<Transform>();

	private List<Quaternion> relativeRotations = new List<Quaternion>();

	private List<Quaternion> oldRotations = new List<Quaternion>();

	private void Start()
	{
		InitializeBones();
	}

	private void InitializeBones()
	{
		TraverseHierarchy(((Component)this).transform);
	}

	private void TraverseHierarchy(Transform root)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Expected O, but got Unknown
		Stack<Transform> stack = new Stack<Transform>();
		stack.Push(root);
		while (stack.Count > 0)
		{
			Transform val = stack.Pop();
			if ((Object)(object)val != (Object)(object)((Component)this).transform)
			{
				bones.Add(val);
				relativeRotations.Add(Quaternion.Inverse(val.parent.rotation) * val.rotation);
				oldRotations.Add(val.rotation);
			}
			foreach (Transform item2 in val)
			{
				Transform item = item2;
				stack.Push(item);
			}
		}
	}

	private void Update()
	{
		ApplyJiggleEffect();
	}

	private void ApplyJiggleEffect()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < bones.Count; i++)
		{
			Quaternion val = bones[i].parent.rotation * relativeRotations[i];
			bones[i].rotation = Quaternion.Slerp(oldRotations[i], val, damping * Time.deltaTime);
			oldRotations[i] = bones[i].rotation;
		}
	}
}
namespace CompanyIssuedProtogen
{
	internal class BoneMimicHandler : MonoBehaviour
	{
		private struct BonePair
		{
			public Transform original;

			public Transform target;

			public bool rotation;

			public bool position;

			public Vector3 offset;

			public Vector3 rotation_offset;

			public BonePair(Transform original, Transform target, bool rotation = false, bool position = false)
			{
				//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_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				this.original = target;
				this.target = target;
				this.rotation = rotation;
				this.position = position;
				offset = Vector3.zero;
				rotation_offset = Vector3.zero;
			}
		}

		private List<BonePair> bonePairs = new List<BonePair>();

		private Dictionary<string, Transform> original_reference;

		private Dictionary<string, Transform> target_reference;

		public void ClearReferences()
		{
			original_reference.Clear();
			target_reference.Clear();
		}

		public void BuildOriginalReference(Transform target)
		{
			original_reference = BuildReference(target);
		}

		public void BuildTargetReference(Transform target)
		{
			target_reference = BuildReference(target);
		}

		private Dictionary<string, Transform> BuildReference(Transform target)
		{
			Dictionary<string, Transform> dictionary = new Dictionary<string, Transform>();
			Transform[] componentsInChildren = ((Component)target).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (!dictionary.ContainsKey(((Object)val).name))
				{
					dictionary.Add(((Object)val).name, val);
				}
			}
			return dictionary;
		}

		public void ResetBonePairs()
		{
			bonePairs.Clear();
		}

		public Transform GetOriginalBone(string name)
		{
			Transform value = null;
			if (original_reference != null)
			{
				original_reference.TryGetValue(name, out value);
			}
			return value;
		}

		public Transform GetTargetBone(string name)
		{
			Transform value = null;
			if (target_reference != null)
			{
				target_reference.TryGetValue(name, out value);
			}
			return value;
		}

		public void PairBones(string original, string target, bool rotation = true, bool position = true)
		{
			if (rotation || position)
			{
				PairBones(GetOriginalBone(original), GetTargetBone(target), rotation, position);
			}
		}

		public void PairBones(string original, string target, Vector3 offset, Vector3 rotation_offset, bool rotation = true, bool position = true)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (rotation || position)
			{
				PairBones(GetOriginalBone(original), GetTargetBone(target), offset, rotation_offset, rotation, position);
			}
		}

		public void PairBones(Transform original, string target, bool rotation = true, bool position = true)
		{
			if (rotation || position)
			{
				PairBones(original, GetTargetBone(target), rotation, position);
			}
		}

		public void PairBones(Transform original, string target, Vector3 offset, Vector3 rotation_offset, bool rotation = true, bool position = true)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (rotation || position)
			{
				PairBones(original, GetTargetBone(target), offset, rotation_offset, rotation, position);
			}
		}

		public void PairBones(string original, Transform target, bool rotation = true, bool position = true)
		{
			if (rotation || position)
			{
				PairBones(GetOriginalBone(original), target, rotation, position);
			}
		}

		public void PairBones(string original, Transform target, Vector3 offset, Vector3 rotation_offset, bool rotation = true, bool position = true)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (rotation || position)
			{
				PairBones(GetOriginalBone(original), target, offset, rotation_offset, rotation, position);
			}
		}

		public void PairBones(Transform original, Transform target, bool rotation = true, bool position = true)
		{
			if (Object.op_Implicit((Object)(object)original) && Object.op_Implicit((Object)(object)target) && (rotation || position))
			{
				bonePairs.Add(SetUpBonePair(original, target, rotation, position));
			}
		}

		public void PairBones(Transform original, Transform target, Vector3 offset, Vector3 rotation_offset, bool rotation = true, bool position = true)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)original) && Object.op_Implicit((Object)(object)target) && (rotation || position))
			{
				bonePairs.Add(SetUpBonePair(original, target, offset, rotation_offset, rotation, position));
			}
		}

		private BonePair SetUpBonePair(Transform original, Transform target, bool rotation = true, bool position = true)
		{
			return new BonePair
			{
				original = original,
				target = target,
				rotation = rotation,
				position = position
			};
		}

		private BonePair SetUpBonePair(Transform original, Transform target, Vector3 offset, Vector3 rotation_offset, bool rotation = true, bool position = true)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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)
			BonePair result = new BonePair
			{
				original = original,
				target = target,
				rotation = rotation,
				position = position
			};
			if (rotation)
			{
				result.rotation_offset = rotation_offset;
			}
			if (position)
			{
				result.offset = offset;
			}
			return result;
		}

		private void SyncBones()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			foreach (BonePair bonePair in bonePairs)
			{
				if (Object.op_Implicit((Object)(object)bonePair.original) && Object.op_Implicit((Object)(object)bonePair.target))
				{
					if (bonePair.rotation)
					{
						bonePair.original.eulerAngles = bonePair.target.eulerAngles + bonePair.rotation_offset;
					}
					if (bonePair.position)
					{
						bonePair.original.position = bonePair.target.position + bonePair.offset;
					}
				}
			}
		}

		private void LateUpdate()
		{
			SyncBones();
		}
	}
	[BepInPlugin("Updatedprotogen", "Updatedprotogen", "1.1.10")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private static bool keyWasHeld;

		public static ConfigEntry<KeyboardShortcut> Toggle;

		public static ManualLogSource Logger;

		private void Awake()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			try
			{
				Logger.LogInfo((object)"Plugin Updatedprotogen");
				Logger.LogInfo((object)"Dressing Up Protogens");
				if (ProtogenPrefabs.Init())
				{
					Logger.LogInfo((object)"Teaching Protogens Emotions");
					ProtogenExpressions.BuildExpressions();
					Logger.LogInfo((object)"Spray Painting Protogens");
					Logger.LogInfo((object)"Patching Protogens In.");
					new Harmony("SFXArt.CompanyIssuedProtoGen").PatchAll(Assembly.GetExecutingAssembly());
					NetcodeValidator val = new NetcodeValidator("Updatedprotogen");
					val.PatchAll();
					val.BindToPreExistingObjectByBehaviour<ProtogenSync, PlayerControllerB>();
					Toggle = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Toggle", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), "Key to turn your protogen on or off. Unbound until you set one here. Ignored in the terminal, chat, and menus. Other players see the same choice.");
					Logger.LogInfo((object)"Protogen starts off. Set General.Toggle in the config to bind a key.");
					Logger.LogInfo((object)"Plugin Updatedprotogen is loaded!");
				}
				else
				{
					Logger.LogError((object)"Could not load assets...!");
				}
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Plugin Updatedprotogen failed to load: " + ex));
			}
		}

		private void Update()
		{
			PollToggle();
		}

		internal static void PollToggle()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (Toggle != null)
			{
				KeyboardShortcut value = Toggle.Value;
				if ((int)((KeyboardShortcut)(ref value)).MainKey != 0)
				{
					if (!Object.op_Implicit((Object)(object)GameNetworkManager.Instance) || !Object.op_Implicit((Object)(object)GameNetworkManager.Instance.localPlayerController))
					{
						return;
					}
					PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
					if (!WasPressed(Toggle.Value, localPlayerController))
					{
						return;
					}
					ProtogenSync component = ((Component)localPlayerController).GetComponent<ProtogenSync>();
					if (!Object.op_Implicit((Object)(object)component))
					{
						Logger.LogWarning((object)"Protogen toggle is not on the player yet.");
						return;
					}
					bool flag = (component.Enabled = !component.Enabled);
					ProtogenManager.Apply(localPlayerController, flag);
					Logger.LogInfo((object)(flag ? "Protogen on." : "Protogen off."));
					if (((NetworkBehaviour)component).IsSpawned)
					{
						try
						{
							component.SetEnabledServerRpc(flag);
						}
						catch (Exception ex)
						{
							Logger.LogWarning((object)("Could not sync the protogen toggle: " + ex.Message));
						}
					}
					if (Object.op_Implicit((Object)(object)HUDManager.Instance))
					{
						HUDManager.Instance.DisplayTip("Protogen", flag ? "On" : "Off", false, false, "CIPToggle");
					}
					return;
				}
			}
			keyWasHeld = false;
		}

		private static bool WasPressed(KeyboardShortcut shortcut, PlayerControllerB player)
		{
			bool flag = ((KeyboardShortcut)(ref shortcut)).IsPressed();
			bool result = flag && !keyWasHeld && !IsUsingTextInterface(player);
			keyWasHeld = flag;
			return result;
		}

		private static bool IsUsingTextInterface(PlayerControllerB player)
		{
			if (player.isTypingChat || player.inTerminalMenu || player.inSpecialMenu)
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)player.quickMenuManager))
			{
				return player.quickMenuManager.isMenuOpen;
			}
			return false;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "Updatedprotogen";

		public const string PLUGIN_NAME = "Updatedprotogen";

		public const string PLUGIN_VERSION = "1.1.10";
	}
	internal class SimpleIKHandler : MonoBehaviour
	{
		private Transform lefthand;

		private Transform righthand;

		private Transform leftfoot;

		private Transform rightfoot;

		private Animator animator;

		private void Start()
		{
			animator = ((Component)this).GetComponent<Animator>();
		}

		public void SetLeftHand(Transform target)
		{
			lefthand = target;
		}

		public void SetRightHand(Transform target)
		{
			righthand = target;
		}

		public void SetLeftFoot(Transform target)
		{
			leftfoot = target;
		}

		public void SetRightFoot(Transform target)
		{
			rightfoot = target;
		}

		private void OnAnimatorIK(int layerIndex)
		{
			//IL_004a: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)animator))
			{
				if (Object.op_Implicit((Object)(object)leftfoot))
				{
					animator.SetIKPositionWeight((AvatarIKGoal)0, 1f);
					animator.SetIKRotationWeight((AvatarIKGoal)0, 1f);
					animator.SetIKPosition((AvatarIKGoal)0, leftfoot.position);
					animator.SetIKRotation((AvatarIKGoal)0, leftfoot.rotation);
				}
				if (Object.op_Implicit((Object)(object)rightfoot))
				{
					animator.SetIKPositionWeight((AvatarIKGoal)1, 1f);
					animator.SetIKRotationWeight((AvatarIKGoal)1, 1f);
					animator.SetIKPosition((AvatarIKGoal)1, rightfoot.position);
					animator.SetIKRotation((AvatarIKGoal)1, rightfoot.rotation);
				}
				if (Object.op_Implicit((Object)(object)lefthand))
				{
					animator.SetIKPositionWeight((AvatarIKGoal)2, 1f);
					animator.SetIKRotationWeight((AvatarIKGoal)2, 1f);
					animator.SetIKPosition((AvatarIKGoal)2, lefthand.position);
					animator.SetIKRotation((AvatarIKGoal)2, lefthand.rotation);
				}
				if (Object.op_Implicit((Object)(object)righthand))
				{
					animator.SetIKPositionWeight((AvatarIKGoal)3, 1f);
					animator.SetIKRotationWeight((AvatarIKGoal)3, 1f);
					animator.SetIKPosition((AvatarIKGoal)3, righthand.position);
					animator.SetIKRotation((AvatarIKGoal)3, righthand.rotation);
				}
			}
		}
	}
	public static class TextureTools
	{
		public static void DominantColors(Texture2D texture, out bool isDark, out Color mainColor, out Color secondaryColor)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: 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_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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_00b5: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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)
			Color[] pixels = texture.GetPixels();
			Dictionary<Color, int> dictionary = new Dictionary<Color, int>();
			Color val = Color.white;
			int num = 0;
			Color val2 = Color.black;
			float num2 = 0f;
			Color val3 = Color.black;
			Color[] array = pixels;
			float num3 = default(float);
			float num4 = default(float);
			float num5 = default(float);
			foreach (Color val4 in array)
			{
				if (dictionary.ContainsKey(val4))
				{
					dictionary[val4]++;
				}
				else
				{
					dictionary.Add(val4, 1);
				}
				if (dictionary[val4] > num)
				{
					num = dictionary[val4];
					val = val4;
				}
				Color.RGBToHSV(val4, ref num3, ref num4, ref num5);
				if ((double)num5 > 0.5 || val2 == Color.black)
				{
					if (num4 == num2)
					{
						val2 = Color.Lerp(val2, val4, 0.5f);
					}
					else if (num4 > num2)
					{
						val2 = val4;
						num2 = num4;
					}
				}
				val3 += val4;
			}
			val3 /= (float)pixels.Length;
			float num6 = default(float);
			float num7 = default(float);
			Color.RGBToHSV(val, ref num3, ref num6, ref num7);
			isDark = (double)num7 < 0.5;
			float num8 = default(float);
			float num9 = default(float);
			float num10 = default(float);
			Color.RGBToHSV(val3, ref num8, ref num9, ref num10);
			float num11 = default(float);
			float num12 = default(float);
			Color.RGBToHSV(val2, ref num6, ref num11, ref num12);
			mainColor = val;
			secondaryColor = Color.HSVToRGB(num8, Mathf.Lerp(num9, num11, 0.5f), Mathf.Lerp(num10, num12, 0.5f));
			if (mainColor == secondaryColor)
			{
				if (isDark)
				{
					secondaryColor = Color.white;
				}
				else
				{
					secondaryColor = Color.black;
				}
			}
		}

		public static Color[] FlatColor(int width, int height, Color color)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = color;
			}
			return array;
		}
	}
}
namespace CompanyIssuedProtogen.Tools
{
	internal class AssetHelper
	{
		private AssetBundle assetbundle;

		private Dictionary<string, Object> assets = new Dictionary<string, Object>();

		public void LoadAssetsStripped(string path, string prefix)
		{
			assetbundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), path));
			string[] allAssetNames = assetbundle.GetAllAssetNames();
			foreach (string text in allAssetNames)
			{
				if (text.StartsWith(prefix))
				{
					string text2 = text.Remove(0, prefix.Length);
					if (!assets.ContainsKey(text2))
					{
						assets.Add(text2, assetbundle.LoadAsset(text));
					}
					else
					{
						Debug.LogWarning((object)("StrippedAsset : " + text2 + " :  Already Exists."));
					}
				}
			}
			assetbundle.Unload(false);
		}

		public T Get<T>(string name) where T : Object
		{
			if (!assets.TryGetValue(name, out var value))
			{
				return default(T);
			}
			return (T)(object)value;
		}

		public bool Has<T>(string name, out T asset) where T : Object
		{
			asset = (assets.TryGetValue(name, out var value) ? ((T)(object)value) : default(T));
			return (Object)(object)asset != (Object)null;
		}
	}
	public static class PixelKit
	{
		public static void HSV(ref Color original, float H, float S, float V)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			original = Color.HSVToRGB(H, S, V);
		}

		public static void HV(ref Color original, float H, float V)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(original, ref num, ref num2, ref num3);
			original = Color.HSVToRGB(H, num2, V);
		}

		public static void HS(ref Color original, float H, float S)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(original, ref num, ref num2, ref num3);
			original = Color.HSVToRGB(H, S, num3);
		}

		public static void SV(ref Color original, float S, float V)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(original, ref num, ref num2, ref num3);
			original = Color.HSVToRGB(num, S, V);
		}

		public static void Hue(ref Color original, float amount)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(original, ref num, ref num2, ref num3);
			original = Color.HSVToRGB(amount, num2, num3);
		}

		public static void Saturate(ref Color original, float amount)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(original, ref num, ref num2, ref num3);
			original = Color.HSVToRGB(num, amount, num3);
		}

		public static void Value(ref Color original, float amount)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(original, ref num, ref num2, ref num3);
			original = Color.HSVToRGB(num, num2, amount);
		}

		public static void Multiply(ref Color original, Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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)
			original *= color;
		}

		public static void Invert(ref Color original)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			original -= Color.white;
		}

		public static Color Lerp_Mask(Color original, Color reference, Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return Color.Lerp(original, color, 1f - reference.r);
		}

		public static Color Lerp_Alpha(Color original, Color reference)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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)
			return Color.Lerp(original, reference, reference.a);
		}
	}
}
namespace CompanyIssuedProtogen.Protogen
{
	public enum FacialExpression
	{
		None,
		Default,
		Dance,
		Point,
		Paranoid,
		Crash
	}
	internal static class ProtogenArms
	{
		private const string MeshFile = "protoarms.bin";

		private static readonly string[] BoneNames = new string[30]
		{
			"Armature", "Hips", "Spine", "Chest", "Neck", "Head", "shoulder.L", "upper_arm.L", "forearm.L", "hand.L",
			"Index01.L", "Middle01.L", "Middle01.L.001", "Thumb01.L", "shoulder.R", "upper_arm.R", "forearm.R", "hand.R", "Index01.R", "Middle01.R",
			"Middle01.R.001", "Thumb01.R", "thigh.L", "shin.L", "foot.L", "toe.L", "thigh.R", "shin.R", "foot.R", "toe.R"
		};

		private static Mesh sharedMesh;

		public static bool Ready => Object.op_Implicit((Object)(object)sharedMesh);

		public static SkinnedMeshRenderer CreateView(SkinnedMeshRenderer source)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)source) || source.bones == null || source.bones.Length == 0)
			{
				return null;
			}
			Mesh orCreateMesh = GetOrCreateMesh();
			if (!Object.op_Implicit((Object)(object)orCreateMesh))
			{
				return null;
			}
			if (orCreateMesh.bindposes.Length != source.bones.Length)
			{
				Plugin.Logger.LogWarning((object)"Protogen arm mesh does not match this body, so first person hands stay the employee mesh.");
				return null;
			}
			GameObject val = new GameObject("ProtoFirstPersonArmRig");
			val.transform.SetParent(((Component)source).transform.parent, false);
			Transform[] array = (Transform[])(object)new Transform[orCreateMesh.bindposes.Length];
			for (int i = 0; i < array.Length; i++)
			{
				GameObject val2 = new GameObject((i < BoneNames.Length) ? BoneNames[i] : ("bone" + i));
				val2.transform.SetParent(val.transform, false);
				array[i] = val2.transform;
			}
			GameObject val3 = new GameObject("ProtoFirstPersonArms");
			val3.transform.SetParent(val.transform, false);
			val3.layer = ((Component)source).gameObject.layer;
			SkinnedMeshRenderer obj = val3.AddComponent<SkinnedMeshRenderer>();
			obj.sharedMesh = orCreateMesh;
			obj.bones = array;
			obj.rootBone = val.transform;
			((Renderer)obj).sharedMaterials = ((Renderer)source).sharedMaterials;
			obj.updateWhenOffscreen = true;
			((Renderer)obj).enabled = false;
			val3.AddComponent<ProtogenArmDriver>().viewBones = array;
			return obj;
		}

		public static void FollowViewmodel(Renderer armsRenderer, SkinnedMeshRenderer viewmodel)
		{
			if (Object.op_Implicit((Object)(object)armsRenderer) && Object.op_Implicit((Object)(object)viewmodel))
			{
				ProtogenArmDriver component = ((Component)armsRenderer).GetComponent<ProtogenArmDriver>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.Follow(viewmodel);
				}
			}
		}

		private static Mesh GetOrCreateMesh()
		{
			if (Object.op_Implicit((Object)(object)sharedMesh))
			{
				return sharedMesh;
			}
			string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "protoarms.bin");
			if (!File.Exists(path))
			{
				Plugin.Logger.LogWarning((object)"Missing protoarms.bin, so first person hands stay the employee mesh.");
				return null;
			}
			sharedMesh = ReadMesh(path);
			if (Object.op_Implicit((Object)(object)sharedMesh))
			{
				Plugin.Logger.LogInfo((object)("First person arms are using the edited protogen mesh (" + sharedMesh.vertexCount + " vertices)."));
			}
			return sharedMesh;
		}

		private static Mesh ReadMesh(string path)
		{
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			using FileStream input = File.OpenRead(path);
			using BinaryReader binaryReader = new BinaryReader(input);
			if (binaryReader.ReadUInt32() != 1297236304)
			{
				Plugin.Logger.LogWarning((object)"protoarms.bin is not an arm mesh.");
				return null;
			}
			if (binaryReader.ReadInt32() != 1)
			{
				Plugin.Logger.LogWarning((object)"protoarms.bin is an unsupported version.");
				return null;
			}
			int count = binaryReader.ReadInt32();
			int num = binaryReader.ReadInt32();
			int count2 = binaryReader.ReadInt32();
			Vector3[] vertices = ReadVectors(binaryReader, count);
			Vector3[] normals = ReadVectors(binaryReader, count);
			Vector4[] tangents = ReadTangents(binaryReader, count);
			Vector2[] uv = ReadUvs(binaryReader, count);
			BoneWeight[] boneWeights = ReadWeights(binaryReader, count);
			Matrix4x4[] bindposes = ReadBindposes(binaryReader, count2);
			int[][] array = new int[num][];
			for (int i = 0; i < num; i++)
			{
				int num2 = binaryReader.ReadInt32();
				int[] array2 = new int[num2];
				for (int j = 0; j < num2; j++)
				{
					array2[j] = binaryReader.ReadInt32();
				}
				array[i] = array2;
			}
			Mesh val = new Mesh();
			((Object)val).name = "ProtoFirstPersonArms";
			val.vertices = vertices;
			val.normals = normals;
			val.tangents = tangents;
			val.uv = uv;
			val.boneWeights = boneWeights;
			val.bindposes = bindposes;
			val.subMeshCount = num;
			for (int k = 0; k < num; k++)
			{
				val.SetTriangles(array[k], k);
			}
			val.RecalculateBounds();
			return val;
		}

		private static Vector3[] ReadVectors(BinaryReader reader, int count)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[count];
			for (int i = 0; i < count; i++)
			{
				array[i] = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
			}
			return array;
		}

		private static Vector4[] ReadTangents(BinaryReader reader, int count)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Vector4[] array = (Vector4[])(object)new Vector4[count];
			for (int i = 0; i < count; i++)
			{
				array[i] = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
			}
			return array;
		}

		private static Vector2[] ReadUvs(BinaryReader reader, int count)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Vector2[] array = (Vector2[])(object)new Vector2[count];
			for (int i = 0; i < count; i++)
			{
				array[i] = new Vector2(reader.ReadSingle(), reader.ReadSingle());
			}
			return array;
		}

		private static BoneWeight[] ReadWeights(BinaryReader reader, int count)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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)
			int[] array = new int[count];
			int[] array2 = new int[count];
			int[] array3 = new int[count];
			int[] array4 = new int[count];
			for (int i = 0; i < count; i++)
			{
				array[i] = reader.ReadUInt16();
				array2[i] = reader.ReadUInt16();
				array3[i] = reader.ReadUInt16();
				array4[i] = reader.ReadUInt16();
			}
			BoneWeight[] array5 = (BoneWeight[])(object)new BoneWeight[count];
			for (int j = 0; j < count; j++)
			{
				BoneWeight val = default(BoneWeight);
				((BoneWeight)(ref val)).boneIndex0 = array[j];
				((BoneWeight)(ref val)).boneIndex1 = array2[j];
				((BoneWeight)(ref val)).boneIndex2 = array3[j];
				((BoneWeight)(ref val)).boneIndex3 = array4[j];
				((BoneWeight)(ref val)).weight0 = reader.ReadSingle();
				((BoneWeight)(ref val)).weight1 = reader.ReadSingle();
				((BoneWeight)(ref val)).weight2 = reader.ReadSingle();
				((BoneWeight)(ref val)).weight3 = reader.ReadSingle();
				array5[j] = val;
			}
			return array5;
		}

		private static Matrix4x4[] ReadBindposes(BinaryReader reader, int count)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			Matrix4x4[] array = (Matrix4x4[])(object)new Matrix4x4[count];
			for (int i = 0; i < count; i++)
			{
				array[i] = new Matrix4x4
				{
					m00 = reader.ReadSingle(),
					m01 = reader.ReadSingle(),
					m02 = reader.ReadSingle(),
					m03 = reader.ReadSingle(),
					m10 = reader.ReadSingle(),
					m11 = reader.ReadSingle(),
					m12 = reader.ReadSingle(),
					m13 = reader.ReadSingle(),
					m20 = reader.ReadSingle(),
					m21 = reader.ReadSingle(),
					m22 = reader.ReadSingle(),
					m23 = reader.ReadSingle(),
					m30 = reader.ReadSingle(),
					m31 = reader.ReadSingle(),
					m32 = reader.ReadSingle(),
					m33 = reader.ReadSingle()
				};
			}
			return array;
		}
	}
	[DefaultExecutionOrder(20000)]
	internal class ProtogenArmDriver : MonoBehaviour
	{
		public Transform[] viewBones;

		private SkinnedMeshRenderer viewmodel;

		private Transform[] sources;

		public void Follow(SkinnedMeshRenderer viewmodel)
		{
			this.viewmodel = viewmodel;
			sources = null;
		}

		private void LateUpdate()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)viewmodel) || viewBones == null || viewBones.Length == 0)
			{
				return;
			}
			if (sources == null)
			{
				BuildMap();
			}
			if (sources == null)
			{
				return;
			}
			Transform parent = viewBones[0].parent;
			if (Object.op_Implicit((Object)(object)parent))
			{
				parent.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
				parent.localScale = Vector3.one;
			}
			for (int i = 0; i < viewBones.Length; i++)
			{
				Transform val = viewBones[i];
				Transform val2 = sources[i];
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2))
				{
					val.SetPositionAndRotation(val2.position, val2.rotation);
					val.localScale = val2.lossyScale;
				}
			}
		}

		private void BuildMap()
		{
			Transform[] bones = viewmodel.bones;
			if (bones == null || bones.Length == 0)
			{
				return;
			}
			Dictionary<string, Transform> dictionary = new Dictionary<string, Transform>();
			foreach (Transform val in bones)
			{
				if (Object.op_Implicit((Object)(object)val) && !dictionary.ContainsKey(((Object)val).name))
				{
					dictionary.Add(((Object)val).name, val);
				}
			}
			dictionary.TryGetValue("spine.003", out var value);
			if (!dictionary.TryGetValue("arm.L_upper", out var _))
			{
				Plugin.Logger.LogWarning((object)"Could not find the employee viewmodel arms.");
				return;
			}
			Transform[] array = (Transform[])(object)new Transform[viewBones.Length];
			for (int j = 0; j < viewBones.Length; j++)
			{
				Transform val2 = viewBones[j];
				string text = (Object.op_Implicit((Object)(object)val2) ? ViewmodelBone(((Object)val2).name) : null);
				Transform value3 = null;
				if (text != null)
				{
					dictionary.TryGetValue(text, out value3);
				}
				array[j] = (Object.op_Implicit((Object)(object)value3) ? value3 : value);
			}
			sources = array;
			Plugin.Logger.LogInfo((object)"First person arms are following the employee viewmodel.");
		}

		private static string ViewmodelBone(string name)
		{
			switch (name)
			{
			case "upper_arm.L":
				return "arm.L_upper";
			case "forearm.L":
				return "arm.L_lower";
			case "Index01.L":
				return "finger2.L";
			case "Middle01.L":
				return "finger3.L";
			case "Middle01.L.001":
				return "finger3.L.001";
			case "Thumb01.L":
				return "finger1.L";
			case "upper_arm.R":
				return "arm.R_upper";
			case "forearm.R":
				return "arm.R_lower";
			case "Index01.R":
				return "finger2.R";
			case "Middle01.R":
				return "finger3.R";
			case "Middle01.R.001":
				return "finger3.R.001";
			case "Thumb01.R":
				return "finger1.R";
			case "shoulder.L":
			case "shoulder.R":
			case "hand.L":
			case "hand.R":
				return name;
			default:
				return "spine.003";
			}
		}
	}
	internal static class ProtogenBones
	{
		public static BoneMimicHandler AttachBones(ProtogenHandler protogen)
		{
			Transform val = FindMetarig(protogen.player);
			GameObject gameObject = ((Component)protogen).gameObject;
			gameObject.AddComponent<SimpleIKHandler>();
			BoneMimicHandler boneMimicHandler = gameObject.AddComponent<BoneMimicHandler>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.Logger.LogError((object)"Could not find the player metarig. The protogen will not follow the body.");
				return boneMimicHandler;
			}
			AttachToTarget(boneMimicHandler, ((Component)protogen).transform, val);
			return boneMimicHandler;
		}

		private static Transform FindMetarig(PlayerControllerB player)
		{
			if (!Object.op_Implicit((Object)(object)player))
			{
				return null;
			}
			LODGroup componentInChildren = ((Component)player).GetComponentInChildren<LODGroup>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				Transform val = ((Component)componentInChildren).transform.Find("metarig");
				if (Object.op_Implicit((Object)(object)val))
				{
					return val;
				}
			}
			Transform[] componentsInChildren = ((Component)player).GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (((Object)componentsInChildren[i]).name == "metarig")
				{
					return componentsInChildren[i];
				}
			}
			return null;
		}

		public static BoneMimicHandler AttachTempBones(ProtogenHandler protogen, Transform target)
		{
			BoneMimicHandler boneMimicHandler = ((Component)protogen).gameObject.AddComponent<BoneMimicHandler>();
			AttachToTarget(boneMimicHandler, ((Component)protogen).transform, target);
			return boneMimicHandler;
		}

		private static void AttachToTarget(BoneMimicHandler bones, Transform original, Transform target)
		{
			bones.ResetBonePairs();
			bones.BuildOriginalReference(original);
			bones.BuildTargetReference(target);
			bones.PairBones(original, target);
			if (!Object.op_Implicit((Object)(object)bones.GetTargetBone("spine")))
			{
				bones.PairBones("Spine", "spine.001");
			}
			else
			{
				bones.PairBones("Spine", "spine");
			}
			bones.PairBones("Chest", "spine.003", rotation: true, position: false);
			bones.PairBones("Neck", "spine.004", rotation: true, position: false);
			bones.PairBones("Head", "spine.004_end", rotation: true, position: false);
			bones.PairBones("shoulder.L", "shoulder.L", rotation: true, position: false);
			bones.PairBones("upper_arm.L", "arm.L_upper", rotation: true, position: false);
			bones.PairBones("forearm.L", "arm.L_lower", rotation: true, position: false);
			bones.PairBones("hand.L", "hand.L", rotation: true, position: false);
			bones.PairBones("Index01.L", "finger2.L", rotation: true, position: false);
			bones.PairBones("Middle01.L", "finger3.L", rotation: true, position: false);
			bones.PairBones("Middle01.L.001", "finger3.L.001", rotation: true, position: false);
			bones.PairBones("Thumb01.L", "finger1.L", rotation: true, position: false);
			bones.PairBones("shoulder.R", "shoulder.R", rotation: true, position: false);
			bones.PairBones("upper_arm.R", "arm.R_upper", rotation: true, position: false);
			bones.PairBones("forearm.R", "arm.R_lower", rotation: true, position: false);
			bones.PairBones("hand.R", "hand.R", rotation: true, position: false);
			bones.PairBones("Index01.R", "finger2.R", rotation: true, position: false);
			bones.PairBones("Middle01.R", "finger3.R", rotation: true, position: false);
			bones.PairBones("Middle01.R.001", "finger3.R.001", rotation: true, position: false);
			bones.PairBones("Thumb01.R", "finger1.R", rotation: true, position: false);
			bones.PairBones("thigh.L", "thigh.L");
			bones.PairBones("shin.L", "shin.L", rotation: true, position: false);
			bones.PairBones("foot.L", "foot.L");
			bones.PairBones("toe.L", "toe.L", rotation: true, position: false);
			bones.PairBones("thigh.R", "thigh.R");
			bones.PairBones("shin.R", "shin.R", rotation: true, position: false);
			bones.PairBones("foot.R", "foot.R");
			bones.PairBones("toe.R", "toe.R", rotation: true, position: false);
		}

		public static void AttachWigglyBones(Transform original)
		{
			if (!Object.op_Implicit((Object)(object)((Component)original).GetComponent<WigglyBones>()))
			{
				((Component)original).gameObject.AddComponent<WigglyBones>();
			}
		}

		public static void UpdateIKTargets(Transform original, BoneMimicHandler bones)
		{
			SimpleIKHandler component = ((Component)original).GetComponent<SimpleIKHandler>();
			if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)bones))
			{
				component.SetLeftHand(bones.GetTargetBone("hand.L"));
				component.SetRightHand(bones.GetTargetBone("hand.R"));
				component.SetLeftFoot(bones.GetTargetBone("foot.L"));
				component.SetRightFoot(bones.GetTargetBone("foot.R"));
			}
		}
	}
	internal static class ProtogenExpressions
	{
		private static Material[] expressions;

		public static void BuildExpressions()
		{
			if (expressions == null)
			{
				expressions = (Material[])(object)new Material[6];
				expressions[0] = CreateUnLitExpressionMaterial(ProtogenPrefabs.face_none);
				expressions[1] = CreateLitExpressionMaterial(ProtogenPrefabs.face_default);
				expressions[2] = CreateLitExpressionMaterial(ProtogenPrefabs.face_dance);
				expressions[3] = CreateLitExpressionMaterial(ProtogenPrefabs.face_point);
				expressions[4] = CreateLitExpressionMaterial(ProtogenPrefabs.face_paranoid);
				expressions[5] = CreateLitExpressionMaterial(ProtogenPrefabs.face_crash);
			}
		}

		private static Material CreateUnLitExpressionMaterial(Texture2D texture)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			Material val = new Material(ProtogenPrefabs.face_unlit);
			val.SetTexture("_BaseColorMap", (Texture)(object)texture);
			return val;
		}

		private static Material CreateLitExpressionMaterial(Texture2D texture)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			Material val = new Material(ProtogenPrefabs.face_lit);
			val.SetTexture("_BaseColorMap", (Texture)(object)texture);
			val.SetTexture("_EmissiveColorMap", (Texture)(object)texture);
			return val;
		}

		public static Material GetFacialMaterial(FacialExpression expression)
		{
			return expressions[(int)expression];
		}
	}
	internal class ProtogenHandler : MonoBehaviour
	{
		public bool isAttached;

		private bool isInitialized;

		public bool validDeadbody;

		public PlayerControllerB player;

		public Transform body;

		public Renderer bodyRenderer;

		private Renderer armsRenderer;

		private MaterialPropertyBlock armsBlock;

		public Transform ears;

		public Renderer earsRenderer;

		public Transform tail;

		public Renderer tailRenderer;

		public Transform tank;

		public Renderer tankRenderer;

		public BoneMimicHandler bones;

		public BoneMimicHandler temp_bones;

		private FacialExpression expression;

		private Material[] body_materials;

		public void UpdateCosmetics()
		{
			ProtogenTextureKit textureKit = ProtogenManager.GetTextureKit(ProtogenUtil.GetPlayerID(player));
			ProtogenTextures.ApplyTextures(this, textureKit);
			ProtogenTextures.UpdateSuit(this);
			body_materials = bodyRenderer.materials;
		}

		public void UpdateExpression()
		{
			FacialExpression facialExpression = expression;
			facialExpression = ((!player.isPlayerDead) ? (player.performingEmote ? ((player.playerBodyAnimator.GetInteger("emoteNumber") <= 1) ? FacialExpression.Dance : FacialExpression.Point) : ((player.playersManager.fearLevel >= 0.9f && player.insanityLevel > player.maxInsanityLevel / 2f) ? FacialExpression.Crash : ((!(player.playersManager.fearLevel >= 0.9f) && !(player.insanityLevel > player.maxInsanityLevel / 2f)) ? ((!(player.playersManager.fearLevel >= 0.4f) && !(player.insanityLevel > 0f)) ? FacialExpression.Default : FacialExpression.Point) : FacialExpression.Paranoid))) : FacialExpression.None);
			if (facialExpression != expression)
			{
				expression = facialExpression;
				body_materials[3] = ProtogenExpressions.GetFacialMaterial(expression);
				bodyRenderer.materials = body_materials;
			}
		}

		public void Initialize()
		{
			if (!isInitialized)
			{
				body = ((Component)this).transform.Find("ProtoBody");
				bodyRenderer = (Renderer)(object)((Component)body).GetComponent<SkinnedMeshRenderer>();
				ref Renderer reference = ref armsRenderer;
				Renderer obj = bodyRenderer;
				reference = (Renderer)(object)ProtogenArms.CreateView((SkinnedMeshRenderer)(object)((obj is SkinnedMeshRenderer) ? obj : null));
				((Component)this).gameObject.AddComponent<SimpleIKHandler>();
				ears = Object.Instantiate<GameObject>(ProtogenPrefabs.prefab_ears).transform;
				earsRenderer = (Renderer)(object)((Component)ears).GetComponent<SkinnedMeshRenderer>();
				tail = Object.Instantiate<GameObject>(ProtogenPrefabs.prefab_tail).transform;
				tailRenderer = (Renderer)(object)((Component)tail).GetComponent<SkinnedMeshRenderer>();
				tank = Object.Instantiate<GameObject>(ProtogenPrefabs.prefab_tank).transform;
				tankRenderer = (Renderer)(object)((Component)tank).GetComponent<MeshRenderer>();
				((Component)ears).gameObject.AddComponent<WigglyBones>();
				((Component)tail).gameObject.AddComponent<WigglyBones>();
				body_materials = bodyRenderer.materials;
				isInitialized = true;
			}
		}

		public void AttachToPlayer(PlayerControllerB player)
		{
			this.player = player;
			bones = ProtogenBones.AttachBones(this);
			ears.SetParent(bones.GetOriginalBone("Head"), false);
			tail.SetParent(bones.GetOriginalBone("Spine"), false);
			tank.SetParent(bones.GetOriginalBone("Chest"), false);
			ProtogenBones.UpdateIKTargets(((Component)this).transform, bones);
			isAttached = true;
			ProtogenArms.FollowViewmodel(armsRenderer, player.thisPlayerModelArms);
			MatchPlayerMaterial(player);
			IsVisible(visible: true);
			((Component)this).transform.SetParent(((Component)player).transform, false);
		}

		private void MatchPlayerMaterial(PlayerControllerB player)
		{
			if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)player.thisPlayerModel))
			{
				Material sharedMaterial = ((Renderer)player.thisPlayerModel).sharedMaterial;
				if (Object.op_Implicit((Object)(object)sharedMaterial) && Object.op_Implicit((Object)(object)sharedMaterial.shader))
				{
					int layer = ((Component)player.thisPlayerModel).gameObject.layer;
					ApplyReferenceShader(bodyRenderer, sharedMaterial, layer);
					ApplyReferenceShader(earsRenderer, sharedMaterial, layer);
					ApplyReferenceShader(tailRenderer, sharedMaterial, layer);
					ApplyReferenceShader(tankRenderer, sharedMaterial, layer);
				}
			}
		}

		private void ApplyReferenceShader(Renderer renderer, Material reference, int layer)
		{
			if (!Object.op_Implicit((Object)(object)renderer))
			{
				return;
			}
			((Component)renderer).gameObject.layer = layer;
			Material[] materials = renderer.materials;
			for (int i = 0; i < materials.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)materials[i]))
				{
					materials[i].shader = reference.shader;
				}
			}
			renderer.materials = materials;
		}

		public void RemoveFromPlayer()
		{
			IsVisible(visible: false);
			RemoveFromDeadBody();
			Object.DestroyImmediate((Object)(object)bones);
			bones = null;
			isAttached = false;
			validDeadbody = false;
			player = null;
			((Component)this).transform.SetParent((Transform)null, false);
		}

		public void AttachToDeadBody()
		{
			if (HasDeadBody())
			{
				temp_bones = ProtogenBones.AttachTempBones(this, ((Component)player.deadBody).transform);
			}
		}

		public void RemoveFromDeadBody()
		{
			Object.DestroyImmediate((Object)(object)temp_bones);
			temp_bones = null;
			validDeadbody = false;
		}

		public bool HasDeadBody()
		{
			if (player.isPlayerDead && !((Object)(object)player.deadBody == (Object)null))
			{
				return ((Component)player.deadBody).gameObject.activeSelf;
			}
			return false;
		}

		public void UpdateVisuals()
		{
			bool flag = isAttached && (HasDeadBody() || !player.isPlayerDead) && (HasDeadBody() || !ProtogenUtil.IsLocal(player) || ProtogenUtil.IsLocalThirdPerson(player));
			if (player.isPlayerDead)
			{
				if (Object.op_Implicit((Object)(object)temp_bones) && !validDeadbody)
				{
					RemoveFromDeadBody();
				}
				else if (!Object.op_Implicit((Object)(object)temp_bones) && validDeadbody)
				{
					AttachToDeadBody();
				}
			}
			else if (Object.op_Implicit((Object)(object)temp_bones))
			{
				RemoveFromDeadBody();
			}
			bool flag2 = isAttached && ProtogenUtil.IsLocal(player) && !ProtogenUtil.IsLocalThirdPerson(player) && !player.isPlayerDead && !HasDeadBody();
			SetBodyVisible(flag);
			SetRendererVisible(armsRenderer, flag2);
			if (flag2)
			{
				SyncArms();
			}
			IsTracking(flag || flag2);
			FollowBody(flag || flag2);
		}

		public void IsVisible(bool visible)
		{
			SetBodyVisible(visible);
			if (!visible)
			{
				SetRendererVisible(armsRenderer, visible: false);
			}
			IsTracking(visible);
			FollowBody(visible);
		}

		private void SetBodyVisible(bool visible)
		{
			SetRendererVisible(bodyRenderer, visible);
			SetRendererVisible(earsRenderer, visible);
			SetRendererVisible(tailRenderer, visible);
			SetRendererVisible(tankRenderer, visible);
		}

		private void SyncArms()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)armsRenderer) && Object.op_Implicit((Object)(object)bodyRenderer))
			{
				((Component)armsRenderer).gameObject.layer = ((Component)bodyRenderer).gameObject.layer;
				armsRenderer.sharedMaterials = bodyRenderer.sharedMaterials;
				if (armsBlock == null)
				{
					armsBlock = new MaterialPropertyBlock();
				}
				int num = bodyRenderer.sharedMaterials.Length;
				for (int i = 0; i < num; i++)
				{
					armsBlock.Clear();
					bodyRenderer.GetPropertyBlock(armsBlock, i);
					armsRenderer.SetPropertyBlock(armsBlock, i);
				}
			}
		}

		private void SetRendererVisible(Renderer renderer, bool visible)
		{
			if (Object.op_Implicit((Object)(object)renderer))
			{
				renderer.enabled = visible;
			}
		}

		public void IsTracking(bool tracking)
		{
			if (Object.op_Implicit((Object)(object)bones))
			{
				((Behaviour)bones).enabled = tracking && !Object.op_Implicit((Object)(object)temp_bones);
			}
			if (Object.op_Implicit((Object)(object)temp_bones))
			{
				((Behaviour)temp_bones).enabled = tracking;
			}
		}

		public void FollowBody(bool follow)
		{
			//IL_0042: 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)
			if (follow)
			{
				if (Object.op_Implicit((Object)(object)temp_bones))
				{
					((Component)this).transform.position = ((Component)player.deadBody).transform.position;
				}
				else
				{
					((Component)this).transform.position = ((Component)player).transform.position;
				}
			}
		}

		private void Awake()
		{
		}

		private void Start()
		{
		}

		private void Update()
		{
		}

		private void LateUpdate()
		{
			if (Object.op_Implicit((Object)(object)player))
			{
				PlayerPatch.HideVanillaBody(player);
			}
			UpdateVisuals();
			UpdateExpression();
		}

		private void OnEnable()
		{
		}

		private void OnDisable()
		{
			IsVisible(visible: false);
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)player))
			{
				ProtogenManager.RemoveProtogen(player);
			}
		}
	}
	internal static class ProtogenManager
	{
		private static Dictionary<PlayerControllerB, ProtogenHandler> PlayerProtogens = new Dictionary<PlayerControllerB, ProtogenHandler>();

		private static Dictionary<ulong, ProtogenTextureKit> TextureKits = new Dictionary<ulong, ProtogenTextureKit>();

		private static Stack<ProtogenHandler> ProtogenPool = new Stack<ProtogenHandler>();

		public static bool HasProtogen(PlayerControllerB player, out ProtogenHandler protogen)
		{
			protogen = null;
			if (PlayerProtogens != null)
			{
				PlayerProtogens.TryGetValue(player, out protogen);
			}
			return (Object)(object)protogen != (Object)null;
		}

		public static void Apply(PlayerControllerB player, bool enabled)
		{
			if (Object.op_Implicit((Object)(object)player))
			{
				ProtogenHandler protogen;
				if (enabled)
				{
					PlayerPatch.HideVanillaBody(player);
					GetProtogen(player);
				}
				else if (HasProtogen(player, out protogen))
				{
					RemoveProtogen(player);
					PlayerPatch.ShowVanillaBody(player);
				}
			}
		}

		public static ProtogenHandler GetProtogen(PlayerControllerB player)
		{
			if (!Object.op_Implicit((Object)(object)player))
			{
				return null;
			}
			if (PlayerProtogens.TryGetValue(player, out var value) && Object.op_Implicit((Object)(object)value))
			{
				return value;
			}
			PlayerProtogens.Remove(player);
			value = CreateProtogen();
			PlayerProtogens[player] = value;
			value.AttachToPlayer(player);
			value.UpdateCosmetics();
			return value;
		}

		public static void RemoveProtogen(PlayerControllerB player)
		{
			if (Object.op_Implicit((Object)(object)player))
			{
				if (PlayerProtogens.TryGetValue(player, out var value) && Object.op_Implicit((Object)(object)value))
				{
					value.RemoveFromPlayer();
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
				PlayerProtogens.Remove(player);
			}
		}

		public static ProtogenTextureKit GetTextureKit(ulong playerID)
		{
			if (!TextureKits.TryGetValue(playerID, out var value))
			{
				value = ProtogenTextures.BuildTextures(playerID);
				TextureKits.Add(playerID, value);
			}
			return value;
		}

		private static ProtogenHandler CreateProtogen()
		{
			ProtogenHandler protogenHandler = Object.Instantiate<GameObject>(ProtogenPrefabs.prefab_body).AddComponent<ProtogenHandler>();
			protogenHandler.Initialize();
			return protogenHandler;
		}
	}
	internal static class ProtogenPrefabs
	{
		private const string ASSETBUNDLE = "companyprotogen";

		private const string VERSIONFILE = "Assets/Protogen/version.txt";

		private const string VERSION = "RELEASE_1";

		private const string BODY_SUIT = "Assets/Protogen/FurPatterns/Body/Suit.png";

		private const string BODY_PAWS_DETAIL = "Assets/Protogen/FurPatterns/Body/PawDetail.png";

		private const string BODY_PAWS = "Assets/Protogen/FurPatterns/Body/Paws.png";

		private const string BODY_REGAL = "Assets/Protogen/FurPatterns/Body/Regal.png";

		private const string BODY_SHADE = "Assets/Protogen/FurPatterns/Body/Shade.png";

		private const string BODY_SPOTTY = "Assets/Protogen/FurPatterns/Body/Spotty.png";

		private const string BODY_STRIPED = "Assets/Protogen/FurPatterns/Body/Striped.png";

		private const string EARS_INNER = "Assets/Protogen/FurPatterns/Ears/Inner.png";

		private const string EARS_STRIPED = "Assets/Protogen/FurPatterns/Ears/Striped.png";

		private const string EARS_TIPPED = "Assets/Protogen/FurPatterns/Ears/Tipped.png";

		private const string TAIL_REGAL = "Assets/Protogen/FurPatterns/Tail/Regal.png";

		private const string TAIL_SHAPES = "Assets/Protogen/FurPatterns/Tail/Shapes.png";

		private const string TAIL_SPOTTY = "Assets/Protogen/FurPatterns/Tail/Spotty.png";

		private const string TAIL_STRIPED = "Assets/Protogen/FurPatterns/Tail/Striped.png";

		private const string PREFAB_PROTO = "Assets/Protogen/Prefabs/ProtoPrefab.prefab";

		private const string PREFAB_EARS = "Assets/Protogen/Prefabs/ProtoEarsPrefab.prefab";

		private const string PREFAB_TAIL = "Assets/Protogen/Prefabs/ProtoTailLongPrefab.prefab";

		private const string PREFAB_TANK = "Assets/Protogen/Prefabs/ProtoTankPrefab.prefab";

		private const string TEXTURES_ICON = "Assets/Protogen/Textures/defaulticon.png";

		private const string TEXTURES_BODY = "Assets/Protogen/Textures/BodyTex.png";

		private const string TEXTURES_EARS = "Assets/Protogen/Textures/EarsTex.png";

		private const string TEXTURES_TAIL = "Assets/Protogen/Textures/TailTex.png";

		private const string FACES_MAT_UNLIT = "Assets/Protogen/Faces/ProtoUnLitScreenMat.mat";

		private const string FACES_MAT_LIT = "Assets/Protogen/Faces/ProtoScreenMat.mat";

		private const string FACES_NONE = "Assets/Protogen/Faces/ScreenPlaceholder.png";

		private const string FACES_DEFAULT = "Assets/Protogen/Faces/DefaultFace.png";

		private const string FACES_DANCE = "Assets/Protogen/Faces/DanceFace.png";

		private const string FACES_POINT = "Assets/Protogen/Faces/PointFace.png";

		private const string FACES_PARANOID = "Assets/Protogen/Faces/ParanoidFace.png";

		private const string FACES_CRASH = "Assets/Protogen/Faces/CrashFace.png";

		public static AssetBundle assetbundle;

		public static GameObject prefab_body;

		public static GameObject prefab_ears;

		public static GameObject prefab_tail;

		public static GameObject prefab_tank;

		public static Texture2D fur_body_suit;

		public static Texture2D fur_body_paws_detail;

		public static Texture2D fur_body_paws;

		public static Texture2D fur_body_regal;

		public static Texture2D fur_body_shade;

		public static Texture2D fur_body_spotty;

		public static Texture2D fur_body_striped;

		public static Texture2D fur_ears_inner;

		public static Texture2D fur_ears_striped;

		public static Texture2D fur_ears_tipped;

		public static Texture2D fur_tail_regal;

		public static Texture2D fur_tail_shapes;

		public static Texture2D fur_tail_spotty;

		public static Texture2D fur_tail_striped;

		public static Texture2D icon_default;

		public static Texture2D body_default;

		public static Texture2D ears_default;

		public static Texture2D tail_default;

		public static Material face_unlit;

		public static Material face_lit;

		public static Texture2D face_none;

		public static Texture2D face_default;

		public static Texture2D face_dance;

		public static Texture2D face_point;

		public static Texture2D face_paranoid;

		public static Texture2D face_crash;

		public static bool Init()
		{
			assetbundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "companyprotogen"));
			if (assetbundle.LoadAsset<TextAsset>("Assets/Protogen/version.txt").text != "RELEASE_1")
			{
				Plugin.Logger.LogError((object)"Assetbundle is outdated/incompatible!");
				return false;
			}
			prefab_body = assetbundle.LoadAsset<GameObject>("Assets/Protogen/Prefabs/ProtoPrefab.prefab");
			prefab_ears = assetbundle.LoadAsset<GameObject>("Assets/Protogen/Prefabs/ProtoEarsPrefab.prefab");
			prefab_tail = assetbundle.LoadAsset<GameObject>("Assets/Protogen/Prefabs/ProtoTailLongPrefab.prefab");
			prefab_tank = assetbundle.LoadAsset<GameObject>("Assets/Protogen/Prefabs/ProtoTankPrefab.prefab");
			fur_body_suit = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Body/Suit.png");
			fur_body_paws_detail = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Body/PawDetail.png");
			fur_body_paws = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Body/Paws.png");
			fur_body_regal = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Body/Regal.png");
			fur_body_shade = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Body/Shade.png");
			fur_body_spotty = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Body/Spotty.png");
			fur_body_striped = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Body/Striped.png");
			fur_ears_inner = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Ears/Inner.png");
			fur_ears_striped = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Ears/Striped.png");
			fur_ears_tipped = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Ears/Tipped.png");
			fur_tail_regal = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Tail/Regal.png");
			fur_tail_shapes = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Tail/Shapes.png");
			fur_tail_spotty = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Tail/Spotty.png");
			fur_tail_striped = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/FurPatterns/Tail/Striped.png");
			icon_default = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/Textures/defaulticon.png");
			body_default = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/Textures/BodyTex.png");
			ears_default = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/Textures/EarsTex.png");
			tail_default = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/Textures/TailTex.png");
			face_unlit = assetbundle.LoadAsset<Material>("Assets/Protogen/Faces/ProtoUnLitScreenMat.mat");
			face_lit = assetbundle.LoadAsset<Material>("Assets/Protogen/Faces/ProtoScreenMat.mat");
			face_none = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/Faces/ScreenPlaceholder.png");
			face_default = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/Faces/DefaultFace.png");
			face_dance = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/Faces/DanceFace.png");
			face_point = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/Faces/PointFace.png");
			face_paranoid = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/Faces/ParanoidFace.png");
			face_crash = assetbundle.LoadAsset<Texture2D>("Assets/Protogen/Faces/CrashFace.png");
			RetargetBundleShaders();
			return true;
		}

		private static void RetargetBundleShaders()
		{
			Shader val = Shader.Find("HDRP/Lit");
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.Logger.LogWarning((object)"HDRP/Lit was not found. Protogen materials may not render on this game version.");
				return;
			}
			RetargetRenderers(prefab_body, val);
			RetargetRenderers(prefab_ears, val);
			RetargetRenderers(prefab_tail, val);
			RetargetRenderers(prefab_tank, val);
			RetargetMaterial(face_unlit, val);
			RetargetMaterial(face_lit, val);
		}

		private static void RetargetRenderers(GameObject prefab, Shader shader)
		{
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				return;
			}
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Material[] sharedMaterials = componentsInChildren[i].sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					RetargetMaterial(sharedMaterials[j], shader);
				}
			}
		}

		private static void RetargetMaterial(Material material, Shader shader)
		{
			if (Object.op_Implicit((Object)(object)material) && Object.op_Implicit((Object)(object)shader) && !((Object)(object)material.shader == (Object)(object)shader))
			{
				material.shader = shader;
			}
		}
	}
	public class ProtogenSync : NetworkBehaviour
	{
		public bool Enabled;

		private bool askedForSync;

		[ServerRpc]
		public void SetEnabledServerRpc(bool enabled)
		{
			Enabled = enabled;
			SetEnabledClientRpc(enabled);
		}

		[ClientRpc]
		public void SetEnabledClientRpc(bool enabled)
		{
			Enabled = enabled;
			ProtogenManager.Apply(((Component)this).GetComponent<PlayerControllerB>(), enabled);
		}

		[ServerRpc]
		public void RequestSyncServerRpc()
		{
			if (!Object.op_Implicit((Object)(object)StartOfRound.Instance))
			{
				return;
			}
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			for (int i = 0; i < allPlayerScripts.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)allPlayerScripts[i]))
				{
					ProtogenSync component = ((Component)allPlayerScripts[i]).GetComponent<ProtogenSync>();
					if (Object.op_Implicit((Object)(object)component))
					{
						component.SetEnabledClientRpc(component.Enabled);
					}
				}
			}
		}

		private void Update()
		{
			if (!askedForSync && ((NetworkBehaviour)this).IsOwner && !((NetworkBehaviour)this).IsServer && ((NetworkBehaviour)this).IsSpawned)
			{
				askedForSync = true;
				RequestSyncServerRpc();
			}
		}
	}
	internal class ProtogenTextureKit
	{
		public bool isDark;

		public Color mainColor;

		public Color secondaryColor;

		public Texture2D icon;

		public Texture2D body;

		public Texture2D ears;

		public Texture2D tail;

		public MaterialPropertyBlock iconProp;

		public MaterialPropertyBlock bodyProp;

		public MaterialPropertyBlock earsProp;

		public MaterialPropertyBlock tailProp;
	}
	internal class ProtogenTextures
	{
		public static void ApplyTextures(ProtogenHandler protogen, ProtogenTextureKit texKit)
		{
			protogen.bodyRenderer.SetPropertyBlock(texKit.iconProp, 2);
			protogen.bodyRenderer.SetPropertyBlock(texKit.bodyProp, 0);
			protogen.earsRenderer.SetPropertyBlock(texKit.earsProp);
			protogen.tailRenderer.SetPropertyBlock(texKit.tailProp);
		}

		public static void UpdateSuit(ProtogenHandler protogen)
		{
			MaterialPropertyBlock val = CreateProperty(StartOfRound.Instance.unlockablesList.unlockables[protogen.player.currentSuitID].suitMaterial.mainTexture);
			protogen.bodyRenderer.SetPropertyBlock(val, 1);
			protogen.tankRenderer.SetPropertyBlock(val);
		}

		public static ProtogenTextureKit BuildTextures(ulong playerID)
		{
			ProtogenTextureKit kit = new ProtogenTextureKit();
			kit.icon = ProtogenUtil.GetPlayerIcon(playerID);
			TextureTools.DominantColors(kit.icon, out kit.isDark, out kit.mainColor, out kit.secondaryColor);
			RandomizeTextures(playerID, ref kit);
			kit.iconProp = CreateEmissiveProperty((Texture)(object)kit.icon);
			kit.bodyProp = CreateProperty((Texture)(object)kit.body);
			kit.tailProp = CreateProperty((Texture)(object)kit.tail);
			kit.earsProp = CreateProperty((Texture)(object)kit.ears);
			return kit;
		}

		private static void RandomizeTextures(ulong seed, ref ProtogenTextureKit kit)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			Color[] array = RandomizeBody(seed, kit);
			Color[] array2 = RandomizeEars(seed, kit);
			Color[] array3 = RandomizeTail(seed, kit);
			kit.body = new Texture2D(1024, 1024, (TextureFormat)3, true);
			kit.ears = new Texture2D(512, 512, (TextureFormat)3, true);
			kit.tail = new Texture2D(512, 512, (TextureFormat)3, true);
			kit.body.SetPixels(0, 0, 1024, 1024, array);
			kit.ears.SetPixels(0, 0, 512, 512, array2);
			kit.tail.SetPixels(0, 0, 512, 512, array3);
			kit.body.Apply();
			kit.ears.Apply();
			kit.tail.Apply();
		}

		public static Color[] RandomizeBody(ulong seed, ProtogenTextureKit kit)
		{
			//IL_0007: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: 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_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: 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_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			int magic = 45634;
			Color mainColor = kit.mainColor;
			List<int> list = DeckShuffle(seed, 4);
			int num = (int)((ulong)GenerateRandomNumber(mainColor, magic, seed) % (ulong)list.Count());
			Color[] array = null;
			switch ((num < list.Count) ? list[num] : (-1))
			{
			case 0:
				array = ProtogenPrefabs.fur_body_striped.GetPixels();
				break;
			case 1:
				array = ProtogenPrefabs.fur_body_spotty.GetPixels();
				break;
			case 2:
				array = ProtogenPrefabs.fur_body_shade.GetPixels();
				break;
			case 3:
				array = ProtogenPrefabs.fur_body_regal.GetPixels();
				break;
			}
			Color[] array2 = TextureTools.FlatColor(1024, 1024, kit.isDark ? kit.mainColor : kit.secondaryColor);
			Color[] pixels = ProtogenPrefabs.fur_body_suit.GetPixels();
			Color[] pixels2 = ProtogenPrefabs.fur_body_paws.GetPixels();
			Color[] pixels3 = ProtogenPrefabs.fur_body_paws_detail.GetPixels();
			Color color = (kit.isDark ? kit.secondaryColor : kit.mainColor);
			Color val = (kit.isDark ? Color.white : Color.black);
			Color val2 = Color.Lerp(val, kit.mainColor, 0.5f);
			val2 = Color.Lerp(val2, kit.secondaryColor, 0.25f);
			for (int i = 0; i < array2.Length; i++)
			{
				if (array != null)
				{
					array2[i] = PixelKit.Lerp_Mask(array2[i], array[i], color);
				}
				array2[i] = PixelKit.Lerp_Mask(array2[i], pixels2[i], val2);
				array2[i] = PixelKit.Lerp_Mask(array2[i], pixels3[i], val);
				array2[i] = PixelKit.Lerp_Alpha(array2[i], pixels[i]);
			}
			return array2;
		}

		public static Color[] RandomizeEars(ulong seed, ProtogenTextureKit kit)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			int magic = 185139221;
			Color mainColor = kit.mainColor;
			List<int> list = DeckShuffle(seed, 2);
			int num = (int)((ulong)GenerateRandomNumber(mainColor, magic, seed) % (ulong)list.Count());
			Color[] array = null;
			switch ((num < list.Count) ? list[num] : (-1))
			{
			case 1:
				array = ProtogenPrefabs.fur_ears_tipped.GetPixels();
				break;
			case 0:
				array = ProtogenPrefabs.fur_ears_striped.GetPixels();
				break;
			}
			Color[] array2 = TextureTools.FlatColor(512, 512, kit.isDark ? kit.mainColor : kit.secondaryColor);
			Color[] pixels = ProtogenPrefabs.fur_ears_inner.GetPixels();
			Color color = (kit.isDark ? kit.secondaryColor : kit.mainColor);
			for (int i = 0; i < array2.Length; i++)
			{
				if (array != null)
				{
					array2[i] = PixelKit.Lerp_Mask(array2[i], array[i], color);
				}
				array2[i] = PixelKit.Lerp_Mask(array2[i], pixels[i], color);
			}
			return array2;
		}

		public static Color[] RandomizeTail(ulong seed, ProtogenTextureKit kit)
		{
			//IL_0007: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			int magic = 9472735;
			Color mainColor = kit.mainColor;
			List<int> list = DeckShuffle(seed, 4);
			int num = (int)((ulong)GenerateRandomNumber(mainColor, magic, seed) % (ulong)list.Count());
			Color[] array = null;
			switch ((num < list.Count) ? list[num] : (-1))
			{
			case 0:
				array = ProtogenPrefabs.fur_tail_striped.GetPixels();
				break;
			case 1:
				array = ProtogenPrefabs.fur_tail_spotty.GetPixels();
				break;
			case 2:
				array = ProtogenPrefabs.fur_tail_shapes.GetPixels();
				break;
			case 3:
				array = ProtogenPrefabs.fur_tail_regal.GetPixels();
				break;
			}
			Color[] array2 = TextureTools.FlatColor(512, 512, kit.isDark ? kit.mainColor : kit.secondaryColor);
			Color color = (kit.isDark ? kit.secondaryColor : kit.mainColor);
			for (int i = 0; i < array2.Length; i++)
			{
				if (array != null)
				{
					array2[i] = PixelKit.Lerp_Mask(array2[i], array[i], color);
				}
			}
			return array2;
		}

		public static MaterialPropertyBlock CreateProperty(Texture texture)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			MaterialPropertyBlock val = new MaterialPropertyBlock();
			val.SetTexture("_BaseColorMap", texture);
			return val;
		}

		public static MaterialPropertyBlock CreateEmissiveProperty(Texture texture)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			MaterialPropertyBlock val = new MaterialPropertyBlock();
			val.SetTexture("_BaseColorMap", texture);
			val.SetTexture("_EmissiveColorMap", texture);
			return val;
		}

		public static List<int> DeckShuffle(ulong seed, int size)
		{
			List<int> list = new List<int>();
			for (int i = 0; i < size; i++)
			{
				if (seed << list.Count % 2 == 0L)
				{
					list.Insert(0, i);
				}
				else
				{
					list.Add(i);
				}
			}
			return list;
		}

		public static uint GenerateRandomNumber(Color salt, int magic, ulong seed)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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)
			Random random = new Random((int)((ulong)((salt.r + salt.g + salt.b) * (float)magic) ^ seed));
			byte[] array = new byte[4];
			random.NextBytes(array);
			return BitConverter.ToUInt32(array, 0);
		}
	}
	internal static class ProtogenUtil
	{
		private static bool thirdPersonResolved;

		private static Func<bool> thirdPersonEnabled;

		public static bool IsLocal(PlayerControllerB player)
		{
			return (Object)(object)player == (Object)(object)GameNetworkManager.Instance.localPlayerController;
		}

		public static bool IsLocalThirdPerson(PlayerControllerB player)
		{
			if (IsLocal(player))
			{
				return IsThirdPersonEnabled();
			}
			return false;
		}

		private static bool IsThirdPersonEnabled()
		{
			if (!thirdPersonResolved)
			{
				thirdPersonResolved = true;
				thirdPersonEnabled = ResolveThirdPerson();
			}
			if (thirdPersonEnabled == null)
			{
				return false;
			}
			try
			{
				return thirdPersonEnabled();
			}
			catch (Exception)
			{
				return false;
			}
		}

		private static Func<bool> ResolveThirdPerson()
		{
			Type type = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				type = assemblies[i].GetType("LCThirdPerson.ThirdPersonPlugin");
				if (type != null)
				{
					break;
				}
			}
			if (type == null)
			{
				Debug.Log((object)"Updatedprotogen: no third-person mod found, so your body stays hidden in first person.");
				return null;
			}
			PropertyInfo instanceProperty = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);
			PropertyInfo enabledProperty = type.GetProperty("Enabled", BindingFlags.Instance | BindingFlags.Public);
			if (instanceProperty == null || enabledProperty == null)
			{
				Debug.Log((object)"Updatedprotogen: third-person mod is present, but its toggle could not be read.");
				return null;
			}
			Debug.Log((object)"Updatedprotogen: showing your protogen while third person is on.");
			return delegate
			{
				object value = instanceProperty.GetValue(null, null);
				if (value == null)
				{
					return false;
				}
				object value2 = enabledProperty.GetValue(value, null);
				bool flag = default(bool);
				int num;
				if (value2 is bool)
				{
					flag = (bool)value2;
					num = 1;
				}
				else
				{
					num = 0;
				}
				return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
			};
		}

		public static ulong GetPlayerID(PlayerControllerB player)
		{
			if (GameNetworkManager.Instance.disableSteam)
			{
				return player.actualClientId;
			}
			return player.playerSteamId;
		}

		public static Texture2D GetPlayerIcon(ulong steamID)
		{
			Texture2D val = null;
			if (!GameNetworkManager.Instance.disableSteam)
			{
				Image? avatarSynchronously = GetAvatarSynchronously(steamID);
				if (avatarSynchronously.HasValue)
				{
					val = HUDManager.GetTextureFromImage(avatarSynchronously);
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = Object.Instantiate<Texture2D>(ProtogenPrefabs.icon_default);
			}
			return val;
		}

		private static Image? GetAvatarSynchronously(ulong steamID)
		{
			try
			{
				Task<Image?> task = Task.Run(async delegate
				{
					try
					{
						return await SteamFriends.GetLargeAvatarAsync(SteamId.op_Implicit(steamID));
					}
					catch (Exception ex2)
					{
						Debug.Log((object)ex2);
						return (Image?)null;
					}
				});
				task.Wait();
				return task.Result;
			}
			catch (Exception ex)
			{
				Debug.Log((object)ex);
				return null;
			}
		}
	}
}
namespace CompanyIssuedProtogen.Patches
{
	[HarmonyPatch]
	internal static class DeadBodyPatch
	{
		public static void ApplyValidBodyMesh(ref DeadBodyInfo __instance)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (ProtogenManager.HasProtogen(__instance.playerScript, out var protogen))
			{
				SkinnedMeshRenderer componentInChildren = ((Component)__instance).GetComponentInChildren<SkinnedMeshRenderer>();
				if ((int)__instance.causeOfDeath != 0)
				{
					protogen.validDeadbody = true;
					((Renderer)componentInChildren).enabled = false;
				}
				else
				{
					protogen.validDeadbody = false;
					((Renderer)componentInChildren).enabled = true;
				}
			}
		}

		[HarmonyPatch(typeof(DeadBodyInfo), "Start")]
		[HarmonyPostfix]
		private static void DeadBodyPatch_Start_Postfix_Patch(ref DeadBodyInfo __instance)
		{
			ApplyValidBodyMesh(ref __instance);
		}

		[HarmonyPatch(typeof(DeadBodyInfo), "ChangeMesh")]
		[HarmonyPostfix]
		private static void DeadBodyPatch_ChangeMesh_Postfix_Patch(ref DeadBodyInfo __instance)
		{
			ApplyValidBodyMesh(ref __instance);
		}

		[HarmonyPatch(typeof(DeadBodyInfo), "OnDestroy")]
		[HarmonyPostfix]
		private static void DeadBodyPatch_OnDestroy_Postfix_Patch(ref DeadBodyInfo __instance)
		{
			ApplyValidBodyMesh(ref __instance);
			PlayerPatch.PatchAllPlayer();
		}
	}
	[HarmonyPatch]
	internal static class HUDManagerPatch
	{
		[HarmonyPatch(typeof(HUDManager), "SetLevelOfPlayer")]
		[HarmonyPostfix]
		public static void HUDManagerPatch_SetLevelOfPlayer_Postfix_Patch(ref HUDManager __instance, PlayerControllerB playerScript, int playerLevelIndex, bool hasBeta)
		{
		}
	}
	[HarmonyPatch]
	internal static class PlayerPatch
	{
		public static void AutoPatchVisuals(PlayerControllerB player)
		{
			if (Object.op_Implicit((Object)(object)player))
			{
				ProtogenSync component = ((Component)player).GetComponent<ProtogenSync>();
				if ((Object)(object)component != (Object)null && component.Enabled)
				{
					ProtogenManager.Apply(player, enabled: true);
				}
			}
		}

		public static void ShowVanillaBody(PlayerControllerB player)
		{
			if (!Object.op_Implicit((Object)(object)player))
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)player.thisPlayerModel))
			{
				((Renderer)player.thisPlayerModel).enabled = true;
			}
			if (Object.op_Implicit((Object)(object)player.thisPlayerModelLOD1))
			{
				((Renderer)player.thisPlayerModelLOD1).enabled = true;
			}
			if (Object.op_Implicit((Object)(object)player.thisPlayerModelLOD2))
			{
				((Renderer)player.thisPlayerModelLOD2).enabled = true;
			}
			if (ProtogenUtil.IsLocal(player) && Object.op_Implicit((Object)(object)player.thisPlayerModelArms))
			{
				((Renderer)player.thisPlayerModelArms).enabled = !ProtogenUtil.IsLocalThirdPerson(player);
			}
			LODGroup componentInChildren = ((Component)player).GetComponentInChildren<LODGroup>();
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				return;
			}
			componentInChildren.enabled = true;
			string[] array = new string[3] { "LOD1", "LOD2", "LOD3" };
			for (int i = 0; i < array.Length; i++)
			{
				Transform val = ((Component)componentInChildren).transform.Find(array[i]);
				if (Object.op_Implicit((Object)(object)val))
				{
					SkinnedMeshRenderer component = ((Component)val).GetComponent<SkinnedMeshRenderer>();
					if (Object.op_Implicit((Object)(object)component))
					{
						((Renderer)component).enabled = true;
					}
				}
			}
		}

		public static void HideVanillaBody(PlayerControllerB player)
		{
			if (Object.op_Implicit((Object)(object)player.thisPlayerModel))
			{
				((Renderer)player.thisPlayerModel).enabled = false;
			}
			if (Object.op_Implicit((Object)(object)player.thisPlayerModelLOD1))
			{
				((Renderer)player.thisPlayerModelLOD1).enabled = false;
			}
			if (Object.op_Implicit((Object)(object)player.thisPlayerModelLOD2))
			{
				((Renderer)player.thisPlayerModelLOD2).enabled = false;
			}
			if (ProtogenArms.Ready && ProtogenUtil.IsLocal(player) && Object.op_Implicit((Object)(object)player.thisPlayerModelArms))
			{
				((Renderer)player.thisPlayerModelArms).enabled = false;
			}
			LODGroup componentInChildren = ((Component)player).GetComponentInChildren<LODGroup>();
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				return;
			}
			componentInChildren.enabled = false;
			string[] array = new string[3] { "LOD1", "LOD2", "LOD3" };
			for (int i = 0; i < array.Length; i++)
			{
				Transform val = ((Component)componentInChildren).transform.Find(array[i]);
				if (Object.op_Implicit((Object)(object)val))
				{
					SkinnedMeshRenderer component = ((Component)val).GetComponent<SkinnedMeshRenderer>();
					if (Object.op_Implicit((Object)(object)component))
					{
						((Renderer)component).enabled = false;
					}
				}
			}
		}

		public static void PatchAllPlayer()
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			for (int i = 0; i < allPlayerScripts.Length; i++)
			{
				AutoPatchVisuals(allPlayerScripts[i]);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		[HarmonyPostfix]
		private static void PlayerControllerB_Update_Postfix_Patch()
		{
			Plugin.PollToggle();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "Start")]
		[HarmonyPostfix]
		private static void PlayerControllerB_Start_Postfix_Patch(PlayerControllerB __instance)
		{
			PatchAllPlayer();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DisablePlayerModel")]
		[HarmonyPostfix]
		public static void PlayerControllerB_DisablePlayerModel_Postfix_Patch(PlayerControllerB __instance)
		{
			PatchAllPlayer();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")]
		[HarmonyPostfix]
		public static void PlayerControllerB_SpawnPlayerAnimation_Postfix_Patch(PlayerControllerB __instance)
		{
			PatchAllPlayer();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SpawnDeadBody")]
		[HarmonyPrefix]
		public static void PlayerControllerB_SpawnDeadBody_Prefix_Patch(PlayerControllerB __instance, PlayerControllerB deadPlayerController)
		{
			PlayerControllerB val = (Object.op_Implicit((Object)(object)deadPlayerController) ? deadPlayerController : __instance);
			PatchAllPlayer();
			if (Object.op_Implicit((Object)(object)val) && ProtogenManager.HasProtogen(val, out var protogen))
			{
				protogen.validDeadbody = true;
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "OnDestroy")]
		[HarmonyPostfix]
		private static void PlayerControllerB_OnDestroy_Postfix_Patch(ref PlayerControllerB __instance)
		{
			ProtogenManager.RemoveProtogen(__instance);
		}
	}
	[HarmonyPatch]
	internal static class QuickMenuManagerPatch
	{
		[HarmonyPatch(typeof(QuickMenuManager), "AddUserToPlayerList")]
		[HarmonyPostfix]
		public static void AddUserToPlayerList_Postfix_Patch(QuickMenuManager __instance)
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			for (int i = 0; i < allPlayerScripts.Length; i++)
			{
				if (ProtogenManager.HasProtogen(allPlayerScripts[i], out var protogen))
				{
					protogen.UpdateCosmetics();
				}
			}
		}

		[HarmonyPatch(typeof(QuickMenuManager), "RemoveUserFromPlayerList")]
		[HarmonyPostfix]
		public static void RemoveUserFromPlayerList_Postfix_Patch(QuickMenuManager __instance)
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			for (int i = 0; i < allPlayerScripts.Length; i++)
			{
				if (ProtogenManager.HasProtogen(allPlayerScripts[i], out var protogen))
				{
					protogen.UpdateCosmetics();
				}
			}
		}
	}
	[HarmonyPatch]
	internal class UnlockableSuitPatch
	{
		[HarmonyPatch(typeof(UnlockableSuit), "SwitchSuitForPlayer")]
		[HarmonyPostfix]
		public static void UnlockableSuitPatch_SwitchSuitForPlayer_Postfix_Patch(UnlockableSuit __instance, PlayerControllerB player, int suitID, bool playAudio)
		{
			if (ProtogenManager.HasProtogen(player, out var protogen))
			{
				protogen.UpdateCosmetics();
			}
		}
	}
}

UpdatedprotogenCommand.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RuntimeNetcodeRPCValidator;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace UpdatedprotogenCommand
{
	internal struct Look
	{
		public bool UseProfilePicture;

		public bool HasPrimary;

		public bool HasSecondary;

		public Color Primary;

		public Color Secondary;

		public string Body;

		public string Ear;

		public string Tail;
	}
	internal static class Customization
	{
		private static readonly string[] BodyPatterns = new string[5] { "Profile", "Striped", "Spotty", "Shade", "Regal" };

		private static readonly string[] EarPatterns = new string[3] { "Profile", "Striped", "Tipped" };

		private static readonly string[] TailPatterns = new string[5] { "Profile", "Striped", "Spotty", "Shapes", "Regal" };

		private static ConfigEntry<bool> useProfilePicture;

		private static ConfigEntry<string> primaryColor;

		private static ConfigEntry<string> secondaryColor;

		private static ConfigEntry<string> bodyPattern;

		private static ConfigEntry<string> earPattern;

		private static ConfigEntry<string> tailPattern;

		private static readonly Dictionary<ulong, Look> Looks = new Dictionary<ulong, Look>();

		private static readonly HashSet<ulong> Painted = new HashSet<ulong>();

		internal static bool Dirty = true;

		internal static void Bind(BaseUnityPlugin plugin)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			useProfilePicture = plugin.Config.Bind<bool>("Customization", "UseProfilePicture", true, "Use your Steam profile picture for colors and patterns. Leave this on for the usual look.");
			primaryColor = plugin.Config.Bind<string>("Customization", "PrimaryColor", "", "Fur color when profile picture is off. Example: #33AAFF");
			secondaryColor = plugin.Config.Bind<string>("Customization", "SecondaryColor", "", "Accent color when profile picture is off. Example: #101820");
			bodyPattern = plugin.Config.Bind<string>("Customization", "BodyPattern", "Profile", new ConfigDescription("Body pattern when profile picture is off. Profile keeps the generated one.", (AcceptableValueBase)(object)new AcceptableValueList<string>(BodyPatterns), Array.Empty<object>()));
			earPattern = plugin.Config.Bind<string>("Customization", "EarPattern", "Profile", new ConfigDescription("Ear pattern when profile picture is off. Profile keeps the generated one.", (AcceptableValueBase)(object)new AcceptableValueList<string>(EarPatterns), Array.Empty<object>()));
			tailPattern = plugin.Config.Bind<string>("Customization", "TailPattern", "Profile", new ConfigDescription("Tail pattern when profile picture is off. Profile keeps the generated one.", (AcceptableValueBase)(object)new AcceptableValueList<string>(TailPatterns), Array.Empty<object>()));
			plugin.Config.SettingChanged += delegate
			{
				Dirty = true;
			};
			Plugin.Log.LogInfo((object)"Customization is in the config. Profile picture colors stay the default.");
		}

		internal static Look LocalLook()
		{
			Look result = default(Look);
			result.UseProfilePicture = useProfilePicture.Value;
			result.HasPrimary = TryHex(primaryColor.Value, out result.Primary);
			result.HasSecondary = TryHex(secondaryColor.Value, out result.Secondary);
			result.Body = Match(bodyPattern.Value, BodyPatterns);
			result.Ear = Match(earPattern.Value, EarPatterns);
			result.Tail = Match(tailPattern.Value, TailPatterns);
			return result;
		}

		internal static void Remember(ulong playerId, Look look)
		{
			Looks[playerId] = look;
		}

		internal static void Rebuild(PlayerControllerB player)
		{
			if (Object.op_Implicit((Object)(object)player))
			{
				object obj = FindHandler(player);
				obj?.GetType().GetMethod("UpdateCosmetics").Invoke(obj, null);
			}
		}

		internal static ulong PlayerId(PlayerControllerB player)
		{
			if (!Object.op_Implicit((Object)(object)player))
			{
				return 0uL;
			}
			if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance) && GameNetworkManager.Instance.disableSteam)
			{
				return player.actualClientId;
			}
			return player.playerSteamId;
		}

		internal static int PackColor(bool has, Color color)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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)
			if (!has)
			{
				return -1;
			}
			int num = Mathf.Clamp(Mathf.RoundToInt(color.r * 255f), 0, 255);
			int num2 = Mathf.Clamp(Mathf.RoundToInt(color.g * 255f), 0, 255);
			int num3 = Mathf.Clamp(Mathf.RoundToInt(color.b * 255f), 0, 255);
			return num | (num2 << 8) | (num3 << 16);
		}

		internal static int PackPatterns(Look look)
		{
			return Index(BodyPatterns, look.Body) | (Index(EarPatterns, look.Ear) << 8) | (Index(TailPatterns, look.Tail) << 16);
		}

		internal static Look Unpack(bool useProfilePicture, int primary, int secondary, int patterns)
		{
			Look result = default(Look);
			result.UseProfilePicture = useProfilePicture;
			result.HasPrimary = UnpackColor(primary, out result.Primary);
			result.HasSecondary = UnpackColor(secondary, out result.Secondary);
			result.Body = BodyPatterns[Mathf.Clamp(patterns & 0xFF, 0, BodyPatterns.Length - 1)];
			result.Ear = EarPatterns[Mathf.Clamp((patterns >> 8) & 0xFF, 0, EarPatterns.Length - 1)];
			result.Tail = TailPatterns[Mathf.Clamp((patterns >> 16) & 0xFF, 0, TailPatterns.Length - 1)];
			return result;
		}

		internal static void AfterCosmetics(MonoBehaviour handler)
		{
			try
			{
				PaintIfNeeded(handler);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not apply protogen colors: " + ex.Message));
			}
		}

		private static void PaintIfNeeded(MonoBehaviour handler)
		{
			FieldInfo field = ((object)handler).GetType().GetField("player");
			PlayerControllerB val = (PlayerControllerB)((field == null) ? null : /*isinst with value type is only supported in some contexts*/);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			ulong num = PlayerId(val);
			if (!Looks.TryGetValue(num, out var value) || value.UseProfilePicture)
			{
				if (Painted.Remove(num))
				{
					Restore(num);
				}
			}
			else
			{
				Painted.Add(num);
				Paint(num, value);
			}
		}

		private static void Restore(ulong id)
		{
			object obj = TextureKit(id);
			if (obj != null)
			{
				Type type = AccessTools.TypeByName("CompanyIssuedProtogen.Protogen.ProtogenTextures");
				Write(obj, "body", (Color[])type.GetMethod("RandomizeBody").Invoke(null, new object[2] { id, obj }));
				Write(obj, "ears", (Color[])type.GetMethod("RandomizeEars").Invoke(null, new object[2] { id, obj }));
				Write(obj, "tail", (Color[])type.GetMethod("RandomizeTail").Invoke(null, new object[2] { id, obj }));
			}
		}

		private static void Paint(ulong id, Look look)
		{
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: 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_0022: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: 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)
			object obj = TextureKit(id);
			if (obj == null)
			{
				return;
			}
			bool flag = Field<bool>(obj, "isDark");
			Color val = Field<Color>(obj, "mainColor");
			Color val2 = Field<Color>(obj, "secondaryColor");
			bool dark = (look.HasPrimary && look.HasSecondary) || flag;
			Color main = (look.HasPrimary ? look.Primary : val);
			Color secondary = (look.HasSecondary ? look.Secondary : val2);
			Type type = AccessTools.TypeByName("CompanyIssuedProtogen.Protogen.ProtogenTextures");
			try
			{
				SetColors(obj, dark, main, secondary);
				Write(obj, "body", (look.Body == "Profile") ? ((Color[])type.GetMethod("RandomizeBody").Invoke(null, new object[2] { id, obj })) : PaintBody(dark, main, secondary, "fur_body_" + look.Body.ToLowerInvariant()));
				Write(obj, "ears", (look.Ear == "Profile") ? ((Color[])type.GetMethod("RandomizeEars").Invoke(null, new object[2] { id, obj })) : PaintEars(dark, main, secondary, "fur_ears_" + look.Ear.ToLowerInvariant()));
				Write(obj, "tail", (look.Tail == "Profile") ? ((Color[])type.GetMethod("RandomizeTail").Invoke(null, new object[2] { id, obj })) : PaintTail(dark, main, secondary, "fur_tail_" + look.Tail.ToLowerInvariant()));
			}
			finally
			{
				SetColors(obj, flag, val, val2);
			}
		}

		private static void SetColors(object kit, bool dark, Color main, Color secondary)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			kit.GetType().GetField("isDark").SetValue(kit, dark);
			kit.GetType().GetField("mainColor").SetValue(kit, main);
			kit.GetType().GetField("secondaryColor").SetValue(kit, secondary);
		}

		private static Color[] PaintBody(bool dark, Color main, Color secondary, string maskField)
		{
			//IL_0010: 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)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_004c: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0067: 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)
			//IL_00bd: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			Color[] array = Flat(1024, 1024, dark ? main : secondary);
			Color[] array2 = Pixels(maskField);
			Color[] array3 = Pixels("fur_body_paws");
			Color[] array4 = Pixels("fur_body_paws_detail");
			Color[] array5 = Pixels("fur_body_suit");
			Color val = (dark ? secondary : main);
			Color val2 = (dark ? Color.white : Color.black);
			Color val3 = Color.Lerp(Color.Lerp(val2, main, 0.5f), secondary, 0.25f);
			for (int i = 0; i < array.Length; i++)
			{
				if (array2 != null && i < array2.Length)
				{
					array[i] = Color.Lerp(array[i], val, 1f - array2[i].r);
				}
				if (i < array3.Length)
				{
					array[i] = Color.Lerp(array[i], val3, 1f - array3[i].r);
				}
				if (i < array4.Length)
				{
					array[i] = Color.Lerp(array[i], val2, 1f - array4[i].r);
				}
				if (i < array5.Length)
				{
					array[i] = Color.Lerp(array[i], array5[i], array5[i].a);
				}
			}
			return array;
		}

		private static Color[] PaintEars(bool dark, Color main, Color secondary, string maskField)
		{
			//IL_0010: 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)
			//IL_002f: 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)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			Color[] array = Flat(512, 512, dark ? main : secondary);
			Color[] array2 = Pixels(maskField);
			Color[] array3 = Pixels("fur_ears_inner");
			Color val = (dark ? secondary : main);
			for (int i = 0; i < array.Length; i++)
			{
				if (array2 != null && i < array2.Length)
				{
					array[i] = Color.Lerp(array[i], val, 1f - array2[i].r);
				}
				if (i < array3.Length)
				{
					array[i] = Color.Lerp(array[i], val, 1f - array3[i].r);
				}
			}
			return array;
		}

		private static Color[] PaintTail(bool dark, Color main, Color secondary, string maskField)
		{
			//IL_0010: 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)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			Color[] array = Flat(512, 512, dark ? main : secondary);
			Color[] array2 = Pixels(maskField);
			Color val = (dark ? secondary : main);
			if (array2 == null)
			{
				return array;
			}
			for (int i = 0; i < array.Length && i < array2.Length; i++)
			{
				array[i] = Color.Lerp(array[i], val, 1f - array2[i].r);
			}
			return array;
		}

		private static void Write(object kit, string fieldName, Color[] pixels)
		{
			Texture2D val = Field<Texture2D>(kit, fieldName);
			if (Object.op_Implicit((Object)(object)val) && pixels != null && ((Texture)val).width * ((Texture)val).height == pixels.Length)
			{
				val.SetPixels(pixels);
				val.Apply();
			}
		}

		private static object TextureKit(ulong id)
		{
			return AccessTools.TypeByName("CompanyIssuedProtogen.Protogen.ProtogenManager").GetMethod("GetTextureKit").Invoke(null, new object[1] { id });
		}

		private static object FindHandler(PlayerControllerB player)
		{
			object value = AccessTools.TypeByName("CompanyIssuedProtogen.Protogen.ProtogenManager").GetField("PlayerProtogens", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
			object[] array = new object[2] { player, null };
			if (!(bool)value.GetType().GetMethod("TryGetValue").Invoke(value, array))
			{
				return null;
			}
			return array[1];
		}

		private static T Field<T>(object kit, string name)
		{
			return (T)kit.GetType().GetField(name).GetValue(kit);
		}

		private static Color[] Pixels(string fieldName)
		{
			object? value = AccessTools.TypeByName("CompanyIssuedProtogen.Protogen.ProtogenPrefabs").GetField(fieldName).GetValue(null);
			Texture2D val = (Texture2D)((value is Texture2D) ? value : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return val.GetPixels();
		}

		private static Color[] Flat(int width, int height, Color color)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = color;
			}
			return array;
		}

		private static string Match(string value, string[] choices)
		{
			for (int i = 0; i < choices.Length; i++)
			{
				if (string.Equals(choices[i], value, StringComparison.OrdinalIgnoreCase))
				{
					return choices[i];
				}
			}
			return choices[0];
		}

		private static int Index(string[] choices, string value)
		{
			for (int i = 0; i < choices.Length; i++)
			{
				if (choices[i] == value)
				{
					return i;
				}
			}
			return 0;
		}

		private static bool UnpackColor(int packed, out Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			color = Color.white;
			if (packed < 0)
			{
				return false;
			}
			color = new Color((float)(packed & 0xFF) / 255f, (float)((packed >> 8) & 0xFF) / 255f, (float)((packed >> 16) & 0xFF) / 255f, 1f);
			return true;
		}

		private static bool TryHex(string text, out Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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)
			color = Color.white;
			if (string.IsNullOrWhiteSpace(text))
			{
				return false;
			}
			text = text.Trim();
			if (text.StartsWith("#"))
			{
				text = text.Substring(1);
			}
			if (text.Length == 3)
			{
				text = string.Concat(text[0], text[0], text[1], text[1], text[2], text[2]);
			}
			if (text.Length != 6)
			{
				return false;
			}
			if (!byte.TryParse(text.Substring(0, 2), NumberStyles.HexNumber, null, out var result))
			{
				return false;
			}
			if (!byte.TryParse(text.Substring(2, 2), NumberStyles.HexNumber, null, out var result2))
			{
				return false;
			}
			if (!byte.TryParse(text.Substring(4, 2), NumberStyles.HexNumber, null, out var result3))
			{
				return false;
			}
			color = new Color((float)(int)result / 255f, (float)(int)result2 / 255f, (float)(int)result3 / 255f, 1f);
			return true;
		}
	}
	public class ProtogenLookSync : NetworkBehaviour
	{
		private bool known;

		private bool asked;

		private bool sent;

		private bool useProfilePicture = true;

		private int primary = -1;

		private int secondary = -1;

		private int patterns;

		private void Update()
		{
			//IL_0050: 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)
			if (!((NetworkBehaviour)this).IsSpawned)
			{
				return;
			}
			if (((NetworkBehaviour)this).IsOwner && (Customization.Dirty || !sent))
			{
				Look look = Customization.LocalLook();
				PlayerControllerB component = ((Component)this).GetComponent<PlayerControllerB>();
				Customization.Remember(Customization.PlayerId(component), look);
				try
				{
					Customization.Rebuild(component);
					SetLookServerRpc(look.UseProfilePicture, Customization.PackColor(look.HasPrimary, look.Primary), Customization.PackColor(look.HasSecondary, look.Secondary), Customization.PackPatterns(look));
					sent = true;
					Customization.Dirty = false;
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Could not sync protogen colors: " + ex.Message));
				}
			}
			if (((NetworkBehaviour)this).IsOwner && !((NetworkBehaviour)this).IsServer && !asked)
			{
				asked = true;
				RequestLooksServerRpc();
			}
		}

		[ServerRpc]
		public void SetLookServerRpc(bool useProfilePicture, int primary, int secondary, int patterns)
		{
			this.useProfilePicture = useProfilePicture;
			this.primary = primary;
			this.secondary = secondary;
			this.patterns = patterns;
			known = true;
			SetLookClientRpc(useProfilePicture, primary, secondary, patterns);
		}

		[ClientRpc]
		public void SetLookClientRpc(bool useProfilePicture, int primary, int secondary, int patterns)
		{
			known = true;
			this.useProfilePicture = useProfilePicture;
			this.primary = primary;
			this.secondary = secondary;
			this.patterns = patterns;
			PlayerControllerB component = ((Component)this).GetComponent<PlayerControllerB>();
			Customization.Remember(Customization.PlayerId(component), Customization.Unpack(useProfilePicture, primary, secondary, patterns));
			Customization.Rebuild(component);
		}

		[ServerRpc]
		public void RequestLooksServerRpc()
		{
			if (!Object.op_Implicit((Object)(object)StartOfRound.Instance))
			{
				return;
			}
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			for (int i = 0; i < allPlayerScripts.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)allPlayerScripts[i]))
				{
					ProtogenLookSync component = ((Component)allPlayerScripts[i]).GetComponent<ProtogenLookSync>();
					if ((Object)(object)component != (Object)null && component.known)
					{
						component.SetLookClientRpc(component.useProfilePicture, component.primary, component.secondary, component.patterns);
					}
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class CosmeticPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method("CompanyIssuedProtogen.Protogen.ProtogenHandler:UpdateCosmetics", (Type[])null, (Type[])null);
		}

		private static void Postfix(MonoBehaviour __instance)
		{
			Customization.AfterCosmetics(__instance);
		}
	}
	[BepInPlugin("Updatedprotogen.Command", "Updatedprotogen", "1.1.14")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private static readonly Harmony Harmony = new Harmony("Updatedprotogen.Command");

		private void Awake()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0064: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Customization.Bind((BaseUnityPlugin)(object)this);
			Harmony.PatchAll(typeof(Plugin).Assembly);
			MethodInfo methodInfo = AccessTools.Method("CompanyIssuedProtogen.Plugin:PollToggle", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				Harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin), "SkipKeybind", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			NetcodeValidator val = new NetcodeValidator("Updatedprotogen.Command");
			val.PatchAll();
			val.BindToPreExistingObjectByBehaviour<ProtogenLookSync, PlayerControllerB>();
			Log.LogInfo((object)"Type protogen in the terminal to toggle it.");
		}

		private static bool SkipKeybind()
		{
			return false;
		}

		internal static bool TryToggle(out bool enabled)
		{
			enabled = false;
			if (!Object.op_Implicit((Object)(object)GameNetworkManager.Instance) || !Object.op_Implicit((Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				return false;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			Type type = Type.GetType("CompanyIssuedProtogen.Protogen.ProtogenSync, Updatedprotogen");
			Type type2 = Type.GetType("CompanyIssuedProtogen.Protogen.ProtogenManager, Updatedprotogen");
			if (type == null || type2 == null)
			{
				return false;
			}
			Component component = ((Component)localPlayerController).GetComponent(type);
			if (!Object.op_Implicit((Object)(object)component))
			{
				return false;
			}
			FieldInfo? field = type.GetField("Enabled");
			bool flag = !(bool)field.GetValue(component);
			field.SetValue(component, flag);
			type2.GetMethod("Apply").Invoke(null, new object[2] { localPlayerController, flag });
			enabled = flag;
			NetworkBehaviour val = (NetworkBehaviour)(object)((component is NetworkBehaviour) ? component : null);
			if ((Object)(object)val != (Object)null && val.IsSpawned)
			{
				try
				{
					type.GetMethod("SetEnabledServerRpc").Invoke(component, new object[1] { flag });
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("Could not sync the protogen toggle: " + ex.Message));
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Terminal), "OnSubmit")]
	internal static class TerminalPatch
	{
		private static TerminalNode response;

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool Prefix(Terminal __instance)
		{
			if (!__instance.terminalInUse || __instance.textAdded <= 0 || (Object)(object)__instance.screenText == (Object)null)
			{
				return true;
			}
			string text = __instance.screenText.text;
			int num = text.Length - __instance.textAdded;
			if (num < 0 || !IsProtogenCommand(text.Substring(num)))
			{
				return true;
			}
			bool enabled;
			string line = ((!Plugin.TryToggle(out enabled)) ? "Protogen unavailable.\n\n" : (enabled ? "Protogen online.\n\n" : "Protogen offline.\n\n"));
			__instance.LoadNewNode(Response(line));
			__instance.screenText.ActivateInputField();
			((Selectable)__instance.screenText).Select();
			return false;
		}

		private static bool IsProtogenCommand(string typed)
		{
			StringBuilder stringBuilder = new StringBuilder(typed.Length);
			foreach (char c in typed)
			{
				if (!char.IsPunctuation(c))
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.ToString().Trim().ToLowerInvariant() == "protogen";
		}

		private static TerminalNode Response(string line)
		{
			if ((Object)(object)response == (Object)null)
			{
				response = ScriptableObject.CreateInstance<TerminalNode>();
				response.clearPreviousText = false;
				response.terminalEvent = "";
				response.maxCharactersToType = 25;
			}
			response.displayText = line;
			return response;
		}
	}
	[HarmonyPatch]
	internal static class ViewmodelFix
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method("CompanyIssuedProtogen.Protogen.ProtogenHandler:LateUpdate", (Type[])null, (Type[])null);
		}

		private static void Postfix(MonoBehaviour __instance)
		{
			FieldInfo field = ((object)__instance).GetType().GetField("armsRenderer", BindingFlags.Instance | BindingFlags.NonPublic);
			FieldInfo field2 = ((object)__instance).GetType().GetField("player", BindingFlags.Instance | BindingFlags.Public);
			if (field == null || field2 == null)
			{
				return;
			}
			object? value = field.GetValue(__instance);
			Renderer val = (Renderer)((value is Renderer) ? value : null);
			object? value2 = field2.GetValue(__instance);
			PlayerControllerB val2 = (PlayerControllerB)((value2 is PlayerControllerB) ? value2 : null);
			if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.thisPlayerModelArms) && val.enabled)
			{
				int layer = ((Component)val2.thisPlayerModelArms).gameObject.layer;
				((Component)val).gameObject.layer = layer;
				Transform parent = ((Component)val).transform.parent;
				if (Object.op_Implicit((Object)(object)parent))
				{
					((Component)parent).gameObject.layer = layer;
				}
				SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null);
				if (Object.op_Implicit((Object)(object)val3))
				{
					val3.updateWhenOffscreen = true;
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class ViewmodelScaleFix
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method("CompanyIssuedProtogen.Protogen.ProtogenArmDriver:LateUpdate", (Type[])null, (Type[])null);
		}

		private static void Postfix(MonoBehaviour __instance)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			FieldInfo field = ((object)__instance).GetType().GetField("viewBones", BindingFlags.Instance | BindingFlags.Public);
			FieldInfo field2 = ((object)__instance).GetType().GetField("sources", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field == null || field2 == null)
			{
				return;
			}
			Transform[] array = field.GetValue(__instance) as Transform[];
			Transform[] array2 = field2.GetValue(__instance) as Transform[];
			if (array == null || array2 == null)
			{
				return;
			}
			int num = Math.Min(array.Length, array2.Length);
			for (int i = 0; i < num; i++)
			{
				Transform val = array[i];
				Transform val2 = array2[i];
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2))
				{
					Vector3 val3 = (Object.op_Implicit((Object)(object)val.parent) ? val.parent.lossyScale : Vector3.one);
					Vector3 lossyScale = val2.lossyScale;
					val.localScale = new Vector3(Divide(lossyScale.x, val3.x), Divide(lossyScale.y, val3.y), Divide(lossyScale.z, val3.z));
					val.SetPositionAndRotation(val2.position, val2.rotation);
				}
			}
		}

		private static float Divide(float value, float parent)
		{
			if (Mathf.Abs(parent) < 0.0001f)
			{
				return 1f;
			}
			return value / parent;
		}
	}
	[HarmonyPatch]
	internal static class VisibilityFix
	{
		private static bool logged;

		private static MethodBase TargetMethod()
		{
			return AccessTools.Method("CompanyIssuedProtogen.Protogen.ProtogenHandler:LateUpdate", (Type[])null, (Type[])null);
		}

		private static void Postfix(MonoBehaviour __instance)
		{
			FieldInfo field = ((object)__instance).GetType().GetField("player");
			PlayerControllerB val = (PlayerControllerB)((field == null) ? null : /*isinst with value type is only supported in some contexts*/);
			if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.thisPlayerModel))
			{
				bool num = Field<bool>(__instance, "isAttached");
				Renderer val2 = RendererOf(__instance, "bodyRenderer");
				bool flag = Object.op_Implicit((Object)(object)GameNetworkManager.Instance) && (Object)(object)val == (Object)(object)GameNetworkManager.Instance.localPlayerController;
				bool flag2 = num && flag && Object.op_Implicit((Object)(object)val2) && !val2.enabled && !val.isPlayerDead;
				int layer = (flag2 ? ((Component)val.thisPlayerModel).gameObject.layer : VisibleLayer(val));
				Place(__instance, "bodyRenderer", layer, flag2);
				Place(__instance, "earsRenderer", layer, flag2);
				Place(__instance, "tailRenderer", layer, flag2);
				Place(__instance, "tankRenderer", layer, flag2);
				Renderer val3 = RendererOf(__instance, "armsRenderer");
				if (Object.op_Implicit((Object)(object)val3))
				{
					val3.shadowCastingMode = (ShadowCastingMode)0;
				}
				if (!logged)
				{
					logged = true;
					Plugin.Log.LogInfo((object)"Other protogens stay visible in first person.");
				}
			}
		}

		private static int VisibleLayer(PlayerControllerB player)
		{
			int layer = ((Component)player.thisPlayerModel).gameObject.layer;
			Camera val = null;
			if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance) && Object.op_Implicit((Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				val = GameNetworkManager.Instance.localPlayerController.gameplayCamera;
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				if (layer != 23)
				{
					return layer;
				}
				return 0;
			}
			if ((val.cullingMask & (1 << layer)) != 0)
			{
				return layer;
			}
			for (int i = 0; i < 32; i++)
			{
				if ((val.cullingMask & (1 << i)) != 0)
				{
					return i;
				}
			}
			return 0;
		}

		private static void Place(MonoBehaviour handler, string fieldName, int layer, bool shadowOnly)
		{
			Renderer val = RendererOf(handler, fieldName);
			if (Object.op_Implicit((Object)(object)val))
			{
				((Component)val).gameObject.layer = layer;
				val.shadowCastingMode = (ShadowCastingMode)((!shadowOnly) ? 1 : 3);
				if (shadowOnly)
				{
					val.enabled = true;
				}
				SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null);
				if (Object.op_Implicit((Object)(object)val2))
				{
					val2.updateWhenOffscreen = true;
				}
			}
		}

		private static Renderer RendererOf(MonoBehaviour handler, string fieldName)
		{
			FieldInfo field = ((object)handler).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field == null))
			{
				object? value = field.GetValue(handler);
				return (Renderer)((value is Renderer) ? value : null);
			}
			return null;
		}

		private static T Field<T>(MonoBehaviour handler, string fieldName)
		{
			FieldInfo field = ((object)handler).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field == null))
			{
				return (T)field.GetValue(handler);
			}
			return default(T);
		}
	}
}