Decompiled source of SquadPlayermodels v0.2.0

plugins/SquadPlayermodels.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using Microsoft.CodeAnalysis;
using ModelReplacement;
using ModelReplacement.AvatarBodyUpdater;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SquadPlayermodels")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+82e8ffefbf7e7576f783034961019a242e6e6c5c")]
[assembly: AssemblyProduct("SquadPlayermodels")]
[assembly: AssemblyTitle("SquadPlayermodels")]
[assembly: AssemblyVersion("0.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 SquadPlayermodels
{
	internal sealed class AutoTest : MonoBehaviour
	{
		private string _outDir = "";

		private bool _hosted;

		private bool _captured;

		private bool _choseLaunch;

		public static void StartIfRequested()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (Environment.GetEnvironmentVariable("SQUADPM_AUTOTEST") == "1" || File.Exists(Path.Combine(Paths.ConfigPath, "SquadPlayermodels.autotest")))
			{
				GameObject val = new GameObject("SquadPlayermodels.AutoTest");
				Object.DontDestroyOnLoad((Object)val);
				((Object)val).hideFlags = (HideFlags)61;
				val.AddComponent<AutoTest>();
			}
		}

		private void Awake()
		{
			_outDir = Path.Combine(Paths.BepInExRootPath, "SquadAutotest");
			Directory.CreateDirectory(_outDir);
			Plugin.Log.LogWarning((object)("AUTOTEST enabled, writing to " + _outDir));
			SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode _)
			{
				((MonoBehaviour)this).StartCoroutine(OnScene(((Scene)(ref scene)).name));
			};
			((MonoBehaviour)this).StartCoroutine(Timeout());
		}

		private IEnumerator Timeout()
		{
			yield return (object)new WaitForSecondsRealtime(900f);
			Plugin.Log.LogError((object)"AUTOTEST timed out");
			Application.Quit();
		}

		private IEnumerator OnScene(string scene)
		{
			Plugin.Log.LogInfo((object)("AUTOTEST scene " + scene));
			yield return (object)new WaitForSecondsRealtime(1.5f);
			if (!_choseLaunch)
			{
				PreInitSceneScript val = Object.FindObjectOfType<PreInitSceneScript>();
				if (val != null)
				{
					_choseLaunch = true;
					val.ChooseLaunchOption(false);
					yield break;
				}
			}
			if (!_hosted)
			{
				MenuManager menu = Object.FindObjectOfType<MenuManager>();
				if (menu != null && !menu.isInitScene)
				{
					_hosted = true;
					yield return (object)new WaitForSecondsRealtime(1.5f);
					menu.lobbyNameInputField.text = "squadpm-autotest";
					menu.ConfirmHostButton();
					yield break;
				}
			}
			if (!_captured && scene == "SampleSceneRelay")
			{
				_captured = true;
				yield return Capture();
			}
		}

		private IEnumerator Capture()
		{
			PlayerControllerB player = null;
			while ((Object)(object)player == (Object)null || !player.isPlayerControlled)
			{
				player = StartOfRound.Instance?.localPlayerController;
				yield return (object)new WaitForSecondsRealtime(0.5f);
			}
			yield return (object)new WaitForSecondsRealtime(3f);
			SkinnedMeshRenderer thisPlayerModel = player.thisPlayerModel;
			Plugin.Log.LogInfo((object)("AUTOTEST player bones: " + string.Join(", ", thisPlayerModel.bones.Select((Transform b) => (!Object.op_Implicit((Object)(object)b)) ? "null" : ((Object)b).name))));
			Plugin.Log.LogInfo((object)$"AUTOTEST player renderer scale {((Component)thisPlayerModel).transform.lossyScale}, material {((Object)((Renderer)thisPlayerModel).sharedMaterial.shader).name}");
			((Component)player).transform.Rotate(0f, 90f, 0f);
			yield return null;
			Shot(player, "vanilla_front", 0f, 0.55f);
			yield return null;
			List<UnlockableItem> suits = StartOfRound.Instance.unlockablesList.unlockables;
			string suitName = Plugin.Models[0].Suit;
			int num = suits.FindIndex((UnlockableItem u) => u.unlockableName == suitName);
			Plugin.Log.LogInfo((object)$"AUTOTEST suit '{suitName}' id {num}");
			if (num < 0)
			{
				Plugin.Log.LogError((object)("AUTOTEST suit not found. Suits: " + string.Join(", ", suits.Select((UnlockableItem u) => u.unlockableName))));
				Application.Quit();
				yield break;
			}
			UnlockableSuit.SwitchSuitForPlayer(player, num, false);
			yield return (object)new WaitForSecondsRealtime(4f);
			(string, float, float)[] array = new(string, float, float)[5]
			{
				("front", 0f, 0.55f),
				("side", 90f, 0.55f),
				("back", 180f, 0.55f),
				("threequarter", 35f, 0.55f),
				("face", 15f, 1f)
			};
			for (int num2 = 0; num2 < array.Length; num2++)
			{
				var (text, angle, height) = array[num2];
				Shot(player, text, angle, height, (text == "face") ? 0.45f : 1.9f);
				yield return null;
			}
			player.Crouch(true);
			yield return (object)new WaitForSecondsRealtime(1.5f);
			Shot(player, "crouch_side", 70f, 0.4f);
			player.Crouch(false);
			yield return (object)new WaitForSecondsRealtime(1f);
			player.performingEmote = true;
			player.playerBodyAnimator.SetInteger("emoteNumber", 1);
			player.StartPerformingEmoteServerRpc();
			yield return (object)new WaitForSecondsRealtime(1.2f);
			Shot(player, "emote_front", 20f, 0.55f);
			player.performingEmote = false;
			player.playerBodyAnimator.SetInteger("emoteNumber", 0);
			yield return (object)new WaitForSecondsRealtime(1f);
			foreach (ModelDefinition def in Plugin.Models)
			{
				int num3 = suits.FindIndex((UnlockableItem u) => u.unlockableName == def.Suit);
				if (num3 < 0)
				{
					Plugin.Log.LogError((object)("AUTOTEST suit '" + def.Suit + "' not found"));
					continue;
				}
				UnlockableSuit.SwitchSuitForPlayer(player, num3, false);
				yield return (object)new WaitForSecondsRealtime(1.5f);
				Shot(player, "model_" + def.Id, 20f, 0.55f);
			}
			File.WriteAllText(Path.Combine(_outDir, "done.txt"), DateTime.Now.ToString("O"));
			Plugin.Log.LogWarning((object)"AUTOTEST finished");
			yield return (object)new WaitForSecondsRealtime(1f);
			Application.Quit();
		}

		private void Shot(PlayerControllerB player, string name, float angle, float height, float distance = 1.9f)
		{
			//IL_004d: 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_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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Expected O, but got Unknown
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Expected O, but got Unknown
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)player).transform;
			Transform val = ((IEnumerable<Transform>)player.thisPlayerModel.bones).FirstOrDefault((Func<Transform, bool>)((Transform b) => (Object)(object)b != (Object)null && ((Object)b).name == "spine.004"));
			float num = (((Object)(object)val != (Object)null) ? Mathf.Max(0.5f, val.position.y - transform.position.y) : 2f);
			Vector3 val2 = transform.position + Vector3.up * (height * num);
			distance *= num;
			Vector3 val3 = Quaternion.AngleAxis(angle, Vector3.up) * transform.forward;
			List<Renderer> list = new List<Renderer>();
			GameObject val4 = GameObject.Find("Systems/Rendering/PlayerHUDHelmetModel");
			if ((Object)(object)val4 != (Object)null)
			{
				list.AddRange(val4.GetComponentsInChildren<Renderer>());
			}
			if ((Object)(object)player.thisPlayerModelArms != (Object)null)
			{
				list.Add((Renderer)(object)player.thisPlayerModelArms);
			}
			BodyReplacementBase component = ((Component)player).GetComponent<BodyReplacementBase>();
			if (component != null)
			{
				GameObject replacementViewModel = component.replacementViewModel;
				if (replacementViewModel != null)
				{
					list.AddRange(replacementViewModel.GetComponentsInChildren<Renderer>());
				}
			}
			list = list.Where((Renderer x) => x.enabled).ToList();
			foreach (Renderer item in list)
			{
				item.enabled = false;
			}
			GameObject val5 = new GameObject("AutoTestCamera");
			try
			{
				val5.transform.position = val2 + val3 * distance + Vector3.up * (0.08f * num);
				val5.transform.LookAt(val2);
				Camera val6 = val5.AddComponent<Camera>();
				val5.AddComponent<HDAdditionalCameraData>();
				val6.fieldOfView = 45f;
				val6.nearClipPlane = 0.05f;
				int num2 = player.gameplayCamera.cullingMask | (1 << ((Component)player.thisPlayerModel).gameObject.layer);
				component = ((Component)player).GetComponent<BodyReplacementBase>();
				if (component != null)
				{
					GameObject replacementModel = component.replacementModel;
					if (replacementModel != null)
					{
						Renderer[] componentsInChildren = replacementModel.GetComponentsInChildren<Renderer>();
						foreach (Renderer val7 in componentsInChildren)
						{
							num2 |= 1 << ((Component)val7).gameObject.layer;
						}
					}
				}
				val6.cullingMask = num2;
				RenderTexture val8 = (val6.targetTexture = new RenderTexture(960, 1080, 24, (RenderTextureFormat)0));
				val6.Render();
				RenderTexture active = RenderTexture.active;
				RenderTexture.active = val8;
				Texture2D val10 = new Texture2D(960, 1080, (TextureFormat)3, false);
				val10.ReadPixels(new Rect(0f, 0f, 960f, 1080f), 0, 0);
				val10.Apply();
				RenderTexture.active = active;
				File.WriteAllBytes(Path.Combine(_outDir, name + ".png"), ImageConversion.EncodeToPNG(val10));
				val6.targetTexture = null;
				Object.Destroy((Object)(object)val10);
				val8.Release();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"AUTOTEST shot {name} failed: {arg}");
			}
			finally
			{
				Object.Destroy((Object)(object)val5);
				foreach (Renderer item2 in list)
				{
					item2.enabled = true;
				}
			}
		}
	}
	internal static class ModelBuilder
	{
		private static readonly Dictionary<HumanBodyBones, string> SquadHumanoid = BuildSquadHumanoidMap();

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

		private static readonly (HumanBodyBones bone, HumanBodyBones target, string lcBone, string lcTarget)[] PoseChain = new(HumanBodyBones, HumanBodyBones, string, string)[27]
		{
			((HumanBodyBones)7, (HumanBodyBones)8, "spine.001", "spine.002"),
			((HumanBodyBones)8, (HumanBodyBones)54, "spine.002", "spine.003"),
			((HumanBodyBones)54, (HumanBodyBones)9, "spine.003", "spine.004"),
			((HumanBodyBones)1, (HumanBodyBones)3, "thigh.L", "shin.L"),
			((HumanBodyBones)3, (HumanBodyBones)5, "shin.L", "foot.L"),
			((HumanBodyBones)5, (HumanBodyBones)19, "foot.L", "toe.L"),
			((HumanBodyBones)2, (HumanBodyBones)4, "thigh.R", "shin.R"),
			((HumanBodyBones)4, (HumanBodyBones)6, "shin.R", "foot.R"),
			((HumanBodyBones)6, (HumanBodyBones)20, "foot.R", "toe.R"),
			((HumanBodyBones)11, (HumanBodyBones)13, "shoulder.L", "arm.L_upper"),
			((HumanBodyBones)13, (HumanBodyBones)15, "arm.L_upper", "arm.L_lower"),
			((HumanBodyBones)15, (HumanBodyBones)17, "arm.L_lower", "hand.L"),
			((HumanBodyBones)17, (HumanBodyBones)30, "hand.L", "finger3.L"),
			((HumanBodyBones)24, (HumanBodyBones)25, "finger1.L", "finger1.L.001"),
			((HumanBodyBones)27, (HumanBodyBones)28, "finger2.L", "finger2.L.001"),
			((HumanBodyBones)30, (HumanBodyBones)31, "finger3.L", "finger3.L.001"),
			((HumanBodyBones)33, (HumanBodyBones)34, "finger4.L", "finger4.L.001"),
			((HumanBodyBones)36, (HumanBodyBones)37, "finger5.L", "finger5.L.001"),
			((HumanBodyBones)12, (HumanBodyBones)14, "shoulder.R", "arm.R_upper"),
			((HumanBodyBones)14, (HumanBodyBones)16, "arm.R_upper", "arm.R_lower"),
			((HumanBodyBones)16, (HumanBodyBones)18, "arm.R_lower", "hand.R"),
			((HumanBodyBones)18, (HumanBodyBones)45, "hand.R", "finger3.R"),
			((HumanBodyBones)39, (HumanBodyBones)40, "finger1.R", "finger1.R.001"),
			((HumanBodyBones)42, (HumanBodyBones)43, "finger2.R", "finger2.R.001"),
			((HumanBodyBones)45, (HumanBodyBones)46, "finger3.R", "finger3.R.001"),
			((HumanBodyBones)48, (HumanBodyBones)49, "finger4.R", "finger4.R.001"),
			((HumanBodyBones)51, (HumanBodyBones)52, "finger5.R", "finger5.R.001")
		};

		private static readonly Dictionary<string, Texture2D> TextureCache = new Dictionary<string, Texture2D>();

		public static GameObject Build(ModelDefinition def, SkinnedMeshRenderer playerRenderer)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Expected O, but got Unknown
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_047c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0563: Unknown result type (might be due to invalid IL or missing references)
			//IL_0568: Unknown result type (might be due to invalid IL or missing references)
			LcRestPose lcRestPose = LcRestPose.FromRenderer(playerRenderer);
			SqpmFile file = SqpmFile.Load(Path.Combine(def.Folder, def.Mesh));
			GameObject val = new GameObject("SquadModel_" + def.Id);
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			Transform transform = new GameObject("Armature").transform;
			transform.SetParent(val.transform, false);
			Transform[] array = (Transform[])(object)new Transform[file.BoneNames.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new GameObject(file.BoneNames[i]).transform;
			}
			for (int j = 0; j < array.Length; j++)
			{
				int num = file.BoneParents[j];
				array[j].SetParent((num >= 0) ? array[num] : transform, false);
				array[j].localPosition = file.BonePositions[j];
				array[j].localRotation = file.BoneRotations[j];
				array[j].localScale = file.BoneScales[j];
			}
			Dictionary<string, Transform> byName = array.ToDictionary((Transform b) => ((Object)b).name, (Transform b) => b);
			Dictionary<string, MaterialDefinition> mats = (from m in def.Materials
				group m by m.Name).ToDictionary((IGrouping<string, MaterialDefinition> g) => g.Key, (IGrouping<string, MaterialDefinition> g) => g.First());
			MaterialDefinition value2;
			List<int> list = (from s in Enumerable.Range(0, file.SubmeshMaterials.Length)
				where !mats.TryGetValue(file.SubmeshMaterials[s], out value2) || !value2.Hidden
				select s).ToList();
			Mesh val2 = new Mesh
			{
				name = def.Id,
				indexFormat = (IndexFormat)1
			};
			val2.vertices = file.Positions;
			val2.normals = file.Normals;
			val2.uv = file.UVs;
			val2.boneWeights = file.Weights;
			val2.bindposes = file.BindPoses;
			val2.subMeshCount = list.Count;
			for (int num2 = 0; num2 < list.Count; num2++)
			{
				val2.SetTriangles(file.SubmeshIndices[list[num2]], num2, false);
			}
			val2.RecalculateTangents();
			val2.RecalculateBounds();
			val2.UploadMeshData(true);
			GameObject val3 = new GameObject("Body");
			val3.transform.SetParent(transform, false);
			SkinnedMeshRenderer obj = val3.AddComponent<SkinnedMeshRenderer>();
			obj.sharedMesh = val2;
			obj.bones = array;
			obj.rootBone = H((HumanBodyBones)0);
			((Renderer)obj).sharedMaterials = list.Select((int s) => CreateMaterial(def, mats.TryGetValue(file.SubmeshMaterials[s], out value2) ? value2 : null, ((Renderer)playerRenderer).sharedMaterial)).ToArray();
			obj.updateWhenOffscreen = true;
			((Renderer)obj).forceRenderingOff = true;
			Vector3 up = Local(val, H((HumanBodyBones)10)) - Local(val, H((HumanBodyBones)0));
			Vector3 right = Local(val, H((HumanBodyBones)14)) - Local(val, H((HumanBodyBones)13));
			transform.localRotation = Basis(lcRestPose.Right, lcRestPose.Up) * Quaternion.Inverse(Basis(right, up));
			(HumanBodyBones, HumanBodyBones, string, string)[] poseChain = PoseChain;
			for (int num3 = 0; num3 < poseChain.Length; num3++)
			{
				var (hb, hb2, bone, bone2) = poseChain[num3];
				if (lcRestPose.Has(bone) && lcRestPose.Has(bone2))
				{
					Transform val4 = H(hb);
					Vector3 val5 = Local(val, H(hb2)) - Local(val, val4);
					Vector3 val6 = lcRestPose.Position(bone2) - lcRestPose.Position(bone);
					if (!(((Vector3)(ref val5)).sqrMagnitude < 1E-10f) && !(((Vector3)(ref val6)).sqrMagnitude < 1E-10f))
					{
						val4.rotation = Quaternion.FromToRotation(val5, val6) * val4.rotation;
					}
				}
			}
			Animator obj2 = val.AddComponent<Animator>();
			obj2.avatar = BuildAvatar(val);
			obj2.cullingMode = (AnimatorCullingMode)0;
			foreach (KeyValuePair<string, HumanBodyBones> item in LcHumanoid)
			{
				if (lcRestPose.Has(item.Key) && SquadHumanoid.TryGetValue(item.Value, out string value))
				{
					Transform val7 = byName[value];
					(((Component)val7).gameObject.GetComponent<RotationOffset>() ?? ((Component)val7).gameObject.AddComponent<RotationOffset>()).offset = Quaternion.Inverse(lcRestPose.Rotation(item.Key)) * val7.rotation;
				}
			}
			SquadModelInfo squadModelInfo = val.AddComponent<SquadModelInfo>();
			Vector3 val8 = (Local(val, H((HumanBodyBones)5)) + Local(val, H((HumanBodyBones)6))) * 0.5f;
			squadModelInfo.HeadHeight = Vector3.Dot(Local(val, H((HumanBodyBones)10)) - val8, lcRestPose.Up);
			squadModelInfo.HipsHeight = Vector3.Dot(Local(val, H((HumanBodyBones)0)) - val8, lcRestPose.Up);
			squadModelInfo.ModelId = def.Id;
			val.AddComponent<OffsetBuilder>().GenerateViewModel = Plugin.FirstPersonArms.Value;
			val.transform.position = new Vector3(0f, -2000f, 0f);
			val.SetActive(true);
			return val;
			Transform H(HumanBodyBones key)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				return byName[SquadHumanoid[key]];
			}
		}

		private static Vector3 Local(GameObject root, Transform t)
		{
			//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)
			return root.transform.InverseTransformPoint(t.position);
		}

		private static Quaternion Basis(Vector3 right, Vector3 up)
		{
			//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_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)
			return Quaternion.LookRotation(Vector3.Cross(right, up), up);
		}

		private static Avatar BuildAvatar(GameObject root)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			SkeletonBone[] skeleton = ((IEnumerable<Transform>)root.GetComponentsInChildren<Transform>(true)).Select((Func<Transform, SkeletonBone>)((Transform t) => new SkeletonBone
			{
				name = ((Object)t).name,
				position = t.localPosition,
				rotation = t.localRotation,
				scale = t.localScale
			})).ToArray();
			string[] humanNames = HumanTrait.BoneName;
			HumanBone[] human = SquadHumanoid.Select<KeyValuePair<HumanBodyBones, string>, HumanBone>(delegate(KeyValuePair<HumanBodyBones, string> kv)
			{
				//IL_0002: 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_002f: 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)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				HumanBone result = default(HumanBone);
				((HumanBone)(ref result)).humanName = humanNames[kv.Key];
				((HumanBone)(ref result)).boneName = kv.Value;
				HumanLimit limit = default(HumanLimit);
				((HumanLimit)(ref limit)).useDefaultValues = true;
				result.limit = limit;
				return result;
			}).ToArray();
			HumanDescription val = new HumanDescription
			{
				skeleton = skeleton,
				human = human
			};
			((HumanDescription)(ref val)).upperArmTwist = 0.5f;
			((HumanDescription)(ref val)).lowerArmTwist = 0.5f;
			((HumanDescription)(ref val)).upperLegTwist = 0.5f;
			((HumanDescription)(ref val)).lowerLegTwist = 0.5f;
			((HumanDescription)(ref val)).armStretch = 0.05f;
			((HumanDescription)(ref val)).legStretch = 0.05f;
			((HumanDescription)(ref val)).feetSpacing = 0f;
			((HumanDescription)(ref val)).hasTranslationDoF = false;
			HumanDescription val2 = val;
			Avatar val3 = AvatarBuilder.BuildHumanAvatar(root, val2);
			((Object)val3).name = ((Object)root).name + "Avatar";
			if (!val3.isValid || !val3.isHuman)
			{
				Plugin.Log.LogError((object)$"Humanoid avatar for {((Object)root).name} is invalid (valid={val3.isValid}, human={val3.isHuman})");
			}
			return val3;
		}

		private static Material CreateMaterial(ModelDefinition def, MaterialDefinition? md, Material playerMaterial)
		{
			//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_0022: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(playerMaterial)
			{
				name = (md?.Name ?? "SquadDefault")
			};
			string[] array = new string[6] { "_DetailMap", "_EmissiveColorMap", "_BentNormalMap", "_SpecularColorMap", "_ThicknessMap", "_CoatMaskMap" };
			foreach (string text in array)
			{
				if (val.HasProperty(text))
				{
					val.SetTexture(text, (Texture)null);
				}
			}
			if (val.HasProperty("_EmissiveColor"))
			{
				val.SetColor("_EmissiveColor", Color.black);
			}
			val.DisableKeyword("_DETAIL_MAP");
			val.DisableKeyword("_EMISSIVE_COLOR_MAP");
			if (md == null)
			{
				md = new MaterialDefinition();
			}
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(md.Color[0], md.Color[1], md.Color[2], (md.Color.Length > 3) ? md.Color[3] : 1f);
			val.SetColor("_BaseColor", val2);
			val.color = val2;
			Texture2D val3 = (Texture2D)((md.Albedo != null) ? ((object)LoadTexture(def, md.Albedo, linear: false)) : ((object)Texture2D.whiteTexture));
			val.SetTexture("_BaseColorMap", (Texture)(object)val3);
			val.mainTexture = (Texture)(object)val3;
			val.SetTextureScale("_BaseColorMap", Vector2.one);
			val.SetTextureOffset("_BaseColorMap", Vector2.zero);
			if (md.Normal != null)
			{
				val.SetTexture("_NormalMap", (Texture)(object)LoadTexture(def, md.Normal, linear: true));
				val.SetFloat("_NormalScale", 1f);
				val.EnableKeyword("_NORMALMAP");
				val.EnableKeyword("_NORMALMAP_TANGENT_SPACE");
			}
			else
			{
				val.SetTexture("_NormalMap", (Texture)null);
				val.DisableKeyword("_NORMALMAP");
			}
			if (md.Mask != null)
			{
				val.SetTexture("_MaskMap", (Texture)(object)LoadTexture(def, md.Mask, linear: true));
				val.EnableKeyword("_MASKMAP");
				val.SetFloat("_MetallicRemapMin", 0f);
				val.SetFloat("_MetallicRemapMax", md.Metallic);
				val.SetFloat("_SmoothnessRemapMin", 0f);
				val.SetFloat("_SmoothnessRemapMax", md.Smoothness);
				val.SetFloat("_AORemapMin", 0f);
				val.SetFloat("_AORemapMax", 1f);
			}
			else
			{
				val.SetTexture("_MaskMap", (Texture)null);
				val.DisableKeyword("_MASKMAP");
				val.SetFloat("_Metallic", md.Metallic);
				val.SetFloat("_Smoothness", md.Smoothness);
			}
			val.SetFloat("_AlphaCutoffEnable", md.Cutout ? 1f : 0f);
			val.SetFloat("_AlphaCutoff", 0.5f);
			if (md.Cutout)
			{
				val.EnableKeyword("_ALPHATEST_ON");
			}
			else
			{
				val.DisableKeyword("_ALPHATEST_ON");
			}
			val.SetFloat("_DoubleSidedEnable", md.DoubleSided ? 1f : 0f);
			val.SetFloat("_CullMode", md.DoubleSided ? 0f : 2f);
			val.SetFloat("_CullModeForward", md.DoubleSided ? 0f : 2f);
			val.doubleSidedGI = md.DoubleSided;
			HDMaterial.ValidateMaterial(val);
			return val;
		}

		private static Texture2D LoadTexture(ModelDefinition def, string file, bool linear)
		{
			//IL_0047: 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_0059: Expected O, but got Unknown
			string fullPath = Path.GetFullPath(Path.Combine(def.Folder, file));
			string key = fullPath + (linear ? "|lin" : "|srgb");
			if (TextureCache.TryGetValue(key, out Texture2D value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
			{
				name = Path.GetFileNameWithoutExtension(file)
			};
			if (!ImageConversion.LoadImage(val, File.ReadAllBytes(fullPath), false))
			{
				Plugin.Log.LogError((object)("Could not load texture " + fullPath));
				return Texture2D.whiteTexture;
			}
			((Texture)val).wrapMode = (TextureWrapMode)0;
			((Texture)val).filterMode = (FilterMode)2;
			((Texture)val).anisoLevel = 4;
			val.Compress(true);
			val.Apply(true, true);
			Object.DontDestroyOnLoad((Object)(object)val);
			TextureCache[key] = val;
			return val;
		}

		private static Dictionary<HumanBodyBones, string> BuildSquadHumanoidMap()
		{
			Dictionary<HumanBodyBones, string> map = new Dictionary<HumanBodyBones, string>
			{
				[(HumanBodyBones)0] = "Bip01_Pelvis",
				[(HumanBodyBones)7] = "Bip01_Spine",
				[(HumanBodyBones)8] = "Bip01_Spine1",
				[(HumanBodyBones)54] = "Bip01_Spine2",
				[(HumanBodyBones)9] = "Bip01_Neck",
				[(HumanBodyBones)10] = "Bip01_Head"
			};
			(string, string)[] array = new(string, string)[2]
			{
				("Left", "L"),
				("Right", "R")
			};
			for (int i = 0; i < array.Length; i++)
			{
				var (side, s) = array[i];
				Add("UpperLeg", "Thigh");
				Add("LowerLeg", "Calf");
				Add("Foot", "Foot");
				Add("Toes", "Toe0");
				Add("Shoulder", "Clavicle");
				Add("UpperArm", "UpperArm");
				Add("LowerArm", "Forearm");
				Add("Hand", "Hand");
				string[] array2 = new string[5] { "Thumb", "Index", "Middle", "Ring", "Little" };
				string[] array3 = new string[3] { "Proximal", "Intermediate", "Distal" };
				for (int j = 0; j < 5; j++)
				{
					for (int k = 0; k < 3; k++)
					{
						Add(array2[j] + array3[k], (k == 0) ? $"Finger{j}" : $"Finger{j}{k}");
					}
				}
				void Add(string human, string bone)
				{
					//IL_0021: Unknown result type (might be due to invalid IL or missing references)
					map[(HumanBodyBones)Enum.Parse(typeof(HumanBodyBones), side + human)] = "Bip01_" + s + "_" + bone;
				}
			}
			return map;
		}
	}
	internal sealed class LcRestPose
	{
		private readonly Dictionary<string, Matrix4x4> _rest = new Dictionary<string, Matrix4x4>();

		private readonly Dictionary<string, Matrix4x4> _bind = new Dictionary<string, Matrix4x4>();

		public Vector3 Up { get; private set; }

		public Vector3 Right { get; private set; }

		public static LcRestPose FromRenderer(SkinnedMeshRenderer r)
		{
			//IL_00a9: 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_00b9: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			LcRestPose lcRestPose = new LcRestPose();
			Matrix4x4[] bindposes = r.sharedMesh.bindposes;
			Transform[] bones = r.bones;
			for (int i = 0; i < bones.Length && i < bindposes.Length; i++)
			{
				if (!((Object)(object)bones[i] == (Object)null))
				{
					string text = ((Object)bones[i]).name;
					if (text.Contains("PlayerRagdoll") && !lcRestPose._rest.ContainsKey("spine"))
					{
						text = "spine";
					}
					lcRestPose._rest[text] = ((Matrix4x4)(ref bindposes[i])).inverse;
					lcRestPose._bind[text] = bindposes[i];
				}
			}
			Vector3 val = lcRestPose.Position("spine.004") - lcRestPose.Position("spine");
			lcRestPose.Up = ((Vector3)(ref val)).normalized;
			Vector3 val2 = lcRestPose.Position("arm.R_upper") - lcRestPose.Position("arm.L_upper");
			val = Vector3.ProjectOnPlane(val2, lcRestPose.Up);
			lcRestPose.Right = ((Vector3)(ref val)).normalized;
			return lcRestPose;
		}

		public bool Has(string bone)
		{
			return _rest.ContainsKey(bone);
		}

		public Vector3 Position(string bone)
		{
			//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_0010: 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)
			Matrix4x4 val = _rest[bone];
			return Vector4.op_Implicit(((Matrix4x4)(ref val)).GetColumn(3));
		}

		public Quaternion Rotation(string bone)
		{
			//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_000f: Unknown result type (might be due to invalid IL or missing references)
			Matrix4x4 val = _rest[bone];
			return ((Matrix4x4)(ref val)).rotation;
		}

		public Matrix4x4 BindPose(string bone)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return _bind[bone];
		}
	}
	internal sealed class ModelDefinition
	{
		[JsonProperty("id")]
		public string Id = "";

		[JsonProperty("suit")]
		public string Suit = "";

		[JsonProperty("source")]
		public string Source = "";

		[JsonProperty("mesh")]
		public string Mesh = "model.sqpm";

		[JsonProperty("materials")]
		public List<MaterialDefinition> Materials = new List<MaterialDefinition>();

		[JsonIgnore]
		public string Folder = "";

		public static ModelDefinition Load(string folder)
		{
			ModelDefinition obj = JsonConvert.DeserializeObject<ModelDefinition>(File.ReadAllText(Path.Combine(folder, "model.json"))) ?? throw new InvalidDataException("Empty model.json in " + folder);
			obj.Folder = folder;
			return obj;
		}
	}
	internal sealed class MaterialDefinition
	{
		[JsonProperty("name")]
		public string Name = "";

		[JsonProperty("albedo")]
		public string? Albedo;

		[JsonProperty("normal")]
		public string? Normal;

		[JsonProperty("mask")]
		public string? Mask;

		[JsonProperty("color")]
		public float[] Color = new float[4] { 1f, 1f, 1f, 1f };

		[JsonProperty("smoothness")]
		public float Smoothness = 0.35f;

		[JsonProperty("metallic")]
		public float Metallic;

		[JsonProperty("cutout")]
		public bool Cutout;

		[JsonProperty("doubleSided")]
		public bool DoubleSided;

		[JsonProperty("hidden")]
		public bool Hidden;
	}
	[BepInPlugin("pauluteli.SquadPlayermodels", "SquadPlayermodels", "0.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "pauluteli.SquadPlayermodels";

		public const string Name = "SquadPlayermodels";

		public const string Version = "0.2.0";

		internal static ManualLogSource Log = null;

		internal static readonly List<ModelDefinition> Models = new List<ModelDefinition>();

		internal static ConfigEntry<bool> FirstPersonArms = null;

		internal static ConfigEntry<float> ModelScale = null;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			FirstPersonArms = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "FirstPersonArms", true, "Show the Squad model's own arms in first person instead of the vanilla arms.");
			ModelScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ModelScale", 1f, "Size of Squad models relative to the vanilla player's height.");
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "SquadPlayermodels");
			if (!Directory.Exists(text))
			{
				Log.LogError((object)("Model folder not found: " + text));
				return;
			}
			foreach (string item in Directory.GetDirectories(text).OrderBy<string, string>((string f) => f, StringComparer.OrdinalIgnoreCase))
			{
				if (!File.Exists(Path.Combine(item, "model.json")))
				{
					continue;
				}
				if (Models.Count >= SquadModelSlots.Types.Length)
				{
					Log.LogWarning((object)$"Only {SquadModelSlots.Types.Length} Squad models are supported; skipping {item}");
					continue;
				}
				try
				{
					ModelDefinition modelDefinition = ModelDefinition.Load(item);
					ModelReplacementAPI.RegisterSuitModelReplacement(modelDefinition.Suit, SquadModelSlots.Types[Models.Count]);
					Models.Add(modelDefinition);
					Log.LogInfo((object)("Registered suit \"" + modelDefinition.Suit + "\" -> " + modelDefinition.Id));
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"Could not load model in {item}: {arg}");
				}
			}
			if (Models.Count > 0)
			{
				AutoTest.StartIfRequested();
			}
		}
	}
	internal sealed class SqpmFile
	{
		public string[] BoneNames = Array.Empty<string>();

		public int[] BoneParents = Array.Empty<int>();

		public Vector3[] BonePositions = Array.Empty<Vector3>();

		public Quaternion[] BoneRotations = Array.Empty<Quaternion>();

		public Vector3[] BoneScales = Array.Empty<Vector3>();

		public Matrix4x4[] BindPoses = Array.Empty<Matrix4x4>();

		public Vector3[] Positions = Array.Empty<Vector3>();

		public Vector3[] Normals = Array.Empty<Vector3>();

		public Vector2[] UVs = Array.Empty<Vector2>();

		public BoneWeight[] Weights = Array.Empty<BoneWeight>();

		public string[] SubmeshMaterials = Array.Empty<string>();

		public int[][] SubmeshIndices = Array.Empty<int[]>();

		public static SqpmFile Load(string path)
		{
			//IL_00f9: 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_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			using FileStream fileStream = File.OpenRead(path);
			BinaryReader binaryReader = new BinaryReader(fileStream);
			if (new string(binaryReader.ReadChars(4)) != "SQPM")
			{
				throw new InvalidDataException(path + " is not a .sqpm file");
			}
			int num = binaryReader.ReadInt32();
			if (num != 2)
			{
				throw new InvalidDataException($"{path}: unsupported version {num}, rebuild with tools/build.sh");
			}
			using BinaryReader binaryReader2 = new BinaryReader(new BufferedStream(new DeflateStream(fileStream, CompressionMode.Decompress), 65536));
			SqpmFile sqpmFile = new SqpmFile();
			int num2 = binaryReader2.ReadInt32();
			sqpmFile.BoneNames = new string[num2];
			sqpmFile.BoneParents = new int[num2];
			sqpmFile.BonePositions = (Vector3[])(object)new Vector3[num2];
			sqpmFile.BoneRotations = (Quaternion[])(object)new Quaternion[num2];
			sqpmFile.BoneScales = (Vector3[])(object)new Vector3[num2];
			sqpmFile.BindPoses = (Matrix4x4[])(object)new Matrix4x4[num2];
			for (int i = 0; i < num2; i++)
			{
				sqpmFile.BoneNames[i] = binaryReader2.ReadString();
				sqpmFile.BoneParents[i] = binaryReader2.ReadInt32();
				sqpmFile.BonePositions[i] = ReadV3(binaryReader2);
				sqpmFile.BoneRotations[i] = new Quaternion(binaryReader2.ReadSingle(), binaryReader2.ReadSingle(), binaryReader2.ReadSingle(), binaryReader2.ReadSingle());
				sqpmFile.BoneScales[i] = ReadV3(binaryReader2);
				Matrix4x4 val = default(Matrix4x4);
				for (int j = 0; j < 16; j++)
				{
					((Matrix4x4)(ref val))[j] = binaryReader2.ReadSingle();
				}
				sqpmFile.BindPoses[i] = val;
			}
			int num3 = binaryReader2.ReadInt32();
			sqpmFile.Positions = (Vector3[])(object)new Vector3[num3];
			sqpmFile.Normals = (Vector3[])(object)new Vector3[num3];
			sqpmFile.UVs = (Vector2[])(object)new Vector2[num3];
			sqpmFile.Weights = (BoneWeight[])(object)new BoneWeight[num3];
			for (int k = 0; k < num3; k++)
			{
				sqpmFile.Positions[k] = ReadV3(binaryReader2);
			}
			for (int l = 0; l < num3; l++)
			{
				sqpmFile.Normals[l] = new Vector3((float)binaryReader2.ReadInt16(), (float)binaryReader2.ReadInt16(), (float)binaryReader2.ReadInt16()) / 32767f;
			}
			for (int m = 0; m < num3; m++)
			{
				sqpmFile.UVs[m] = new Vector2(Mathf.HalfToFloat(binaryReader2.ReadUInt16()), Mathf.HalfToFloat(binaryReader2.ReadUInt16()));
			}
			byte[] array = binaryReader2.ReadBytes(num3 * 4);
			byte[] array2 = binaryReader2.ReadBytes(num3 * 4);
			for (int n = 0; n < num3; n++)
			{
				int num4 = n * 4;
				BoneWeight[] weights = sqpmFile.Weights;
				int num5 = n;
				BoneWeight val2 = default(BoneWeight);
				((BoneWeight)(ref val2)).boneIndex0 = array[num4];
				((BoneWeight)(ref val2)).weight0 = (float)(int)array2[num4] / 255f;
				((BoneWeight)(ref val2)).boneIndex1 = array[num4 + 1];
				((BoneWeight)(ref val2)).weight1 = (float)(int)array2[num4 + 1] / 255f;
				((BoneWeight)(ref val2)).boneIndex2 = array[num4 + 2];
				((BoneWeight)(ref val2)).weight2 = (float)(int)array2[num4 + 2] / 255f;
				((BoneWeight)(ref val2)).boneIndex3 = array[num4 + 3];
				((BoneWeight)(ref val2)).weight3 = (float)(int)array2[num4 + 3] / 255f;
				weights[num5] = val2;
			}
			int num6 = binaryReader2.ReadInt32();
			bool flag = binaryReader2.ReadByte() == 4;
			sqpmFile.SubmeshMaterials = new string[num6];
			sqpmFile.SubmeshIndices = new int[num6][];
			for (int num7 = 0; num7 < num6; num7++)
			{
				sqpmFile.SubmeshMaterials[num7] = binaryReader2.ReadString();
				int num8 = binaryReader2.ReadInt32();
				int[] array3 = new int[num8];
				for (int num9 = 0; num9 < num8; num9++)
				{
					array3[num9] = (int)(flag ? binaryReader2.ReadUInt32() : binaryReader2.ReadUInt16());
				}
				sqpmFile.SubmeshIndices[num7] = array3;
			}
			return sqpmFile;
		}

		private static Vector3 ReadV3(BinaryReader r)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
		}
	}
	public sealed class SquadModelInfo : MonoBehaviour
	{
		public string ModelId = "";

		public float HeadHeight;

		public float HipsHeight;
	}
	public abstract class SquadBodyReplacement : BodyReplacementBase
	{
		private static readonly Dictionary<string, GameObject> Templates = new Dictionary<string, GameObject>();

		protected abstract int Slot { get; }

		protected override GameObject LoadAssetsAndReturnModel()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			ModelDefinition modelDefinition = Plugin.Models[Slot];
			if (!Templates.TryGetValue(modelDefinition.Id, out GameObject value) || (Object)(object)value == (Object)null)
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				value = ModelBuilder.Build(modelDefinition, ((BodyReplacementBase)this).controller.thisPlayerModel);
				Templates[modelDefinition.Id] = value;
				Plugin.Log.LogInfo((object)$"Built model {modelDefinition.Id} in {Time.realtimeSinceStartup - realtimeSinceStartup:0.00}s");
			}
			value.transform.localScale = Vector3.one;
			return value;
		}

		protected override void AddModelScripts()
		{
			try
			{
				FitToPlayer();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Could not fit Squad model to player: {arg}");
			}
		}

		private void FitToPlayer()
		{
			//IL_0063: 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)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = base.replacementModel.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].forceRenderingOff = false;
			}
			SquadModelInfo component = base.replacementModel.GetComponent<SquadModelInfo>();
			OffsetBuilder component2 = base.replacementModel.GetComponent<OffsetBuilder>();
			SkinnedMeshRenderer thisPlayerModel = ((BodyReplacementBase)this).controller.thisPlayerModel;
			LcRestPose lcRestPose = LcRestPose.FromRenderer(thisPlayerModel);
			float num = WorldPerRestUnit(thisPlayerModel, lcRestPose);
			Vector3 val = (lcRestPose.Position("foot.L") + lcRestPose.Position("foot.R")) * 0.5f;
			float num2 = Vector3.Dot(lcRestPose.Position("spine.004") - val, lcRestPose.Up) * num;
			float num3 = Vector3.Dot(lcRestPose.Position("spine") - val, lcRestPose.Up) * num;
			float num4 = num2 / component.HeadHeight * Plugin.ModelScale.Value;
			base.replacementModel.transform.localScale = Vector3.one * num4;
			float num5 = component.HipsHeight * num4 - num3;
			Transform val2 = thisPlayerModel.bones.First((Transform b) => (Object)(object)b != (Object)null && ((Object)b).name == "spine");
			Matrix4x4 val3 = lcRestPose.BindPose("spine");
			Vector3 val4 = ((Matrix4x4)(ref val3)).MultiplyVector(lcRestPose.Up);
			Vector3 normalized = ((Vector3)(ref val4)).normalized;
			val4 = val2.TransformVector(normalized);
			component2.rootPositionOffset = normalized * (num5 / ((Vector3)(ref val4)).magnitude);
			Plugin.Log.LogInfo((object)$"{component.ModelId}: world/rest {num:0.####}, head {num2:0.###}, scale {num4:0.###}, hips raise {num5:0.###}");
		}

		private static float WorldPerRestUnit(SkinnedMeshRenderer pr, LcRestPose lc)
		{
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: 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_01c7: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, Transform> dictionary = (from b in pr.bones
				where (Object)(object)b != (Object)null
				group b by ((Object)b).name).ToDictionary((IGrouping<string, Transform> g) => g.Key, (IGrouping<string, Transform> g) => g.First());
			float num = 0f;
			float num2 = 0f;
			(string, string)[] array = new(string, string)[7]
			{
				("thigh.L", "shin.L"),
				("shin.L", "foot.L"),
				("thigh.R", "shin.R"),
				("shin.R", "foot.R"),
				("arm.L_upper", "arm.L_lower"),
				("arm.R_upper", "arm.R_lower"),
				("spine.001", "spine.002")
			};
			for (int num3 = 0; num3 < array.Length; num3++)
			{
				var (text, text2) = array[num3];
				if (lc.Has(text) && lc.Has(text2) && dictionary.ContainsKey(text) && dictionary.ContainsKey(text2))
				{
					float num4 = num;
					Vector3 val = lc.Position(text2) - lc.Position(text);
					num = num4 + ((Vector3)(ref val)).magnitude;
					float num5 = num2;
					val = dictionary[text2].position - dictionary[text].position;
					num2 = num5 + ((Vector3)(ref val)).magnitude;
				}
			}
			if (!(num > 0f))
			{
				return ((Component)pr).transform.lossyScale.y;
			}
			return num2 / num;
		}
	}
	public sealed class SquadModel000 : SquadBodyReplacement
	{
		protected override int Slot => 0;
	}
	public sealed class SquadModel001 : SquadBodyReplacement
	{
		protected override int Slot => 1;
	}
	public sealed class SquadModel002 : SquadBodyReplacement
	{
		protected override int Slot => 2;
	}
	public sealed class SquadModel003 : SquadBodyReplacement
	{
		protected override int Slot => 3;
	}
	public sealed class SquadModel004 : SquadBodyReplacement
	{
		protected override int Slot => 4;
	}
	public sealed class SquadModel005 : SquadBodyReplacement
	{
		protected override int Slot => 5;
	}
	public sealed class SquadModel006 : SquadBodyReplacement
	{
		protected override int Slot => 6;
	}
	public sealed class SquadModel007 : SquadBodyReplacement
	{
		protected override int Slot => 7;
	}
	public sealed class SquadModel008 : SquadBodyReplacement
	{
		protected override int Slot => 8;
	}
	public sealed class SquadModel009 : SquadBodyReplacement
	{
		protected override int Slot => 9;
	}
	public sealed class SquadModel010 : SquadBodyReplacement
	{
		protected override int Slot => 10;
	}
	public sealed class SquadModel011 : SquadBodyReplacement
	{
		protected override int Slot => 11;
	}
	public sealed class SquadModel012 : SquadBodyReplacement
	{
		protected override int Slot => 12;
	}
	public sealed class SquadModel013 : SquadBodyReplacement
	{
		protected override int Slot => 13;
	}
	public sealed class SquadModel014 : SquadBodyReplacement
	{
		protected override int Slot => 14;
	}
	public sealed class SquadModel015 : SquadBodyReplacement
	{
		protected override int Slot => 15;
	}
	public sealed class SquadModel016 : SquadBodyReplacement
	{
		protected override int Slot => 16;
	}
	public sealed class SquadModel017 : SquadBodyReplacement
	{
		protected override int Slot => 17;
	}
	public sealed class SquadModel018 : SquadBodyReplacement
	{
		protected override int Slot => 18;
	}
	public sealed class SquadModel019 : SquadBodyReplacement
	{
		protected override int Slot => 19;
	}
	public sealed class SquadModel020 : SquadBodyReplacement
	{
		protected override int Slot => 20;
	}
	public sealed class SquadModel021 : SquadBodyReplacement
	{
		protected override int Slot => 21;
	}
	public sealed class SquadModel022 : SquadBodyReplacement
	{
		protected override int Slot => 22;
	}
	public sealed class SquadModel023 : SquadBodyReplacement
	{
		protected override int Slot => 23;
	}
	public sealed class SquadModel024 : SquadBodyReplacement
	{
		protected override int Slot => 24;
	}
	public sealed class SquadModel025 : SquadBodyReplacement
	{
		protected override int Slot => 25;
	}
	public sealed class SquadModel026 : SquadBodyReplacement
	{
		protected override int Slot => 26;
	}
	public sealed class SquadModel027 : SquadBodyReplacement
	{
		protected override int Slot => 27;
	}
	public sealed class SquadModel028 : SquadBodyReplacement
	{
		protected override int Slot => 28;
	}
	public sealed class SquadModel029 : SquadBodyReplacement
	{
		protected override int Slot => 29;
	}
	public sealed class SquadModel030 : SquadBodyReplacement
	{
		protected override int Slot => 30;
	}
	public sealed class SquadModel031 : SquadBodyReplacement
	{
		protected override int Slot => 31;
	}
	public sealed class SquadModel032 : SquadBodyReplacement
	{
		protected override int Slot => 32;
	}
	public sealed class SquadModel033 : SquadBodyReplacement
	{
		protected override int Slot => 33;
	}
	public sealed class SquadModel034 : SquadBodyReplacement
	{
		protected override int Slot => 34;
	}
	public sealed class SquadModel035 : SquadBodyReplacement
	{
		protected override int Slot => 35;
	}
	public sealed class SquadModel036 : SquadBodyReplacement
	{
		protected override int Slot => 36;
	}
	public sealed class SquadModel037 : SquadBodyReplacement
	{
		protected override int Slot => 37;
	}
	public sealed class SquadModel038 : SquadBodyReplacement
	{
		protected override int Slot => 38;
	}
	public sealed class SquadModel039 : SquadBodyReplacement
	{
		protected override int Slot => 39;
	}
	public sealed class SquadModel040 : SquadBodyReplacement
	{
		protected override int Slot => 40;
	}
	public sealed class SquadModel041 : SquadBodyReplacement
	{
		protected override int Slot => 41;
	}
	public sealed class SquadModel042 : SquadBodyReplacement
	{
		protected override int Slot => 42;
	}
	public sealed class SquadModel043 : SquadBodyReplacement
	{
		protected override int Slot => 43;
	}
	public sealed class SquadModel044 : SquadBodyReplacement
	{
		protected override int Slot => 44;
	}
	public sealed class SquadModel045 : SquadBodyReplacement
	{
		protected override int Slot => 45;
	}
	public sealed class SquadModel046 : SquadBodyReplacement
	{
		protected override int Slot => 46;
	}
	public sealed class SquadModel047 : SquadBodyReplacement
	{
		protected override int Slot => 47;
	}
	public sealed class SquadModel048 : SquadBodyReplacement
	{
		protected override int Slot => 48;
	}
	public sealed class SquadModel049 : SquadBodyReplacement
	{
		protected override int Slot => 49;
	}
	public sealed class SquadModel050 : SquadBodyReplacement
	{
		protected override int Slot => 50;
	}
	public sealed class SquadModel051 : SquadBodyReplacement
	{
		protected override int Slot => 51;
	}
	public sealed class SquadModel052 : SquadBodyReplacement
	{
		protected override int Slot => 52;
	}
	public sealed class SquadModel053 : SquadBodyReplacement
	{
		protected override int Slot => 53;
	}
	public sealed class SquadModel054 : SquadBodyReplacement
	{
		protected override int Slot => 54;
	}
	public sealed class SquadModel055 : SquadBodyReplacement
	{
		protected override int Slot => 55;
	}
	public sealed class SquadModel056 : SquadBodyReplacement
	{
		protected override int Slot => 56;
	}
	public sealed class SquadModel057 : SquadBodyReplacement
	{
		protected override int Slot => 57;
	}
	public sealed class SquadModel058 : SquadBodyReplacement
	{
		protected override int Slot => 58;
	}
	public sealed class SquadModel059 : SquadBodyReplacement
	{
		protected override int Slot => 59;
	}
	public sealed class SquadModel060 : SquadBodyReplacement
	{
		protected override int Slot => 60;
	}
	public sealed class SquadModel061 : SquadBodyReplacement
	{
		protected override int Slot => 61;
	}
	public sealed class SquadModel062 : SquadBodyReplacement
	{
		protected override int Slot => 62;
	}
	public sealed class SquadModel063 : SquadBodyReplacement
	{
		protected override int Slot => 63;
	}
	public sealed class SquadModel064 : SquadBodyReplacement
	{
		protected override int Slot => 64;
	}
	public sealed class SquadModel065 : SquadBodyReplacement
	{
		protected override int Slot => 65;
	}
	public sealed class SquadModel066 : SquadBodyReplacement
	{
		protected override int Slot => 66;
	}
	public sealed class SquadModel067 : SquadBodyReplacement
	{
		protected override int Slot => 67;
	}
	public sealed class SquadModel068 : SquadBodyReplacement
	{
		protected override int Slot => 68;
	}
	public sealed class SquadModel069 : SquadBodyReplacement
	{
		protected override int Slot => 69;
	}
	public sealed class SquadModel070 : SquadBodyReplacement
	{
		protected override int Slot => 70;
	}
	public sealed class SquadModel071 : SquadBodyReplacement
	{
		protected override int Slot => 71;
	}
	public sealed class SquadModel072 : SquadBodyReplacement
	{
		protected override int Slot => 72;
	}
	public sealed class SquadModel073 : SquadBodyReplacement
	{
		protected override int Slot => 73;
	}
	public sealed class SquadModel074 : SquadBodyReplacement
	{
		protected override int Slot => 74;
	}
	public sealed class SquadModel075 : SquadBodyReplacement
	{
		protected override int Slot => 75;
	}
	public sealed class SquadModel076 : SquadBodyReplacement
	{
		protected override int Slot => 76;
	}
	public sealed class SquadModel077 : SquadBodyReplacement
	{
		protected override int Slot => 77;
	}
	public sealed class SquadModel078 : SquadBodyReplacement
	{
		protected override int Slot => 78;
	}
	public sealed class SquadModel079 : SquadBodyReplacement
	{
		protected override int Slot => 79;
	}
	public sealed class SquadModel080 : SquadBodyReplacement
	{
		protected override int Slot => 80;
	}
	public sealed class SquadModel081 : SquadBodyReplacement
	{
		protected override int Slot => 81;
	}
	public sealed class SquadModel082 : SquadBodyReplacement
	{
		protected override int Slot => 82;
	}
	public sealed class SquadModel083 : SquadBodyReplacement
	{
		protected override int Slot => 83;
	}
	public sealed class SquadModel084 : SquadBodyReplacement
	{
		protected override int Slot => 84;
	}
	public sealed class SquadModel085 : SquadBodyReplacement
	{
		protected override int Slot => 85;
	}
	public sealed class SquadModel086 : SquadBodyReplacement
	{
		protected override int Slot => 86;
	}
	public sealed class SquadModel087 : SquadBodyReplacement
	{
		protected override int Slot => 87;
	}
	public sealed class SquadModel088 : SquadBodyReplacement
	{
		protected override int Slot => 88;
	}
	public sealed class SquadModel089 : SquadBodyReplacement
	{
		protected override int Slot => 89;
	}
	public sealed class SquadModel090 : SquadBodyReplacement
	{
		protected override int Slot => 90;
	}
	public sealed class SquadModel091 : SquadBodyReplacement
	{
		protected override int Slot => 91;
	}
	public sealed class SquadModel092 : SquadBodyReplacement
	{
		protected override int Slot => 92;
	}
	public sealed class SquadModel093 : SquadBodyReplacement
	{
		protected override int Slot => 93;
	}
	public sealed class SquadModel094 : SquadBodyReplacement
	{
		protected override int Slot => 94;
	}
	public sealed class SquadModel095 : SquadBodyReplacement
	{
		protected override int Slot => 95;
	}
	public sealed class SquadModel096 : SquadBodyReplacement
	{
		protected override int Slot => 96;
	}
	public sealed class SquadModel097 : SquadBodyReplacement
	{
		protected override int Slot => 97;
	}
	public sealed class SquadModel098 : SquadBodyReplacement
	{
		protected override int Slot => 98;
	}
	public sealed class SquadModel099 : SquadBodyReplacement
	{
		protected override int Slot => 99;
	}
	public sealed class SquadModel100 : SquadBodyReplacement
	{
		protected override int Slot => 100;
	}
	public sealed class SquadModel101 : SquadBodyReplacement
	{
		protected override int Slot => 101;
	}
	public sealed class SquadModel102 : SquadBodyReplacement
	{
		protected override int Slot => 102;
	}
	public sealed class SquadModel103 : SquadBodyReplacement
	{
		protected override int Slot => 103;
	}
	public sealed class SquadModel104 : SquadBodyReplacement
	{
		protected override int Slot => 104;
	}
	public sealed class SquadModel105 : SquadBodyReplacement
	{
		protected override int Slot => 105;
	}
	public sealed class SquadModel106 : SquadBodyReplacement
	{
		protected override int Slot => 106;
	}
	public sealed class SquadModel107 : SquadBodyReplacement
	{
		protected override int Slot => 107;
	}
	public sealed class SquadModel108 : SquadBodyReplacement
	{
		protected override int Slot => 108;
	}
	public sealed class SquadModel109 : SquadBodyReplacement
	{
		protected override int Slot => 109;
	}
	public sealed class SquadModel110 : SquadBodyReplacement
	{
		protected override int Slot => 110;
	}
	public sealed class SquadModel111 : SquadBodyReplacement
	{
		protected override int Slot => 111;
	}
	public sealed class SquadModel112 : SquadBodyReplacement
	{
		protected override int Slot => 112;
	}
	public sealed class SquadModel113 : SquadBodyReplacement
	{
		protected override int Slot => 113;
	}
	public sealed class SquadModel114 : SquadBodyReplacement
	{
		protected override int Slot => 114;
	}
	public sealed class SquadModel115 : SquadBodyReplacement
	{
		protected override int Slot => 115;
	}
	public sealed class SquadModel116 : SquadBodyReplacement
	{
		protected override int Slot => 116;
	}
	public sealed class SquadModel117 : SquadBodyReplacement
	{
		protected override int Slot => 117;
	}
	public sealed class SquadModel118 : SquadBodyReplacement
	{
		protected override int Slot => 118;
	}
	public sealed class SquadModel119 : SquadBodyReplacement
	{
		protected override int Slot => 119;
	}
	public sealed class SquadModel120 : SquadBodyReplacement
	{
		protected override int Slot => 120;
	}
	public sealed class SquadModel121 : SquadBodyReplacement
	{
		protected override int Slot => 121;
	}
	public sealed class SquadModel122 : SquadBodyReplacement
	{
		protected override int Slot => 122;
	}
	public sealed class SquadModel123 : SquadBodyReplacement
	{
		protected override int Slot => 123;
	}
	public sealed class SquadModel124 : SquadBodyReplacement
	{
		protected override int Slot => 124;
	}
	public sealed class SquadModel125 : SquadBodyReplacement
	{
		protected override int Slot => 125;
	}
	public sealed class SquadModel126 : SquadBodyReplacement
	{
		protected override int Slot => 126;
	}
	public sealed class SquadModel127 : SquadBodyReplacement
	{
		protected override int Slot => 127;
	}
	internal static class SquadModelSlots
	{
		public static readonly Type[] Types = new Type[128]
		{
			typeof(SquadModel000),
			typeof(SquadModel001),
			typeof(SquadModel002),
			typeof(SquadModel003),
			typeof(SquadModel004),
			typeof(SquadModel005),
			typeof(SquadModel006),
			typeof(SquadModel007),
			typeof(SquadModel008),
			typeof(SquadModel009),
			typeof(SquadModel010),
			typeof(SquadModel011),
			typeof(SquadModel012),
			typeof(SquadModel013),
			typeof(SquadModel014),
			typeof(SquadModel015),
			typeof(SquadModel016),
			typeof(SquadModel017),
			typeof(SquadModel018),
			typeof(SquadModel019),
			typeof(SquadModel020),
			typeof(SquadModel021),
			typeof(SquadModel022),
			typeof(SquadModel023),
			typeof(SquadModel024),
			typeof(SquadModel025),
			typeof(SquadModel026),
			typeof(SquadModel027),
			typeof(SquadModel028),
			typeof(SquadModel029),
			typeof(SquadModel030),
			typeof(SquadModel031),
			typeof(SquadModel032),
			typeof(SquadModel033),
			typeof(SquadModel034),
			typeof(SquadModel035),
			typeof(SquadModel036),
			typeof(SquadModel037),
			typeof(SquadModel038),
			typeof(SquadModel039),
			typeof(SquadModel040),
			typeof(SquadModel041),
			typeof(SquadModel042),
			typeof(SquadModel043),
			typeof(SquadModel044),
			typeof(SquadModel045),
			typeof(SquadModel046),
			typeof(SquadModel047),
			typeof(SquadModel048),
			typeof(SquadModel049),
			typeof(SquadModel050),
			typeof(SquadModel051),
			typeof(SquadModel052),
			typeof(SquadModel053),
			typeof(SquadModel054),
			typeof(SquadModel055),
			typeof(SquadModel056),
			typeof(SquadModel057),
			typeof(SquadModel058),
			typeof(SquadModel059),
			typeof(SquadModel060),
			typeof(SquadModel061),
			typeof(SquadModel062),
			typeof(SquadModel063),
			typeof(SquadModel064),
			typeof(SquadModel065),
			typeof(SquadModel066),
			typeof(SquadModel067),
			typeof(SquadModel068),
			typeof(SquadModel069),
			typeof(SquadModel070),
			typeof(SquadModel071),
			typeof(SquadModel072),
			typeof(SquadModel073),
			typeof(SquadModel074),
			typeof(SquadModel075),
			typeof(SquadModel076),
			typeof(SquadModel077),
			typeof(SquadModel078),
			typeof(SquadModel079),
			typeof(SquadModel080),
			typeof(SquadModel081),
			typeof(SquadModel082),
			typeof(SquadModel083),
			typeof(SquadModel084),
			typeof(SquadModel085),
			typeof(SquadModel086),
			typeof(SquadModel087),
			typeof(SquadModel088),
			typeof(SquadModel089),
			typeof(SquadModel090),
			typeof(SquadModel091),
			typeof(SquadModel092),
			typeof(SquadModel093),
			typeof(SquadModel094),
			typeof(SquadModel095),
			typeof(SquadModel096),
			typeof(SquadModel097),
			typeof(SquadModel098),
			typeof(SquadModel099),
			typeof(SquadModel100),
			typeof(SquadModel101),
			typeof(SquadModel102),
			typeof(SquadModel103),
			typeof(SquadModel104),
			typeof(SquadModel105),
			typeof(SquadModel106),
			typeof(SquadModel107),
			typeof(SquadModel108),
			typeof(SquadModel109),
			typeof(SquadModel110),
			typeof(SquadModel111),
			typeof(SquadModel112),
			typeof(SquadModel113),
			typeof(SquadModel114),
			typeof(SquadModel115),
			typeof(SquadModel116),
			typeof(SquadModel117),
			typeof(SquadModel118),
			typeof(SquadModel119),
			typeof(SquadModel120),
			typeof(SquadModel121),
			typeof(SquadModel122),
			typeof(SquadModel123),
			typeof(SquadModel124),
			typeof(SquadModel125),
			typeof(SquadModel126),
			typeof(SquadModel127)
		};
	}
}