Decompiled source of ModelSwapperSkins v1.5.0

plugins/ModelSwapperSkins/ModelSwapperSkins.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HG;
using HG.Reflection;
using HarmonyLib;
using IL.RoR2;
using IL.RoR2.UI;
using Microsoft.CodeAnalysis;
using ModelSwapperSkins.BoneMapping;
using ModelSwapperSkins.BoneMapping.InitializerRules;
using ModelSwapperSkins.ModCompatibility;
using ModelSwapperSkins.ModelInfos;
using ModelSwapperSkins.ModelParts;
using ModelSwapperSkins.Patches;
using ModelSwapperSkins.Utils;
using ModelSwapperSkins.Utils.Comparers;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using On.RoR2;
using On.RoR2.UI;
using R2API.Utils;
using RoR2;
using RoR2.UI;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("ModelSwapperSkins")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ddb75346350a9570226dc12b898fb0d6f0c6e6a0")]
[assembly: AssemblyProduct("ModelSwapperSkins")]
[assembly: AssemblyTitle("ModelSwapperSkins")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	internal static class IsExternalInit
	{
	}
}
namespace ModelSwapperSkins
{
	public class AdditionalRendererInfoProvider : MonoBehaviour
	{
		public AdditionalRendererInfo AdditionalRendererInfo;

		public static void AddMaterials(Renderer renderer, Material[] additionalMaterials)
		{
			AdditionalRendererInfoProvider additionalRendererInfoProvider = default(AdditionalRendererInfoProvider);
			if (((Component)renderer).TryGetComponent<AdditionalRendererInfoProvider>(ref additionalRendererInfoProvider))
			{
				ArrayUtil.Append(ref additionalRendererInfoProvider.AdditionalRendererInfo.Materials, additionalMaterials);
				return;
			}
			additionalRendererInfoProvider = ((Component)renderer).gameObject.AddComponent<AdditionalRendererInfoProvider>();
			additionalRendererInfoProvider.AdditionalRendererInfo.Materials = additionalMaterials;
		}
	}
	[Serializable]
	public struct AdditionalRendererInfo
	{
		public Material[] Materials;
	}
	public static class BodyIconCache
	{
		private record IconKey(Texture2D bodyPortrait);

		private static readonly Dictionary<IconKey, Sprite> _cachedIcons = new Dictionary<IconKey, Sprite>();

		public static Sprite GetOrCreatePortraitIcon(Texture2D bodyPortrait)
		{
			IconKey key = new IconKey(bodyPortrait);
			if (_cachedIcons.TryGetValue(key, out var value))
			{
				return value;
			}
			Sprite val = generateSkinIcon(bodyPortrait);
			_cachedIcons.Add(key, val);
			return val;
		}

		private static Sprite generateSkinIcon(Texture2D bodyPortrait)
		{
			//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)
			Sprite obj = Sprite.Create(bodyPortrait, new Rect(0f, 0f, (float)((Texture)bodyPortrait).width, (float)((Texture)bodyPortrait).height), Vector2.zero);
			((Object)obj).name = ((Object)bodyPortrait).name;
			return obj;
		}
	}
	public class BodySkinsInitializer
	{
		private readonly CharacterBody _bodyPrefab;

		private readonly ModelPartsProvider _bodyPartsProvider;

		private readonly BonesProvider _bodyBonesProvider;

		private readonly ModelSkinController _bodySkinController;

		private readonly HashSet<Transform> _usedModelTransforms = new HashSet<Transform>();

		public BodySkinsInitializer(CharacterBody bodyPrefab)
		{
			_bodyPrefab = bodyPrefab;
			ModelLocator val = default(ModelLocator);
			if (Object.op_Implicit((Object)(object)_bodyPrefab) && ((Component)_bodyPrefab).TryGetComponent<ModelLocator>(ref val))
			{
				Transform modelTransform = val.modelTransform;
				if (Object.op_Implicit((Object)(object)modelTransform))
				{
					_bodyPartsProvider = ((Component)modelTransform).GetComponent<ModelPartsProvider>();
					_bodyBonesProvider = ((Component)modelTransform).GetComponent<BonesProvider>();
					_bodySkinController = ((Component)modelTransform).GetComponent<ModelSkinController>();
				}
			}
		}

		private bool isSurvivorValidForSkins()
		{
			if (Object.op_Implicit((Object)(object)_bodyPrefab) && Object.op_Implicit((Object)(object)_bodyPartsProvider))
			{
				return Object.op_Implicit((Object)(object)_bodyBonesProvider);
			}
			return false;
		}

		public void TryCreateSkins(List<SkinDef> dest)
		{
			if (!isSurvivorValidForSkins())
			{
				return;
			}
			_usedModelTransforms.Clear();
			List<CharacterBody> list = BodyCatalog.allBodyPrefabBodyBodyComponents.ToList();
			list.Sort(delegate(CharacterBody a, CharacterBody b)
			{
				string sortName = getSortName(a);
				string sortName2 = getSortName(b);
				return sortName.CompareTo(sortName2);
			});
			foreach (CharacterBody item in list)
			{
				if (shouldCreateSkin(item))
				{
					dest.AddRange((IEnumerable<SkinDef>)createSkinsForBody(item));
				}
			}
			static string getSortName(CharacterBody body)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return BodyCatalog.GetBodyName(body.bodyIndex) switch
				{
					"ScavLunar1Body" => "ScavengerLunar1", 
					"ScavLunar2Body" => "ScavengerLunar2", 
					"ScavLunar3Body" => "ScavengerLunar3", 
					"ScavLunar4Body" => "ScavengerLunar4", 
					_ => sanitizeName(Language.GetString(body.baseNameToken, "en")), 
				};
			}
			static string sanitizeName(string input)
			{
				StringBuilder stringBuilder = StringBuilderPool.RentStringBuilder();
				string text = input;
				foreach (char c in text)
				{
					if (c <= '\u007f')
					{
						stringBuilder.Append(c);
					}
				}
				if (stringBuilder.Length > 0 && stringBuilder.Length < input.Length)
				{
					input = stringBuilder.ToString();
				}
				StringBuilderPool.ReturnStringBuilder(stringBuilder);
				return input;
			}
		}

		private bool hasEnoughBonesToMatchWith(BonesProvider otherBonesProvider)
		{
			if (anyBonesValidMatch(new BoneType[4]
			{
				BoneType.Head,
				BoneType.Chest,
				BoneType.Stomach,
				BoneType.Pelvis
			}))
			{
				if (!anyBonesValidMatch(new BoneType[4]
				{
					BoneType.ArmUpperL,
					BoneType.ArmLowerL,
					BoneType.ArmUpperR,
					BoneType.ArmLowerR
				}))
				{
					return anyBonesValidMatch(new BoneType[4]
					{
						BoneType.LegUpperL,
						BoneType.LegLowerL,
						BoneType.LegUpperR,
						BoneType.LegLowerR
					});
				}
				return true;
			}
			return false;
			bool anyBonesValidMatch(BoneType[] bones)
			{
				return Array.Exists(bones, boneTest);
			}
			bool boneTest(BoneType bone)
			{
				if (_bodyBonesProvider.HasMatchForBone(bone))
				{
					return otherBonesProvider.CanMatchToBone(bone);
				}
				return false;
			}
		}

		private bool shouldCreateSkin(CharacterBody body)
		{
			if (!Object.op_Implicit((Object)(object)body))
			{
				return false;
			}
			if ((Object)(object)body == (Object)(object)_bodyPrefab)
			{
				return false;
			}
			ModelLocator component = ((Component)body).GetComponent<ModelLocator>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return false;
			}
			Transform modelTransform = component.modelTransform;
			if (!Object.op_Implicit((Object)(object)modelTransform) || modelTransform.childCount == 0)
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)((Component)modelTransform).GetComponent<ModelPartsProvider>()))
			{
				return false;
			}
			BonesProvider component2 = ((Component)modelTransform).GetComponent<BonesProvider>();
			if (!Object.op_Implicit((Object)(object)component2))
			{
				return false;
			}
			if (!hasEnoughBonesToMatchWith(component2))
			{
				return false;
			}
			if (!_usedModelTransforms.Add(modelTransform))
			{
				return false;
			}
			return true;
		}

		private IEnumerable<ModelSwappedSkinDef> createSkinsForBody(CharacterBody body)
		{
			ModelLocator component = ((Component)body).GetComponent<ModelLocator>();
			Transform modelTransform = component.modelTransform;
			ModelPartsProvider bodyModelPartsProvider = ((Component)modelTransform).GetComponent<ModelPartsProvider>();
			SkinDef[] array = (Object.op_Implicit((Object)(object)_bodySkinController) ? _bodySkinController.skins : null);
			if (array == null || array.Length == 0)
			{
				array = (SkinDef[])(object)new SkinDef[1];
			}
			ModelSkinController modelSkinController = ((Component)modelTransform).GetComponent<ModelSkinController>();
			SkinDef[] array2 = array;
			foreach (SkinDef bodySkin in array2)
			{
				if (Object.op_Implicit((Object)(object)modelSkinController))
				{
					IEnumerable<SkinDef> enumerable = modelSkinController.skins.Where((SkinDef s) => !(s is ModelSwappedSkinDef));
					if (enumerable.Any())
					{
						foreach (SkinDef item in enumerable)
						{
							yield return createSkinDef(bodySkin, item);
						}
						continue;
					}
				}
				yield return createSkinDef(bodySkin, null);
			}
			ModelSwappedSkinDef createSkinDef(SkinDef baseSkin, SkinDef modelSkin)
			{
				ModelSwappedSkinDef modelSwappedSkinDef = ScriptableObject.CreateInstance<ModelSwappedSkinDef>();
				string name = (Object.op_Implicit((Object)(object)baseSkin) ? ((!Object.op_Implicit((Object)(object)modelSkin)) ? ("skin" + ((Object)_bodyPrefab).name + "_" + ((Object)baseSkin).name + "_" + ((Object)body).name) : ("skin" + ((Object)_bodyPrefab).name + "_" + ((Object)baseSkin).name + "_" + ((Object)body).name + "_" + ((Object)modelSkin).name)) : ((!Object.op_Implicit((Object)(object)modelSkin)) ? ("skin" + ((Object)_bodyPrefab).name + "_" + ((Object)body).name) : ("skin" + ((Object)_bodyPrefab).name + "_" + ((Object)body).name + "_" + ((Object)modelSkin).name)));
				((Object)modelSwappedSkinDef).name = name;
				ref Sprite icon = ref ((SkinDef)modelSwappedSkinDef).icon;
				Texture portraitIcon = body.portraitIcon;
				icon = BodyIconCache.GetOrCreatePortraitIcon((Texture2D)(object)((portraitIcon is Texture2D) ? portraitIcon : null));
				if (Object.op_Implicit((Object)(object)baseSkin))
				{
					((SkinDef)modelSwappedSkinDef).baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
				}
				modelSwappedSkinDef.NewModelBodyPrefab = body;
				modelSwappedSkinDef.NewModelTransformPrefab = modelTransform;
				modelSwappedSkinDef.ModelSkin = modelSkin;
				modelSwappedSkinDef.Initialize(_bodyPartsProvider, bodyModelPartsProvider);
				return modelSwappedSkinDef;
			}
		}
	}
	public static class DynamicSkinAdder
	{
		public delegate void AddSkinDelegate(CharacterBody bodyPrefab, List<SkinDef> skins);

		private static bool _skinBakeDisabled;

		public static event AddSkinDelegate AddSkins;

		[SystemInitializer(new Type[]
		{
			typeof(SurvivorCatalog),
			typeof(BodyCatalog),
			typeof(ModelPartsInitializer),
			typeof(BoneInitializer)
		})]
		private static void Init()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			SkinDef.Bake += new hook_Bake(SkinDef_Bake);
			HashSet<CharacterBody> hashSet = new HashSet<CharacterBody>();
			foreach (CharacterBody allBodyPrefabBodyBodyComponent in BodyCatalog.allBodyPrefabBodyBodyComponents)
			{
				try
				{
					addDefaultSkinIfMissing(allBodyPrefabBodyBodyComponent);
				}
				catch (Exception arg)
				{
					Log.Error_NoCallerPrefix($"Failed to generate default skin for {((Object)allBodyPrefabBodyBodyComponent).name}: {arg}");
					hashSet.Add(allBodyPrefabBodyBodyComponent);
				}
			}
			foreach (CharacterBody allBodyPrefabBodyBodyComponent2 in BodyCatalog.allBodyPrefabBodyBodyComponents)
			{
				if (!hashSet.Contains(allBodyPrefabBodyBodyComponent2) && Object.op_Implicit((Object)(object)SurvivorCatalog.FindSurvivorDefFromBody(((Component)allBodyPrefabBodyBodyComponent2).gameObject)))
				{
					addSkinsTo(allBodyPrefabBodyBodyComponent2);
				}
			}
			SkinDef.Bake -= new hook_Bake(SkinDef_Bake);
			static void SkinDef_Bake(orig_Bake orig, SkinDef self)
			{
				if (!_skinBakeDisabled)
				{
					orig.Invoke(self);
				}
			}
		}

		private static void addSkinsTo(CharacterBody body)
		{
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Invalid comparison between Unknown and I4
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Invalid comparison between Unknown and I4
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)body))
			{
				return;
			}
			ModelLocator component = ((Component)body).GetComponent<ModelLocator>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			Transform modelTransform = component.modelTransform;
			if (!Object.op_Implicit((Object)(object)modelTransform))
			{
				return;
			}
			List<SkinDef> list = new List<SkinDef>();
			ModelSkinController component2 = ((Component)modelTransform).GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)component2))
			{
				Log.Warning(((Object)body).name + " model is missing ModelSkinController", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\DynamicSkinAdder.cs", "addSkinsTo", 87);
				return;
			}
			_skinBakeDisabled = true;
			try
			{
				DynamicSkinAdder.AddSkins?.Invoke(body, list);
			}
			catch (Exception arg)
			{
				Log.Error_NoCallerPrefix($"Failed to generate skins for {((Object)body).name}: {arg}");
				return;
			}
			finally
			{
				_skinBakeDisabled = false;
			}
			if (list.Count > 0)
			{
				for (int num = list.Count - 1; num >= 0; num--)
				{
					SkinDef val = list[num];
					SkinDef val2 = val;
					if (val2.baseSkins == null)
					{
						val2.baseSkins = Array.Empty<SkinDef>();
					}
					val2 = val;
					if (val2.rendererInfos == null)
					{
						val2.rendererInfos = Array.Empty<RendererInfo>();
					}
					val2 = val;
					if (val2.gameObjectActivations == null)
					{
						val2.gameObjectActivations = Array.Empty<GameObjectActivation>();
					}
					val2 = val;
					if (val2.meshReplacements == null)
					{
						val2.meshReplacements = Array.Empty<MeshReplacement>();
					}
					val2 = val;
					if (val2.projectileGhostReplacements == null)
					{
						val2.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
					}
					val2 = val;
					if (val2.minionSkinReplacements == null)
					{
						val2.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
					}
					if (!Object.op_Implicit((Object)(object)val.rootObject))
					{
						val.rootObject = ((Component)modelTransform).gameObject;
					}
					try
					{
						val.Bake();
					}
					catch (Exception arg2)
					{
						Log.Warning_NoCallerPrefix($"Failed to create skin {((Object)val).name} for {((Object)body).name}: {arg2}");
						Object.Destroy((Object)(object)list[num]);
						list.RemoveAt(num);
					}
				}
				ArrayUtil.Append(ref component2.skins, list);
				BodyIndex bodyIndex = body.bodyIndex;
				if ((int)bodyIndex != -1)
				{
					SkinDef[][] skins = BodyCatalog.skins;
					if ((int)bodyIndex < skins.Length)
					{
						ArrayUtil.Append(ref skins[bodyIndex], list);
					}
				}
			}
			Log.Info_NoCallerPrefix($"Created {list.Count} skin(s) for {((Object)body).name}");
		}

		private static void addDefaultSkinIfMissing(CharacterBody bodyPrefab)
		{
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: 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_0449: Invalid comparison between Unknown and I4
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Invalid comparison between Unknown and I4
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			SurvivorDef val = SurvivorCatalog.FindSurvivorDefFromBody(((Component)bodyPrefab).gameObject);
			ModelLocator component = ((Component)bodyPrefab).GetComponent<ModelLocator>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			Transform modelTransform = component.modelTransform;
			if (!Object.op_Implicit((Object)(object)modelTransform))
			{
				return;
			}
			CharacterModel component2 = ((Component)modelTransform).GetComponent<CharacterModel>();
			if (!Object.op_Implicit((Object)(object)component2))
			{
				return;
			}
			ModelPartsProvider modelPartsProvider = default(ModelPartsProvider);
			ModelPart[] array = ((!((Component)modelTransform).TryGetComponent<ModelPartsProvider>(ref modelPartsProvider)) ? Array.Empty<ModelPart>() : modelPartsProvider.Parts);
			ModelSkinController val2 = default(ModelSkinController);
			if (((Component)modelTransform).TryGetComponent<ModelSkinController>(ref val2))
			{
				SkinDef[] skins = val2.skins;
				foreach (SkinDef val3 in skins)
				{
					if ((Object)(object)val3.rootObject != (Object)(object)((Component)modelTransform).gameObject)
					{
						Log.Warning("Incorrect skin root object for " + ((Object)val3).name + " on " + ((Object)bodyPrefab).name, "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\DynamicSkinAdder.cs", "addDefaultSkinIfMissing", 193);
						continue;
					}
					List<GameObjectActivation> list = new List<GameObjectActivation>(val3.gameObjectActivations);
					bool flag = false;
					ModelPart[] array2 = array;
					foreach (ModelPart modelPart in array2)
					{
						bool flag2 = false;
						foreach (GameObjectActivation item in list)
						{
							if (Util.BuildPrefabTransformPath(val3.rootObject.transform, item.gameObject.transform, false, false) == modelPart.Path)
							{
								flag2 = true;
								break;
							}
						}
						if (!flag2)
						{
							Transform val4 = val3.rootObject.transform.Find(modelPart.Path);
							if (Object.op_Implicit((Object)(object)val4))
							{
								list.Add(new GameObjectActivation
								{
									gameObject = ((Component)val4).gameObject,
									shouldActivate = ((Component)val4).gameObject.activeSelf
								});
								flag = true;
							}
						}
					}
					if (flag)
					{
						val3.gameObjectActivations = list.ToArray();
						val3.runtimeSkin = null;
					}
				}
			}
			else
			{
				val2 = ((Component)modelTransform).gameObject.AddComponent<ModelSkinController>();
				_skinBakeDisabled = true;
				SkinDef val5 = ScriptableObject.CreateInstance<SkinDef>();
				_skinBakeDisabled = false;
				((Object)val5).name = "skin" + ((Object)bodyPrefab).name + "Default";
				val5.rootObject = ((Component)modelTransform).gameObject;
				val5.baseSkins = Array.Empty<SkinDef>();
				List<RendererInfo> list2 = new List<RendererInfo>(component2.baseRendererInfos);
				for (int num = list2.Count - 1; num >= 0; num--)
				{
					Renderer renderer2 = list2[num].renderer;
					if (!Object.op_Implicit((Object)(object)renderer2) || !((Component)renderer2).transform.IsChildOf(val5.rootObject.transform))
					{
						list2.RemoveAt(num);
					}
				}
				ModelPart[] array2 = array;
				Renderer renderer = default(Renderer);
				foreach (ModelPart modelPart2 in array2)
				{
					if (!modelPart2.RendererInfo.HasValue || !((Component)modelPart2.Transform).TryGetComponent<Renderer>(ref renderer))
					{
						continue;
					}
					Material[] sharedMaterials = renderer.sharedMaterials;
					if (sharedMaterials.Length != 0)
					{
						ModelPartRendererInfo value = modelPart2.RendererInfo.Value;
						RendererInfo val6 = default(RendererInfo);
						val6.renderer = renderer;
						val6.defaultMaterial = sharedMaterials[0];
						val6.defaultShadowCastingMode = renderer.shadowCastingMode;
						val6.ignoreOverlays = value.IgnoreOverlays;
						val6.hideOnDeath = value.HideOnDeath;
						RendererInfo val7 = val6;
						int num2 = list2.FindIndex((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)renderer);
						if (num2 < 0)
						{
							list2.Add(val7);
						}
						else
						{
							list2[num2] = val7;
						}
						if (sharedMaterials.Length > 1)
						{
							Material[] array3 = (Material[])(object)new Material[sharedMaterials.Length - 1];
							Array.Copy(sharedMaterials, 1, array3, 0, array3.Length);
							AdditionalRendererInfoProvider.AddMaterials(renderer, array3);
						}
					}
				}
				val5.rendererInfos = list2.ToArray();
				val5.gameObjectActivations = Array.ConvertAll(array, delegate(ModelPart p)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0031: Unknown result type (might be due to invalid IL or missing references)
					GameObjectActivation result = default(GameObjectActivation);
					result.gameObject = ((Component)p.Transform).gameObject;
					result.shouldActivate = ((Component)p.Transform).gameObject.activeSelf;
					return result;
				});
				val5.meshReplacements = Array.Empty<MeshReplacement>();
				val5.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
				val5.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
				val2.skins = (SkinDef[])(object)new SkinDef[1] { val5 };
				BodyIndex bodyIndex = bodyPrefab.bodyIndex;
				if ((int)bodyIndex != -1)
				{
					SkinDef[][] skins2 = BodyCatalog.skins;
					if ((int)bodyIndex < skins2.Length)
					{
						ArrayUtils.ArrayAppend<SkinDef>(ref skins2[bodyIndex], ref val5);
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.displayPrefab))
			{
				return;
			}
			CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				ModelSkinController val8 = default(ModelSkinController);
				if (!((Component)componentInChildren).TryGetComponent<ModelSkinController>(ref val8))
				{
					val8 = ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
				}
				val8.skins = val2.skins;
			}
		}
	}
	internal static class LanguageFolderHandler
	{
		public static void Register(string searchFolder, string langFolderName = "lang")
		{
			string langFolderPath = Path.Combine(searchFolder, langFolderName);
			if (Directory.Exists(langFolderPath))
			{
				Language.collectLanguageRootFolders += delegate(List<string> folders)
				{
					folders.Add(langFolderPath);
				};
			}
		}
	}
	internal static class Log
	{
		internal static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		private static string getLogPrefix(string callerPath, string callerMemberName, int callerLineNumber)
		{
			int num = callerPath.LastIndexOf("ModelSwapperSkins");
			if (num >= 0)
			{
				callerPath = callerPath.Substring(num + "ModelSwapperSkins".Length + 1);
			}
			return $"{callerPath}:{callerLineNumber} ({callerMemberName}) ";
		}

		internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogError((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Error_NoCallerPrefix(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogFatal((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Fatal_NoCallerPrefix(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogInfo((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Info_NoCallerPrefix(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogMessage((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Message_NoCallerPrefix(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogWarning((object)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Warning_NoCallerPrefix(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[BepInPlugin("Gorakh.ModelSwapperSkins", "ModelSwapperSkins", "1.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Main : BaseUnityPlugin
	{
		public const string PluginGUID = "Gorakh.ModelSwapperSkins";

		public const string PluginAuthor = "Gorakh";

		public const string PluginName = "ModelSwapperSkins";

		public const string PluginVersion = "1.5.0";

		private void Awake()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			Log.Init(((BaseUnityPlugin)this).Logger);
			LanguageFolderHandler.Register(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(DynamicSkinAdder));
			DynamicSkinAdder.AddSkins += DynamicSkinAdder_AddSkins;
			stopwatch.Stop();
			Log.Info_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalSeconds:F2} seconds");
		}

		private static void DynamicSkinAdder_AddSkins(CharacterBody bodyPrefab, List<SkinDef> skins)
		{
			new BodySkinsInitializer(bodyPrefab).TryCreateSkins(skins);
		}
	}
	public class ModelSwappedSkinDef : SkinDef
	{
		public CharacterBody NewModelBodyPrefab;

		public Transform NewModelTransformPrefab;

		public SkinDef ModelSkin;

		public bool KeepSkinModelAnimatorActive;

		public void Initialize(ModelPartsProvider modelPartsProvider, ModelPartsProvider skinModelPartsProvider)
		{
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: 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)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: 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_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: 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)
			HashSet<SkinDef> encounteredSkinInstances = new HashSet<SkinDef>();
			List<SkinDef> baseSkinsApplyOrder = new List<SkinDef>();
			if (base.baseSkins != null)
			{
				SkinDef[] baseSkins = base.baseSkins;
				for (int i = 0; i < baseSkins.Length; i++)
				{
					addBaseSkinToApplyOrder(baseSkins[i]);
				}
			}
			base.gameObjectActivations = (GameObjectActivation[])(object)new GameObjectActivation[modelPartsProvider.Parts.Length];
			for (int j = 0; j < modelPartsProvider.Parts.Length; j++)
			{
				ModelPart modelPart = modelPartsProvider.Parts[j];
				GameObject partObject = ((Component)modelPart.Transform).gameObject;
				bool flag = modelPart.ShouldShow(isMainModel: true);
				for (int num = baseSkinsApplyOrder.Count - 1; num >= 0; num--)
				{
					SkinDef val = baseSkinsApplyOrder[num];
					int num2 = Array.FindIndex(val.gameObjectActivations, (GameObjectActivation a) => (Object)(object)a.gameObject == (Object)(object)partObject);
					if (num2 >= 0)
					{
						bool shouldActivate = val.gameObjectActivations[num2].shouldActivate;
						flag = flag && shouldActivate;
						break;
					}
				}
				base.gameObjectActivations[j] = new GameObjectActivation
				{
					gameObject = partObject,
					shouldActivate = flag
				};
			}
			if (base.baseSkins == null || base.baseSkins.Length == 0)
			{
				base.rendererInfos = ((Component)modelPartsProvider).GetComponent<CharacterModel>().baseRendererInfos;
			}
			else
			{
				HashSet<MinionSkinReplacement> hashSet = new HashSet<MinionSkinReplacement>(MinionSkinReplacementBodyComparer.Instance);
				HashSet<ProjectileGhostReplacement> hashSet2 = new HashSet<ProjectileGhostReplacement>(ProjectileGhostReplacementProjectileComparer.Instance);
				SkinDef[] baseSkins = base.baseSkins;
				foreach (SkinDef val2 in baseSkins)
				{
					if (Object.op_Implicit((Object)(object)val2))
					{
						if (val2.minionSkinReplacements != null && val2.minionSkinReplacements.Length != 0)
						{
							hashSet.UnionWith(val2.minionSkinReplacements);
						}
						if (val2.projectileGhostReplacements != null && val2.projectileGhostReplacements.Length != 0)
						{
							hashSet2.UnionWith(val2.projectileGhostReplacements);
						}
					}
				}
				base.minionSkinReplacements = hashSet.ToArray();
				base.projectileGhostReplacements = hashSet2.ToArray();
			}
			bool flag2 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("GupBody") || NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("GeepBody") || NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("GipBody");
			bool flag3 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("MiniVoidRaidCrabBodyBase");
			bool flag4 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("NullifierBody") || NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("NullifierAllyBody");
			bool flag5 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("CaptainBody");
			bool flag6 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("EngiBody");
			bool flag7 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("HermitCrabBody");
			bool flag8 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("ImpBody");
			bool flag9 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("ImpBossBody");
			bool flag10 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("AcidLarvaBody");
			bool flag11 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("MiniMushroomBody");
			bool flag12 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("TreebotBody");
			bool flag13 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("ScavBody") || NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("ScavLunar1Body") || NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("ScavLunar2Body") || NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("ScavLunar3Body") || NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("ScavLunar4Body");
			KeepSkinModelAnimatorActive = flag2 || flag3 || flag4 || flag5 || flag6 || flag7 || flag8 || flag9 || flag10 || flag11 || flag12 || flag13;
			void addBaseSkinToApplyOrder(SkinDef skin)
			{
				if (encounteredSkinInstances.Add(skin))
				{
					if (skin.baseSkins != null)
					{
						SkinDef[] baseSkins2 = skin.baseSkins;
						for (int k = 0; k < baseSkins2.Length; k++)
						{
							addBaseSkinToApplyOrder(baseSkins2[k]);
						}
					}
					baseSkinsApplyOrder.Add(skin);
				}
			}
		}

		public void RemoveFrom(Transform modelTransform, GameObject skinModelObject)
		{
			//IL_0025: 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)
			CharacterModel val = default(CharacterModel);
			if (!((Component)modelTransform).TryGetComponent<CharacterModel>(ref val))
			{
				return;
			}
			List<LightInfo> list = val.baseLightInfos.ToList();
			bool flag = false;
			for (int num = list.Count - 1; num >= 0; num--)
			{
				if (!Object.op_Implicit((Object)(object)list[num].light) || ((Component)list[num].light).transform.IsChildOf(skinModelObject.transform))
				{
					list.RemoveAt(num);
					flag = true;
				}
			}
			if (flag)
			{
				val.baseLightInfos = list.ToArray();
			}
		}

		public Transform InstantiateModel(Transform modelTransform)
		{
			//IL_007f: 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_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0541: 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_05be: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_064f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0654: Unknown result type (might be due to invalid IL or missing references)
			//IL_065a: Unknown result type (might be due to invalid IL or missing references)
			//IL_065c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0682: Unknown result type (might be due to invalid IL or missing references)
			//IL_0687: Unknown result type (might be due to invalid IL or missing references)
			//IL_068d: Unknown result type (might be due to invalid IL or missing references)
			//IL_068f: Unknown result type (might be due to invalid IL or missing references)
			Transform val = Object.Instantiate<Transform>(NewModelTransformPrefab, modelTransform);
			if (Object.op_Implicit((Object)(object)ModelSkin))
			{
				ModelSkin.Apply(((Component)val).gameObject);
			}
			HurtBox[] componentsInChildren = ((Component)val).GetComponentsInChildren<HurtBox>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Behaviour)componentsInChildren[i]).enabled = false;
			}
			Collider[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				componentsInChildren2[i].enabled = false;
			}
			bool flag = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("ToolbotBody");
			Animator[] componentsInChildren3 = ((Component)val).GetComponentsInChildren<Animator>(true);
			CharacterModel val3 = default(CharacterModel);
			foreach (Animator val2 in componentsInChildren3)
			{
				if (flag && ((Component)val2).TryGetComponent<CharacterModel>(ref val3))
				{
					((MonoBehaviour)val3).StartCoroutine(waitUntilInitializedThenFixToolbotAnimator(val2));
				}
				else if (!KeepSkinModelAnimatorActive)
				{
					((Behaviour)val2).enabled = false;
				}
			}
			SkinnedMeshRenderer[] componentsInChildren4 = ((Component)val).GetComponentsInChildren<SkinnedMeshRenderer>();
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				componentsInChildren4[i].updateWhenOffscreen = true;
			}
			Behaviour[] components = ((Component)val).GetComponents<Behaviour>();
			foreach (Behaviour val4 in components)
			{
				if (Object.op_Implicit((Object)(object)val4) && ((object)val4).GetType().FullName == "Generics.Dynamics.InverseKinematics")
				{
					val4.enabled = false;
				}
			}
			PrintController[] componentsInChildren5 = ((Component)val).GetComponentsInChildren<PrintController>(true);
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				((Behaviour)componentsInChildren5[i]).enabled = false;
			}
			AkEvent[] componentsInChildren6 = ((Component)val).GetComponentsInChildren<AkEvent>(true);
			for (int i = 0; i < componentsInChildren6.Length; i++)
			{
				((Behaviour)componentsInChildren6[i]).enabled = false;
			}
			StriderLegController[] componentsInChildren7 = ((Component)val).GetComponentsInChildren<StriderLegController>();
			for (int i = 0; i < componentsInChildren7.Length; i++)
			{
				((Behaviour)componentsInChildren7[i]).enabled = false;
			}
			componentsInChildren3 = ((Component)modelTransform).GetComponents<Animator>();
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				componentsInChildren3[i].cullingMode = (AnimatorCullingMode)0;
			}
			ModelInfo modelInfo = ModelInfoProvider.GetModelInfo(((Component)modelTransform).gameObject);
			ModelInfo modelInfo2 = ModelInfoProvider.GetModelInfo(((Component)val).gameObject);
			float num = modelInfo.HeightScale / modelInfo2.HeightScale;
			val.localScale = new Vector3(num, num, num);
			BonesProvider other = default(BonesProvider);
			BonesProvider bonesProvider = default(BonesProvider);
			if (((Component)modelTransform).TryGetComponent<BonesProvider>(ref other) && ((Component)val).TryGetComponent<BonesProvider>(ref bonesProvider))
			{
				bonesProvider.MapBonesTo(other);
			}
			ModelPartsProvider modelPartsProvider = default(ModelPartsProvider);
			if (((Component)val).TryGetComponent<ModelPartsProvider>(ref modelPartsProvider))
			{
				ModelPart[] parts = modelPartsProvider.Parts;
				foreach (ModelPart modelPart in parts)
				{
					if (!modelPart.ShouldShow(isMainModel: false))
					{
						((Component)modelPart.Transform).gameObject.SetActive(false);
					}
				}
			}
			CharacterModel val5 = default(CharacterModel);
			if (((Component)modelTransform).TryGetComponent<CharacterModel>(ref val5))
			{
				bool flag2 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("VultureBody");
				bool flag3 = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("GravekeeperBody");
				DynamicBone[] componentsInChildren8 = ((Component)val).GetComponentsInChildren<DynamicBone>();
				foreach (DynamicBone val6 in componentsInChildren8)
				{
					((Behaviour)val6).enabled = false;
					if (!flag2 && (!flag3 || !Object.op_Implicit((Object)(object)val6.m_Root) || !(((Object)val6.m_Root).name == "head")))
					{
						((MonoBehaviour)val5).StartCoroutine(waitThenSetEnabled((Behaviour)(object)val6));
					}
				}
				List<RendererInfo> list = new List<RendererInfo>();
				List<LightInfo> list2 = new List<LightInfo>();
				CharacterModel component = ((Component)val).GetComponent<CharacterModel>();
				if (Object.op_Implicit((Object)(object)component) && (component.baseRendererInfos.Length != 0 || component.baseLightInfos.Length != 0))
				{
					RendererInfo[] baseRendererInfos = component.baseRendererInfos;
					if (NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("MiniVoidRaidCrabBodyBase"))
					{
						for (int j = 0; j < baseRendererInfos.Length; j++)
						{
							ref RendererInfo reference = ref baseRendererInfos[j];
							if (Object.op_Implicit((Object)(object)reference.renderer))
							{
								switch (((Object)reference.renderer).name)
								{
								case "EyePupilMesh":
								case "VoidRaidCrabEye":
									reference.ignoreOverlays = true;
									break;
								case "VoidRaidCrabHead":
								case "VoidRaidCrabMetalLegRingsMesh":
								case "VoidRaidCrabMetalMesh":
								case "VoidRaidCrabBrain":
									reference.ignoreOverlays = false;
									break;
								}
							}
						}
					}
					list.AddRange(baseRendererInfos);
					list2.AddRange(component.baseLightInfos);
					val5.mainSkinnedMeshRenderer = component.mainSkinnedMeshRenderer;
				}
				else
				{
					list.AddRange(((Component)val).GetComponentsInChildren<Renderer>().Select(delegate(Renderer r)
					{
						//IL_0002: Unknown result type (might be due to invalid IL or missing references)
						//IL_0020: 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_0042: Unknown result type (might be due to invalid IL or missing references)
						RendererInfo result = default(RendererInfo);
						result.renderer = r;
						result.defaultMaterial = r.sharedMaterial;
						result.defaultShadowCastingMode = r.shadowCastingMode;
						result.hideOnDeath = false;
						result.ignoreOverlays = r is ParticleSystemRenderer;
						return result;
					}));
					list2.AddRange(((IEnumerable<Light>)((Component)val).GetComponentsInChildren<Light>()).Select((Func<Light, LightInfo>)((Light l) => new LightInfo(l))));
				}
				List<Object> objectsToCleanupOnModelDestroy = new List<Object>();
				for (int k = 0; k < list.Count; k++)
				{
					RendererInfo val7 = list[k];
					bool flag4 = false;
					if (val7.defaultMaterial.IsKeywordEnabled("PRINT_CUTOFF"))
					{
						Material val8 = Object.Instantiate<Material>(val7.defaultMaterial);
						val8.DisableKeyword("PRINT_CUTOFF");
						val8.SetInt(ShaderIDs._PrintOn, 0);
						val7.defaultMaterial = val8;
						objectsToCleanupOnModelDestroy.Add((Object)(object)val8);
						flag4 = true;
					}
					if (flag4)
					{
						list[k] = val7;
					}
				}
				if (objectsToCleanupOnModelDestroy.Count > 0)
				{
					OnDestroyCallback.AddCallback(((Component)modelTransform).gameObject, (Action<OnDestroyCallback>)delegate
					{
						foreach (Object item in objectsToCleanupOnModelDestroy)
						{
							if (Object.op_Implicit(item))
							{
								Object.Destroy(item);
							}
						}
					});
				}
				CharacterModel val9 = val5;
				RendererInfo[] baseRendererInfos2 = val5.baseRendererInfos;
				List<RendererInfo> list3 = list;
				int i = 0;
				RendererInfo[] array = (RendererInfo[])(object)new RendererInfo[baseRendererInfos2.Length + list3.Count];
				RendererInfo[] array2 = baseRendererInfos2;
				foreach (RendererInfo val10 in array2)
				{
					array[i] = val10;
					i++;
				}
				foreach (RendererInfo item2 in list3)
				{
					array[i] = item2;
					i++;
				}
				val9.baseRendererInfos = array;
				val9 = val5;
				LightInfo[] baseLightInfos = val5.baseLightInfos;
				List<LightInfo> list4 = list2;
				i = 0;
				LightInfo[] array3 = (LightInfo[])(object)new LightInfo[baseLightInfos.Length + list4.Count];
				LightInfo[] array4 = baseLightInfos;
				foreach (LightInfo val11 in array4)
				{
					array3[i] = val11;
					i++;
				}
				foreach (LightInfo item3 in list4)
				{
					array3[i] = item3;
					i++;
				}
				val9.baseLightInfos = array3;
				if (Object.op_Implicit((Object)(object)component))
				{
					((Behaviour)component).enabled = false;
				}
			}
			return val;
			static IEnumerator waitThenSetEnabled(Behaviour behaviour)
			{
				yield return (object)new WaitForEndOfFrame();
				if (Object.op_Implicit((Object)(object)behaviour))
				{
					behaviour.enabled = true;
				}
			}
			static IEnumerator waitUntilInitializedThenFixToolbotAnimator(Animator animator)
			{
				Transform val12 = ((Component)animator).transform.Find("ToolbotMesh");
				Renderer toolbotMeshRenderer = default(Renderer);
				if (Object.op_Implicit((Object)(object)val12) && ((Component)val12).TryGetComponent<Renderer>(ref toolbotMeshRenderer))
				{
					yield return (object)new WaitForEndOfFrame();
					yield return (object)new WaitWhile((Func<bool>)(() => Object.op_Implicit((Object)(object)toolbotMeshRenderer) && !toolbotMeshRenderer.enabled));
					if (!Object.op_Implicit((Object)(object)animator))
					{
						yield break;
					}
				}
				animator.speed = 0f;
				animator.Update(0f);
				animator.SetInteger("weaponStance", 0);
				animator.Update(0f);
				animator.PlayInFixedTime("NailgunOut", animator.GetLayerIndex("Stance, Additive"), 0f);
				animator.Update(0f);
				yield return (object)new WaitForEndOfFrame();
				if (Object.op_Implicit((Object)(object)animator))
				{
					((Behaviour)animator).enabled = false;
				}
			}
		}
	}
}
namespace ModelSwapperSkins.Utils
{
	public static class ArrayUtil
	{
		public static void Append<T>(ref T[] array, IEnumerable<T> other)
		{
			if (other != null)
			{
				Append(ref array, other.ToArray());
			}
		}

		public static void Append<T>(ref T[] array, T[] other)
		{
			if (array == null || array.Length == 0)
			{
				array = other;
			}
			else if (other != null && other.Length != 0)
			{
				int num = array.Length;
				Array.Resize(ref array, num + other.Length);
				Array.Copy(other, 0, array, num, other.Length);
			}
		}
	}
	internal static class BoneVisualizer
	{
		private class ModelBonesDrawer : MonoBehaviour
		{
			private static readonly Mesh _lineMesh;

			private readonly List<MeshDrawer> _activeMeshDrawers = new List<MeshDrawer>();

			private CharacterModel _model;

			static ModelBonesDrawer()
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Expected O, but got Unknown
				//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)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				WireMeshBuilder val = new WireMeshBuilder();
				try
				{
					val.AddLine(Vector3.zero, Color.yellow, Vector3.forward, Color.yellow);
					_lineMesh = val.GenerateMesh();
				}
				finally
				{
					((IDisposable)val)?.Dispose();
				}
			}

			private void Awake()
			{
				//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_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Expected O, but got Unknown
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: 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_00ce: 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)
				_model = ((Component)this).GetComponent<CharacterModel>();
				BonesProvider component = ((Component)_model).GetComponent<BonesProvider>();
				if (Object.op_Implicit((Object)(object)component))
				{
					Bone[] bones = component.Bones;
					foreach (Bone bone in bones)
					{
						if (bone.Info.Type == BoneType.Root)
						{
							continue;
						}
						Transform boneTransform = bone.BoneTransform;
						if (Object.op_Implicit((Object)(object)boneTransform))
						{
							int childCount = boneTransform.childCount;
							for (int j = 0; j < childCount; j++)
							{
								Transform child = boneTransform.GetChild(j);
								MeshDrawer val = new MeshDrawer(boneTransform)
								{
									mesh = _lineMesh,
									hasMeshOwnership = false
								};
								Vector3 localPosition = child.localPosition;
								float magnitude = ((Vector3)(ref localPosition)).magnitude;
								val.transform.localPosition = Vector3.zero;
								val.transform.localRotation = Util.QuaternionSafeLookRotation(localPosition);
								val.transform.localScale = Vector3.one * magnitude;
								_activeMeshDrawers.Add(val);
							}
						}
					}
				}
				InstanceTracker.Add<ModelBonesDrawer>(this);
			}

			private void OnDestroy()
			{
				InstanceTracker.Remove<ModelBonesDrawer>(this);
				foreach (MeshDrawer activeMeshDrawer in _activeMeshDrawers)
				{
					if (Object.op_Implicit((Object)(object)activeMeshDrawer.gameObject))
					{
						activeMeshDrawer.Dispose();
					}
				}
				_activeMeshDrawers.Clear();
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__CharacterModel_Awake;
		}

		private static bool _drawModelBones;

		[ConCommand(commandName = "draw_model_bones")]
		private static void CCEnableBoneVisualizer(ConCommandArgs args)
		{
			_drawModelBones = !_drawModelBones;
			if (_drawModelBones)
			{
				foreach (CharacterModel instances in InstanceTracker.GetInstancesList<CharacterModel>())
				{
					((Component)instances).gameObject.AddComponent<ModelBonesDrawer>();
				}
				return;
			}
			List<ModelBonesDrawer> instancesList = InstanceTracker.GetInstancesList<ModelBonesDrawer>();
			for (int num = instancesList.Count - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)instancesList[num]);
			}
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__CharacterModel_Awake;
			if (obj == null)
			{
				hook_Awake val = CharacterModel_Awake;
				<>O.<0>__CharacterModel_Awake = val;
				obj = (object)val;
			}
			CharacterModel.Awake += (hook_Awake)obj;
		}

		private static void CharacterModel_Awake(orig_Awake orig, CharacterModel self)
		{
			orig.Invoke(self);
			if (_drawModelBones)
			{
				((Component)self).gameObject.AddComponent<ModelBonesDrawer>();
			}
		}
	}
	internal static class ShaderIDs
	{
		public static readonly int _PrintOn = Shader.PropertyToID("_PrintOn");
	}
	internal static class ShaderKeywords
	{
		public const string PRINT_CUTOFF = "PRINT_CUTOFF";
	}
	public class TemporaryTexture : IDisposable
	{
		[CompilerGenerated]
		private bool <isTemporary>P;

		public readonly Texture2D Texture;

		public TemporaryTexture(Texture2D texture, bool isTemporary)
		{
			<isTemporary>P = isTemporary;
			Texture = texture;
			base..ctor();
		}

		public void Dispose()
		{
			if (<isTemporary>P)
			{
				Object.Destroy((Object)(object)Texture);
			}
		}
	}
	public static class TransformUtils
	{
		public static string GetObjectPath(Transform obj, Transform root)
		{
			if ((Object)(object)obj == (Object)(object)root)
			{
				return ((Object)obj).name;
			}
			StringBuilder stringBuilder = new StringBuilder();
			do
			{
				if (stringBuilder.Length == 0)
				{
					stringBuilder.Append(((Object)obj).name);
				}
				else
				{
					stringBuilder.Insert(0, ((Object)obj).name + "/");
				}
				obj = obj.parent;
			}
			while ((Object)(object)obj != (Object)null && (Object)(object)obj != (Object)(object)root);
			return stringBuilder.ToString();
		}

		public static IEnumerable<Transform> GetAllChildrenRecursive(Transform root)
		{
			yield return root;
			for (int i = 0; i < root.childCount; i++)
			{
				foreach (Transform item in GetAllChildrenRecursive(root.GetChild(i)))
				{
					yield return item;
				}
			}
		}
	}
	public static class VectorUtils
	{
		public static Vector3 Divide(Vector3 a, Vector3 b)
		{
			//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)
			//IL_0013: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(a.x / b.x, a.y / b.y, a.z / b.z);
		}
	}
}
namespace ModelSwapperSkins.Utils.Extensions
{
	public static class TextureExtensions
	{
		public static Sprite CreateSprite(this Texture2D texture)
		{
			//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)
			return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), Vector2.zero);
		}

		public static TemporaryTexture AsReadable(this Texture2D texture)
		{
			//IL_0044: 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)
			//IL_0062: 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_0086: Expected O, but got Unknown
			if (((Texture)texture).isReadable)
			{
				return new TemporaryTexture(texture, isTemporary: false);
			}
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			Graphics.Blit((Texture)(object)texture, temporary);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D(((Texture)texture).width, ((Texture)texture).height);
			val.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			return new TemporaryTexture(val, isTemporary: true);
		}
	}
	public static class TransformExtensions
	{
		public static Transform FindChildRecursive(this Transform transform, string childName)
		{
			if (((Object)transform).name == childName)
			{
				return transform;
			}
			for (int i = 0; i < transform.childCount; i++)
			{
				Transform val = transform.GetChild(i).FindChildRecursive(childName);
				if (Object.op_Implicit((Object)(object)val))
				{
					return val;
				}
			}
			return null;
		}
	}
}
namespace ModelSwapperSkins.Utils.Comparers
{
	public sealed class GameObjectActivationObjectComparer : IEqualityComparer<GameObjectActivation>
	{
		public static GameObjectActivationObjectComparer Instance { get; } = new GameObjectActivationObjectComparer();


		private GameObjectActivationObjectComparer()
		{
		}

		public bool Equals(GameObjectActivation x, GameObjectActivation y)
		{
			//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)
			return (Object)(object)x.gameObject == (Object)(object)y.gameObject;
		}

		public int GetHashCode(GameObjectActivation obj)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ((object)obj.gameObject).GetHashCode();
		}
	}
	public class MinionSkinReplacementBodyComparer : IEqualityComparer<MinionSkinReplacement>
	{
		public static MinionSkinReplacementBodyComparer Instance { get; } = new MinionSkinReplacementBodyComparer();


		private MinionSkinReplacementBodyComparer()
		{
		}

		public bool Equals(MinionSkinReplacement x, MinionSkinReplacement y)
		{
			//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)
			return (Object)(object)x.minionBodyPrefab == (Object)(object)y.minionBodyPrefab;
		}

		public int GetHashCode(MinionSkinReplacement obj)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ((object)obj.minionBodyPrefab).GetHashCode();
		}
	}
	public class ProjectileGhostReplacementProjectileComparer : IEqualityComparer<ProjectileGhostReplacement>
	{
		public static ProjectileGhostReplacementProjectileComparer Instance { get; } = new ProjectileGhostReplacementProjectileComparer();


		private ProjectileGhostReplacementProjectileComparer()
		{
		}

		public bool Equals(ProjectileGhostReplacement x, ProjectileGhostReplacement y)
		{
			//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)
			return (Object)(object)x.projectilePrefab == (Object)(object)y.projectilePrefab;
		}

		public int GetHashCode(ProjectileGhostReplacement obj)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ((object)obj.projectilePrefab).GetHashCode();
		}
	}
	public class RendererInfoRendererComparer : IEqualityComparer<RendererInfo>
	{
		public static RendererInfoRendererComparer Instance { get; } = new RendererInfoRendererComparer();


		private RendererInfoRendererComparer()
		{
		}

		public bool Equals(RendererInfo x, RendererInfo y)
		{
			//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)
			return (Object)(object)x.renderer == (Object)(object)y.renderer;
		}

		public int GetHashCode(RendererInfo obj)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ((object)obj.renderer).GetHashCode();
		}
	}
}
namespace ModelSwapperSkins.Patches
{
	internal static class AdditionalRendererInfoApplyPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__CharacterModel_UpdateRendererMaterials;
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__CharacterModel_UpdateRendererMaterials;
			if (obj == null)
			{
				Manipulator val = CharacterModel_UpdateRendererMaterials;
				<>O.<0>__CharacterModel_UpdateRendererMaterials = val;
				obj = (object)val;
			}
			CharacterModel.UpdateRendererMaterials += (Manipulator)obj;
		}

		private static void CharacterModel_UpdateRendererMaterials(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.DeclaredPropertySetter(typeof(Renderer), "sharedMaterials"))
			}))
			{
				VariableDefinition val2 = new VariableDefinition((TypeReference)(object)TypeReferenceRocks.MakeArrayType(il.Import(typeof(Material))));
				il.Method.Body.Variables.Add(val2);
				val.Emit(OpCodes.Stloc, val2);
				val.Emit(OpCodes.Dup);
				val.Emit(OpCodes.Ldloc, val2);
				val.EmitDelegate<Func<Renderer, Material[], Material[]>>((Func<Renderer, Material[], Material[]>)delegate(Renderer renderer, Material[] materials)
				{
					AdditionalRendererInfoProvider additionalRendererInfoProvider = default(AdditionalRendererInfoProvider);
					if (((Component)renderer).TryGetComponent<AdditionalRendererInfoProvider>(ref additionalRendererInfoProvider))
					{
						AdditionalRendererInfo additionalRendererInfo = additionalRendererInfoProvider.AdditionalRendererInfo;
						ArrayUtil.Append(ref materials, additionalRendererInfo.Materials);
					}
					return materials;
				});
			}
			else
			{
				Log.Error("Failed to find patch location", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\Patches\\AdditionalRendererInfoApplyPatch.cs", "CharacterModel_UpdateRendererMaterials", 47);
			}
		}
	}
	internal static class CreateModelOnApplySkin
	{
		private class SkinModelObjectTracker : MonoBehaviour
		{
			public ModelSwappedSkinDef AppliedSkin;

			public GameObject SkinModelObject;

			private void OnDestroy()
			{
				if (Object.op_Implicit((Object)(object)SkinModelObject))
				{
					Object.Destroy((Object)(object)SkinModelObject);
				}
			}
		}

		public class AppliedSkinTracker : MonoBehaviour
		{
			public SkinDef AppliedSkin;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Apply <0>__SkinDef_Apply;
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__SkinDef_Apply;
			if (obj == null)
			{
				hook_Apply val = SkinDef_Apply;
				<>O.<0>__SkinDef_Apply = val;
				obj = (object)val;
			}
			SkinDef.Apply += (hook_Apply)obj;
		}

		private static void SkinDef_Apply(orig_Apply orig, SkinDef self, GameObject modelObject)
		{
			SkinModelObjectTracker skinModelObjectTracker = default(SkinModelObjectTracker);
			if (modelObject.TryGetComponent<SkinModelObjectTracker>(ref skinModelObjectTracker))
			{
				skinModelObjectTracker.AppliedSkin.RemoveFrom(modelObject.transform, skinModelObjectTracker.SkinModelObject);
				Object.Destroy((Object)(object)skinModelObjectTracker);
			}
			orig.Invoke(self, modelObject);
			AppliedSkinTracker appliedSkinTracker = default(AppliedSkinTracker);
			if (!modelObject.TryGetComponent<AppliedSkinTracker>(ref appliedSkinTracker))
			{
				appliedSkinTracker = modelObject.AddComponent<AppliedSkinTracker>();
			}
			appliedSkinTracker.AppliedSkin = self;
			if (self is ModelSwappedSkinDef modelSwappedSkinDef)
			{
				Transform val = modelSwappedSkinDef.InstantiateModel(modelObject.transform);
				SkinModelObjectTracker skinModelObjectTracker2 = modelObject.AddComponent<SkinModelObjectTracker>();
				skinModelObjectTracker2.SkinModelObject = ((Component)val).gameObject;
				skinModelObjectTracker2.AppliedSkin = modelSwappedSkinDef;
			}
		}
	}
	internal static class FixMissingSkinPathsPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Apply <0>__RuntimeSkin_Apply;
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__RuntimeSkin_Apply;
			if (obj == null)
			{
				hook_Apply val = RuntimeSkin_Apply;
				<>O.<0>__RuntimeSkin_Apply = val;
				obj = (object)val;
			}
			RuntimeSkin.Apply += (hook_Apply)obj;
		}

		private static void RuntimeSkin_Apply(orig_Apply orig, object self, GameObject modelObject)
		{
			RuntimeSkin val = (RuntimeSkin)((self is RuntimeSkin) ? self : null);
			if (val != null)
			{
				Transform transform = modelObject.transform;
				if (val.gameObjectActivationTemplates != null)
				{
					for (int num = val.gameObjectActivationTemplates.Length - 1; num >= 0; num--)
					{
						if (!Object.op_Implicit((Object)(object)transform.Find(val.gameObjectActivationTemplates[num].path)))
						{
							ArrayUtils.ArrayRemoveAtAndResize<GameObjectActivationTemplate>(ref val.gameObjectActivationTemplates, num, 1);
						}
					}
				}
				if (val.meshReplacementTemplates != null)
				{
					for (int num2 = val.meshReplacementTemplates.Length - 1; num2 >= 0; num2--)
					{
						if (!Object.op_Implicit((Object)(object)transform.Find(val.meshReplacementTemplates[num2].path)))
						{
							ArrayUtils.ArrayRemoveAtAndResize<MeshReplacementTemplate>(ref val.meshReplacementTemplates, num2, 1);
						}
					}
				}
			}
			orig.Invoke(self, modelObject);
		}
	}
	internal static class LoadoutPanelModifications
	{
		private class LoadoutPanelModelSkinsHandler : MonoBehaviour
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static UnityAction <>9__10_0;

				public static Func<Loadout, int> <>9__10_1;

				internal void <rebuildModelSkinRow>b__10_0()
				{
				}

				internal int <rebuildModelSkinRow>b__10_1(Loadout loadout)
				{
					return 0;
				}
			}

			private Row _modelSkinRow;

			public LoadoutPanelController PanelController { get; set; }

			private void OnEnable()
			{
				UserProfile.onLoadoutChangedGlobal += UserProfile_onLoadoutChangedGlobal;
			}

			private void OnDisable()
			{
				UserProfile.onLoadoutChangedGlobal -= UserProfile_onLoadoutChangedGlobal;
			}

			private void UserProfile_onLoadoutChangedGlobal(UserProfile userProfile)
			{
				if (Object.op_Implicit((Object)(object)PanelController) && PanelController.currentDisplayData.userProfile == userProfile)
				{
					rebuildModelSkinRow();
				}
			}

			public void Rebuild()
			{
				rebuildModelRow();
				rebuildModelSkinRow();
			}

			private void rebuildModelRow()
			{
				//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)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Invalid comparison between Unknown and I4
				//IL_002e: 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_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Expected O, but got Unknown
				//IL_009d: 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_00ba: Expected O, but got Unknown
				//IL_010d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_012b: 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)
				//IL_017c: Unknown result type (might be due to invalid IL or missing references)
				//IL_018d: Expected O, but got Unknown
				BodyIndex bodyIndex = PanelController.currentDisplayData.bodyIndex;
				if ((int)bodyIndex == -1)
				{
					return;
				}
				CharacterBody bodyPrefabBodyComponent = BodyCatalog.GetBodyPrefabBodyComponent(bodyIndex);
				if (!Object.op_Implicit((Object)(object)bodyPrefabBodyComponent))
				{
					return;
				}
				SkinDef[] skins = BodyCatalog.GetBodySkins(bodyIndex);
				Row modelRow = new Row(PanelController, bodyIndex, "LOADOUT_MODEL");
				Texture portraitIcon = bodyPrefabBodyComponent.portraitIcon;
				Sprite orCreatePortraitIcon = BodyIconCache.GetOrCreatePortraitIcon((Texture2D)(object)((portraitIcon is Texture2D) ? portraitIcon : null));
				modelRow.AddButton(PanelController, orCreatePortraitIcon, "LOADOUT_MODEL_DEFAULT", string.Empty, modelRow.primaryColor, (UnityAction)delegate
				{
					setSkinModel((BodyIndex)(-1));
				}, string.Empty, (Node)null, false);
				int[] buttonIndexLookup = new int[BodyCatalog.bodyCount + 1];
				int num = 1;
				SkinDef[] array = skins;
				foreach (SkinDef val in array)
				{
					if (!(val is ModelSwappedSkinDef modelSwappedSkinDef))
					{
						continue;
					}
					BodyIndex modelBodyIndex2 = modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex;
					ref int reference = ref buttonIndexLookup[modelBodyIndex2 + 1];
					if (reference <= 0)
					{
						modelRow.AddButton(PanelController, val.icon, modelSwappedSkinDef.NewModelBodyPrefab.baseNameToken, string.Empty, modelRow.primaryColor, (UnityAction)delegate
						{
							//IL_0007: Unknown result type (might be due to invalid IL or missing references)
							setSkinModel(modelBodyIndex2);
						}, string.Empty, (Node)null, false);
						reference = num++;
					}
				}
				modelRow.findCurrentChoice = delegate(Loadout loadout)
				{
					//IL_0007: 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)
					//IL_004a: 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_0052: Expected I4, but got Unknown
					uint skinIndex = loadout.bodyLoadoutManager.GetSkinIndex(bodyIndex);
					if (skins != null && skinIndex < skins.Length && skins[skinIndex] is ModelSwappedSkinDef modelSwappedSkinDef2)
					{
						BodyIndex bodyIndex2 = modelSwappedSkinDef2.NewModelBodyPrefab.bodyIndex;
						return ArrayUtils.GetSafe<int>(buttonIndexLookup, bodyIndex2 + 1);
					}
					return 0;
				};
				modelRow.FinishSetup(false);
				PanelController.rows.Add(modelRow);
				if (SkinTuner.IsActive)
				{
					((MonoBehaviour)this).StartCoroutine(waitThenSetSiblingIndex());
				}
				static bool isValidBodySkin(SkinDef skinDef)
				{
					return !(skinDef is ModelSwappedSkinDef);
				}
				void setSkinModel(BodyIndex modelBodyIndex)
				{
					//IL_001f: 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_014b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0152: Expected O, but got Unknown
					//IL_016c: Unknown result type (might be due to invalid IL or missing references)
					LoadoutPanelSkinResolver loadoutPanelSkinResolver = default(LoadoutPanelSkinResolver);
					if (((Component)PanelController).TryGetComponent<LoadoutPanelSkinResolver>(ref loadoutPanelSkinResolver))
					{
						int num2 = loadoutPanelSkinResolver.ModelSkinIndex;
						loadoutPanelSkinResolver.ModelBodyIndex = modelBodyIndex;
						SkinDef[] bodySkins = BodyCatalog.GetBodySkins(loadoutPanelSkinResolver.ModelBodyIndex);
						if (num2 >= bodySkins.Length - 1)
						{
							num2 = Array.FindLastIndex(bodySkins, isValidBodySkin);
						}
						else if (num2 <= 0)
						{
							num2 = Array.FindIndex(bodySkins, isValidBodySkin);
						}
						else if (!isValidBodySkin(bodySkins[num2]))
						{
							int num3 = Array.FindLastIndex(bodySkins, num2 - 1, num2, isValidBodySkin);
							int num4 = Array.FindIndex(bodySkins, num2, bodySkins.Length - num2, isValidBodySkin);
							num2 = ((num3 == -1) ? num4 : ((num4 == -1 || num4 - num2 >= num2 - num3) ? num3 : num4));
						}
						loadoutPanelSkinResolver.ModelSkinIndex = num2;
						SkinDef resolvedSkin = loadoutPanelSkinResolver.ResolvedSkin;
						uint num5;
						if (Object.op_Implicit((Object)(object)resolvedSkin))
						{
							num5 = (uint)Mathf.Max(0, Array.IndexOf(skins, resolvedSkin));
						}
						else
						{
							Log.Error("Failed to resolve skin", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\Patches\\LoadoutPanelModifications.cs", "rebuildModelRow", 380);
							num5 = 0u;
						}
						Loadout val2 = new Loadout();
						modelRow.userProfile.CopyLoadout(val2);
						val2.bodyLoadoutManager.SetSkinIndex(bodyIndex, num5);
						modelRow.userProfile.SetLoadout(val2);
					}
					else
					{
						Log.Error("Missing skin resolver", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\Patches\\LoadoutPanelModifications.cs", "rebuildModelRow", 391);
					}
				}
				IEnumerator waitThenSetSiblingIndex()
				{
					yield return (object)new WaitForEndOfFrame();
					if (modelRow != null && Object.op_Implicit((Object)(object)modelRow.rowPanelTransform))
					{
						((Transform)modelRow.rowPanelTransform).SetSiblingIndex(2);
					}
				}
			}

			private void rebuildModelSkinRow()
			{
				//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)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Invalid comparison between Unknown and I4
				//IL_002f: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Expected O, but got Unknown
				//IL_0231: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_025a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0273: Unknown result type (might be due to invalid IL or missing references)
				//IL_0278: Unknown result type (might be due to invalid IL or missing references)
				//IL_027e: Expected O, but got Unknown
				//IL_01de: Unknown result type (might be due to invalid IL or missing references)
				//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fc: Expected O, but got Unknown
				BodyIndex bodyIndex = PanelController.currentDisplayData.bodyIndex;
				if ((int)bodyIndex == -1)
				{
					return;
				}
				SkinDef[] skins = BodyCatalog.GetBodySkins(bodyIndex);
				uint skinIndex = PanelController.currentDisplayData.userProfile.loadout.bodyLoadoutManager.GetSkinIndex(bodyIndex);
				if (skinIndex >= skins.Length)
				{
					return;
				}
				int num;
				if (_modelSkinRow != null)
				{
					num = PanelController.rows.IndexOf(_modelSkinRow);
					_modelSkinRow.Dispose();
				}
				else
				{
					num = -1;
				}
				_modelSkinRow = new Row(PanelController, bodyIndex, "LOADOUT_MODEL_SKIN");
				int num2 = 0;
				if (skins[skinIndex] is ModelSwappedSkinDef modelSwappedSkinDef)
				{
					BodyIndex modelBodyIndex = modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex;
					SkinDef[] bodySkins = BodyCatalog.GetBodySkins(modelBodyIndex);
					int[] buttonIndexLookup = new int[bodySkins.Length];
					for (int i = 0; i < bodySkins.Length; i++)
					{
						SkinDef skin = bodySkins[i];
						if (skin is ModelSwappedSkinDef)
						{
							continue;
						}
						ref int reference = ref buttonIndexLookup[i];
						if (reference > 0)
						{
							continue;
						}
						Sprite val = skin.icon;
						if (!Object.op_Implicit((Object)(object)val))
						{
							val = _fallbackSkinIcon;
						}
						string text = skin.nameToken;
						if (string.IsNullOrEmpty(text) || Language.IsTokenInvalid(text))
						{
							text = $"Variant {num2 + 1}";
						}
						_modelSkinRow.AddButton(PanelController, val, text, string.Empty, _modelSkinRow.primaryColor, (UnityAction)delegate
						{
							//IL_0048: 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_007c: Expected O, but got Unknown
							//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
							LoadoutPanelSkinResolver loadoutPanelSkinResolver = default(LoadoutPanelSkinResolver);
							if (((Component)PanelController).TryGetComponent<LoadoutPanelSkinResolver>(ref loadoutPanelSkinResolver))
							{
								loadoutPanelSkinResolver.ModelSkin = skin;
								SkinDef resolvedSkin = loadoutPanelSkinResolver.ResolvedSkin;
								uint num3;
								if (Object.op_Implicit((Object)(object)resolvedSkin))
								{
									num3 = (uint)Mathf.Max(0, SkinCatalog.FindLocalSkinIndexForBody(bodyIndex, resolvedSkin));
								}
								else
								{
									Log.Error("Failed to resolve skin", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\Patches\\LoadoutPanelModifications.cs", "rebuildModelSkinRow", 531);
									num3 = 0u;
								}
								Loadout val3 = new Loadout();
								_modelSkinRow.userProfile.CopyLoadout(val3);
								val3.bodyLoadoutManager.SetSkinIndex(bodyIndex, num3);
								_modelSkinRow.userProfile.SetLoadout(val3);
							}
							else
							{
								Log.Error("Missing skin resolver", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\Patches\\LoadoutPanelModifications.cs", "rebuildModelSkinRow", 542);
							}
						}, string.Empty, (Node)null, false);
						reference = num2++;
					}
					_modelSkinRow.findCurrentChoice = delegate(Loadout loadout)
					{
						//IL_000c: 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)
						int skinIndex2 = (int)loadout.bodyLoadoutManager.GetSkinIndex(bodyIndex);
						return (skinIndex2 >= 0 && skinIndex2 < skins.Length && skins[skinIndex2] is ModelSwappedSkinDef modelSwappedSkinDef2) ? ArrayUtils.GetSafe<int>(buttonIndexLookup, SkinCatalog.FindLocalSkinIndexForBody(modelBodyIndex, modelSwappedSkinDef2.ModelSkin)) : 0;
					};
				}
				else
				{
					bodyIndex = (BodyIndex)(-1);
				}
				if (num2 == 0)
				{
					Row modelSkinRow = _modelSkinRow;
					LoadoutPanelController panelController = PanelController;
					Sprite fallbackSkinIcon = _fallbackSkinIcon;
					string empty = string.Empty;
					Color primaryColor = _modelSkinRow.primaryColor;
					object obj = <>c.<>9__10_0;
					if (obj == null)
					{
						UnityAction val2 = delegate
						{
						};
						<>c.<>9__10_0 = val2;
						obj = (object)val2;
					}
					modelSkinRow.AddButton(panelController, fallbackSkinIcon, "LOADOUT_MODEL_SKIN_FALLBACK", empty, primaryColor, (UnityAction)obj, string.Empty, (Node)null, false);
					_modelSkinRow.findCurrentChoice = (Loadout loadout) => 0;
				}
				_modelSkinRow.FinishSetup(false);
				if (num >= 0)
				{
					PanelController.rows[num] = _modelSkinRow;
				}
				else
				{
					PanelController.rows.Add(_modelSkinRow);
				}
				if (SkinTuner.IsActive)
				{
					((MonoBehaviour)this).StartCoroutine(waitThenSetSiblingIndex());
				}
				IEnumerator waitThenSetSiblingIndex()
				{
					yield return (object)new WaitForEndOfFrame();
					if (_modelSkinRow != null && Object.op_Implicit((Object)(object)_modelSkinRow.rowPanelTransform))
					{
						((Transform)_modelSkinRow.rowPanelTransform).SetSiblingIndex(3);
					}
				}
			}
		}

		private class LoadoutPanelSkinResolver : MonoBehaviour
		{
			private DisplayData _displayData = new DisplayData
			{
				bodyIndex = (BodyIndex)(-1),
				userProfile = null
			};

			private SkinDef _baseSkin;

			private BodyIndex _modelBodyIndex;

			private SkinDef _modelSkin;

			private SkinDef _resolvedSkin;

			private bool _resolvedSkinDirty;

			public DisplayData DisplayData
			{
				get
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					return _displayData;
				}
				set
				{
					//IL_0006: 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_0011: 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)
					//IL_00c8: 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_0038: Invalid comparison between Unknown and I4
					//IL_0043: 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_00bd: 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)
					if (((DisplayData)(ref _displayData)).Equals(value))
					{
						return;
					}
					_displayData = value;
					SkinDef baseSkin = null;
					BodyIndex modelBodyIndex = (BodyIndex)(-1);
					SkinDef modelSkin = null;
					if (_displayData.userProfile != null && (int)_displayData.bodyIndex != -1)
					{
						SkinDef[] bodySkins = BodyCatalog.GetBodySkins(_displayData.bodyIndex);
						if (bodySkins != null)
						{
							uint skinIndex = _displayData.userProfile.loadout.bodyLoadoutManager.GetSkinIndex(_displayData.bodyIndex);
							if (skinIndex < bodySkins.Length)
							{
								SkinDef val = bodySkins[skinIndex];
								if (val is ModelSwappedSkinDef modelSwappedSkinDef)
								{
									baseSkin = ArrayUtils.GetSafe<SkinDef>(((SkinDef)modelSwappedSkinDef).baseSkins, 0);
									modelBodyIndex = modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex;
									modelSkin = modelSwappedSkinDef.ModelSkin;
								}
								else
								{
									baseSkin = val;
									modelBodyIndex = (BodyIndex)(-1);
									modelSkin = null;
								}
							}
						}
					}
					BaseSkin = baseSkin;
					ModelBodyIndex = modelBodyIndex;
					ModelSkin = modelSkin;
					markResolvedSkinDirty();
				}
			}

			public SkinDef BaseSkin
			{
				get
				{
					return _baseSkin;
				}
				set
				{
					if (!((Object)(object)_baseSkin == (Object)(object)value))
					{
						_baseSkin = value;
						markResolvedSkinDirty();
					}
				}
			}

			public BodyIndex ModelBodyIndex
			{
				get
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					return _modelBodyIndex;
				}
				set
				{
					//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_000b: 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)
					if (_modelBodyIndex != value)
					{
						_modelBodyIndex = value;
						markResolvedSkinDirty();
					}
				}
			}

			public SkinDef ModelSkin
			{
				get
				{
					return _modelSkin;
				}
				set
				{
					if (!((Object)(object)_modelSkin == (Object)(object)value))
					{
						_modelSkin = value;
						markResolvedSkinDirty();
					}
				}
			}

			public int ModelSkinIndex
			{
				get
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					return SkinCatalog.FindLocalSkinIndexForBody(ModelBodyIndex, ModelSkin);
				}
				set
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					ModelSkin = SkinCatalog.GetBodySkinDef(ModelBodyIndex, value);
				}
			}

			public SkinDef ResolvedSkin
			{
				get
				{
					//IL_0035: Unknown result type (might be due to invalid IL or missing references)
					//IL_003b: Invalid comparison between Unknown and I4
					//IL_0041: Unknown result type (might be due to invalid IL or missing references)
					//IL_0047: Invalid comparison between Unknown and I4
					//IL_004f: 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_0094: Unknown result type (might be due to invalid IL or missing references)
					if (!Object.op_Implicit((Object)(object)_resolvedSkin) || _resolvedSkinDirty)
					{
						_resolvedSkin = null;
						if (_displayData.userProfile != null && (int)_displayData.bodyIndex != -1)
						{
							if ((int)ModelBodyIndex != -1)
							{
								SkinDef[] bodySkins = BodyCatalog.GetBodySkins(_displayData.bodyIndex);
								if (bodySkins != null)
								{
									SkinDef[] array = bodySkins;
									for (int i = 0; i < array.Length; i++)
									{
										if (array[i] is ModelSwappedSkinDef modelSwappedSkinDef && (Object)(object)BaseSkin == (Object)(object)ArrayUtils.GetSafe<SkinDef>(((SkinDef)modelSwappedSkinDef).baseSkins, 0) && ModelBodyIndex == modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex && (Object)(object)ModelSkin == (Object)(object)modelSwappedSkinDef.ModelSkin)
										{
											_resolvedSkin = (SkinDef)(object)modelSwappedSkinDef;
											break;
										}
									}
								}
							}
							else
							{
								_resolvedSkin = BaseSkin;
							}
						}
						_resolvedSkinDirty = false;
					}
					return _resolvedSkin;
				}
				set
				{
					//IL_0044: 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)
					if (value is ModelSwappedSkinDef modelSwappedSkinDef)
					{
						_baseSkin = ArrayUtils.GetSafe<SkinDef>(((SkinDef)modelSwappedSkinDef).baseSkins, 0);
						_modelBodyIndex = modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex;
						_modelSkin = modelSwappedSkinDef.ModelSkin;
					}
					else
					{
						_baseSkin = value;
						_modelBodyIndex = (BodyIndex)(-1);
						_modelSkin = null;
					}
					_resolvedSkin = value;
					_resolvedSkinDirty = false;
				}
			}

			private void markResolvedSkinDirty()
			{
				_resolvedSkinDirty = true;
			}

			private void OnEnable()
			{
				UserProfile.onLoadoutChangedGlobal += UserProfile_onLoadoutChangedGlobal;
			}

			private void OnDisable()
			{
				UserProfile.onLoadoutChangedGlobal -= UserProfile_onLoadoutChangedGlobal;
			}

			private void UserProfile_onLoadoutChangedGlobal(UserProfile userProfile)
			{
				//IL_001f: 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)
				if (_displayData.userProfile == userProfile)
				{
					uint skinIndex = userProfile.loadout.bodyLoadoutManager.GetSkinIndex(_displayData.bodyIndex);
					SkinDef bodySkinDef = SkinCatalog.GetBodySkinDef(_displayData.bodyIndex, (int)skinIndex);
					if ((Object)(object)_resolvedSkin != (Object)(object)bodySkinDef)
					{
						ResolvedSkin = bodySkinDef;
					}
				}
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_SetDisplayData <0>__LoadoutPanelController_SetDisplayData;

			public static Manipulator <1>__Row_FromSkin;

			public static hook_Rebuild <2>__LoadoutPanelController_Rebuild;
		}

		private static Sprite _fallbackSkinIcon;

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			Texture2D val = Addressables.LoadAssetAsync<Texture2D>((object)"RoR2/Base/Common/texSkinSwatches.png").WaitForCompletion();
			if (Object.op_Implicit((Object)(object)val))
			{
				_fallbackSkinIcon = Sprite.Create(val, new Rect(768f, 128f, 128f, 128f), Vector2.zero);
				((Object)_fallbackSkinIcon).name = "fallbackSkinIcon";
			}
			object obj = <>O.<0>__LoadoutPanelController_SetDisplayData;
			if (obj == null)
			{
				hook_SetDisplayData val2 = LoadoutPanelController_SetDisplayData;
				<>O.<0>__LoadoutPanelController_SetDisplayData = val2;
				obj = (object)val2;
			}
			LoadoutPanelController.SetDisplayData += (hook_SetDisplayData)obj;
			object obj2 = <>O.<1>__Row_FromSkin;
			if (obj2 == null)
			{
				Manipulator val3 = Row_FromSkin;
				<>O.<1>__Row_FromSkin = val3;
				obj2 = (object)val3;
			}
			Row.FromSkin += (Manipulator)obj2;
			if (!SkinTuner.IsActive)
			{
				object obj3 = <>O.<2>__LoadoutPanelController_Rebuild;
				if (obj3 == null)
				{
					hook_Rebuild val4 = LoadoutPanelController_Rebuild;
					<>O.<2>__LoadoutPanelController_Rebuild = val4;
					obj3 = (object)val4;
				}
				LoadoutPanelController.Rebuild += (hook_Rebuild)obj3;
			}
			else
			{
				patchSkinTuner();
			}
		}

		private static void patchSkinTuner()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			Assembly assembly = SkinTuner.Assembly;
			if (assembly == null)
			{
				throw new DllNotFoundException("Failed to load SkinTuner assembly");
			}
			Type type = assembly.GetType("SkinTuning.UI", throwOnError: false);
			if (type == null)
			{
				throw new TypeLoadException("Failed to find class 'SkinTuning.UI'");
			}
			MethodInfo? method = type.GetMethod("RebuildLoadoutPanels", BindingFlags.Instance | BindingFlags.NonPublic);
			if (method == null)
			{
				throw new MissingMethodException(type.FullName, "RebuildLoadoutPanels");
			}
			new Hook((MethodBase)method, (Delegate)(Action<Action<MonoBehaviour, orig_Rebuild, LoadoutPanelController>, MonoBehaviour, orig_Rebuild, LoadoutPanelController>)delegate(Action<MonoBehaviour, orig_Rebuild, LoadoutPanelController> patchOrig, MonoBehaviour patchSelf, orig_Rebuild orig, LoadoutPanelController self)
			{
				patchOrig(patchSelf, orig, self);
				tryRebuildLoadoutPanel(self);
			});
		}

		private static bool shouldModifyLoadoutPanel(LoadoutPanelController loadoutPanel)
		{
			if (SkinTuner.IsActive)
			{
				return ((Object)loadoutPanel).name == "SkinPanel";
			}
			return true;
		}

		private static void LoadoutPanelController_SetDisplayData(orig_SetDisplayData orig, LoadoutPanelController self, DisplayData displayData)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (shouldModifyLoadoutPanel(self))
			{
				LoadoutPanelSkinResolver loadoutPanelSkinResolver = default(LoadoutPanelSkinResolver);
				if (!((Component)self).TryGetComponent<LoadoutPanelSkinResolver>(ref loadoutPanelSkinResolver))
				{
					loadoutPanelSkinResolver = ((Component)self).gameObject.AddComponent<LoadoutPanelSkinResolver>();
				}
				loadoutPanelSkinResolver.DisplayData = displayData;
			}
			orig.Invoke(self, displayData);
		}

		private static void Row_FromSkin(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			VariableDefinition val2 = new VariableDefinition(il.Import(typeof(Row)));
			il.Body.Variables.Add(val2);
			VariableDefinition val3 = new VariableDefinition(il.Import(typeof(uint)));
			il.Body.Variables.Add(val3);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchNewobj<Row>(x)
			}))
			{
				val.Emit(OpCodes.Dup);
				val.Emit(OpCodes.Stloc, val2);
				val.Index = 0;
				FieldReference val7 = default(FieldReference);
				if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchStfld(x, ref val7) && ((MemberReference)val7).Name == "skinToAssign"
				}))
				{
					val.Emit(OpCodes.Dup);
					val.Emit(OpCodes.Stloc, val3);
					val.Index = 0;
					if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => BodyCatalog.GetBodySkins((BodyIndex)0))))
					}))
					{
						val.EmitDelegate<Func<SkinDef[], SkinDef[]>>((Func<SkinDef[], SkinDef[]>)delegate(SkinDef[] skins)
						{
							List<SkinDef> list = new List<SkinDef>(skins.Length);
							bool flag = false;
							foreach (SkinDef val6 in skins)
							{
								if (!(val6 is ModelSwappedSkinDef))
								{
									list.Add(val6);
								}
								else
								{
									flag = true;
								}
							}
							return (!flag) ? skins : list.ToArray();
						});
						val.Index = 0;
						if (val.TryGotoNext(new Func<Instruction, bool>[1]
						{
							(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Row>(x, "AddButton")
						}))
						{
							ILCursor[] array = default(ILCursor[]);
							MethodReference val5 = default(MethodReference);
							if (val.TryFindPrev(ref array, new Func<Instruction, bool>[2]
							{
								(Instruction x) => ILPatternMatchingExt.MatchLdftn(x, ref val5),
								(Instruction x) => ILPatternMatchingExt.MatchNewobj<UnityAction>(x)
							}))
							{
								ILCursor obj = array[1];
								int index = obj.Index;
								obj.Index = index + 1;
								obj.Emit(OpCodes.Ldarg_0);
								obj.Emit(OpCodes.Ldarg_1);
								obj.Emit(OpCodes.Ldloc, val2);
								obj.Emit(OpCodes.Ldloc, val3);
								obj.EmitDelegate<Func<UnityAction, LoadoutPanelController, BodyIndex, Row, uint, UnityAction>>((Func<UnityAction, LoadoutPanelController, BodyIndex, Row, uint, UnityAction>)((UnityAction buttonCallback, LoadoutPanelController loadoutPanelController, BodyIndex bodyIndex, Row row, uint skinToAssign) => (UnityAction)(shouldModifyLoadoutPanel(loadoutPanelController) ? ((object)(Unity