Decompiled source of Sims Cosmetics v1.0.0

BepInEx/plugins/Omniscye-Sims_Cosmetics/EmpressSimsCosmetics.dll

Decompiled 16 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using REPOLib.Modules;
using UnityEngine;

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

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EmpressSimsCosmetics
{
	[BepInPlugin("com.empress.repo.simscosmetics", "Empress Sims Cosmetics", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class EmpressSimsCosmeticsPlugin : BaseUnityPlugin
	{
		private readonly struct FitProfile
		{
			public float Side { get; }

			public float Up { get; }

			public float Forward { get; }

			public float Scale { get; }

			public float Pitch { get; }

			public float Yaw { get; }

			public float Roll { get; }

			public FitProfile(float side = 0f, float up = 0f, float forward = 0f, float scale = 1f, float pitch = 0f, float yaw = 0f, float roll = 0f)
			{
				Side = side;
				Up = up;
				Forward = forward;
				Scale = scale;
				Pitch = pitch;
				Yaw = yaw;
				Roll = roll;
			}
		}

		private const string PluginGuid = "com.empress.repo.simscosmetics";

		private const string PluginName = "Empress Sims Cosmetics";

		private const string PluginVersion = "1.0.0";

		private const string AssetPrefix = "empress.simscosmetics";

		private static readonly string[] BundleSearchPatterns = new string[2] { "*.empress", "*.bundle" };

		private static readonly Dictionary<string, FitProfile> FitProfiles = new Dictionary<string, FitProfile>(StringComparer.OrdinalIgnoreCase);

		private static readonly FitProfile DefaultFitProfile = new FitProfile(0f, 0f, 0f, 1f, 0f, 0f, 0f);

		internal static ManualLogSource Log = null;

		internal static EmpressSimsCosmeticsPlugin Instance = null;

		private static readonly FieldRef<CosmeticAsset, Status> CosmeticAssetStatusRef = AccessTools.FieldRefAccess<CosmeticAsset, Status>("status");

		private static readonly FieldRef<CosmeticAsset, string> CosmeticAssetNameRef = AccessTools.FieldRefAccess<CosmeticAsset, string>("assetName");

		private static readonly FieldRef<CosmeticAsset, string> CosmeticAssetIdRef = AccessTools.FieldRefAccess<CosmeticAsset, string>("assetId");

		private static readonly FieldRef<CosmeticAsset, CosmeticType> CosmeticAssetTypeRef = AccessTools.FieldRefAccess<CosmeticAsset, CosmeticType>("type");

		private static readonly FieldRef<CosmeticAsset, Rarity> CosmeticAssetRarityRef = AccessTools.FieldRefAccess<CosmeticAsset, Rarity>("rarity");

		private static readonly FieldRef<CosmeticAsset, PrefabRef> CosmeticAssetPrefabRef = AccessTools.FieldRefAccess<CosmeticAsset, PrefabRef>("prefab");

		private static readonly FieldRef<CosmeticAsset, List<Type>> CosmeticAssetCustomTypesRef = AccessTools.FieldRefAccess<CosmeticAsset, List<Type>>("customTypeList");

		private static readonly FieldRef<CosmeticAsset, bool> CosmeticAssetTintableRef = AccessTools.FieldRefAccess<CosmeticAsset, bool>("tintable");

		private static readonly FieldRef<CosmeticAsset, SemiColor> CosmeticAssetDefaultColorRef = AccessTools.FieldRefAccess<CosmeticAsset, SemiColor>("defaultColor");

		private static readonly FieldRef<Cosmetic, CosmeticType> CosmeticTypeRef = AccessTools.FieldRefAccess<Cosmetic, CosmeticType>("type");

		private static readonly FieldRef<Cosmetic, Rarity> CosmeticRarityRef = AccessTools.FieldRefAccess<Cosmetic, Rarity>("rarity");

		private static readonly FieldRef<Cosmetic, List<Transform>> CosmeticMeshParentsRef = AccessTools.FieldRefAccess<Cosmetic, List<Transform>>("meshParents");

		private static readonly FieldRef<CosmeticPlayerCrown, Transform> CrownTargetMainRef = AccessTools.FieldRefAccess<CosmeticPlayerCrown, Transform>("targetMain");

		private static readonly FieldRef<CosmeticPlayerCrown, int> CrownPriorityRef = AccessTools.FieldRefAccess<CosmeticPlayerCrown, int>("priority");

		private static readonly FieldRef<PlayerMaterial, bool> PlayerMaterialTintableRef = AccessTools.FieldRefAccess<PlayerMaterial, bool>("tintable");

		private static readonly FieldRef<PlayerMaterial, CosmeticType> PlayerMaterialCosmeticTypeRef = AccessTools.FieldRefAccess<PlayerMaterial, CosmeticType>("cosmeticType");

		private static readonly FieldRef<SemiIconMaker, Camera> IconMakerCameraRef = AccessTools.FieldRefAccess<SemiIconMaker, Camera>("iconCamera");

		private static readonly FieldRef<SemiIconMaker, RenderTexture> IconMakerRenderTextureRef = AccessTools.FieldRefAccess<SemiIconMaker, RenderTexture>("renderTexture");

		private static readonly FieldRef<SemiIconMaker, Color> IconMakerAmbientLightRef = AccessTools.FieldRefAccess<SemiIconMaker, Color>("ambientLight");

		private static readonly FieldRef<MetaManager, List<CosmeticAsset>> MetaCosmeticAssetsRef = AccessTools.FieldRefAccess<MetaManager, List<CosmeticAsset>>("cosmeticAssets");

		private static readonly FieldRef<MetaManager, List<SemiColor>> MetaColorsRef = AccessTools.FieldRefAccess<MetaManager, List<SemiColor>>("colors");

		private static readonly FieldRef<MetaManager, List<int>> MetaCosmeticUnlocksRef = AccessTools.FieldRefAccess<MetaManager, List<int>>("cosmeticUnlocks");

		private static readonly FieldRef<MetaManager, List<int>> MetaCosmeticHistoryRef = AccessTools.FieldRefAccess<MetaManager, List<int>>("cosmeticHistory");

		private readonly List<AssetBundle> _loadedBundles = new List<AssetBundle>();

		private readonly Dictionary<string, CosmeticAsset> _registeredAssets = new Dictionary<string, CosmeticAsset>(StringComparer.Ordinal);

		private GameObject? _prefabVault;

		private ConfigEntry<float> _hatMaxSize;

		private ConfigEntry<float> _hatHeadLift;

		private ConfigEntry<float> _hatHeightOffset;

		private ConfigEntry<float> _hatForwardOffset;

		private ConfigEntry<float> _hatSideOffset;

		private ConfigEntry<float> _modelYaw;

		private ConfigEntry<float> _modelPitch;

		private ConfigEntry<float> _modelRoll;

		private ConfigEntry<string> _rarity;

		private ConfigEntry<bool> _autoUnlock;

		private ConfigEntry<bool> _markAutoUnlockedAsSeen;

		private ConfigEntry<bool> _resetUnlocksNow;

		private bool _autoUnlockPending = true;

		internal float WorldUp => _hatHeadLift.Value + _hatHeightOffset.Value;

		internal float WorldForward => _hatForwardOffset.Value;

		internal float WorldSide => _hatSideOffset.Value;

		private void Awake()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Expected O, but got Unknown
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Expected O, but got Unknown
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Expected O, but got Unknown
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			_hatMaxSize = ((BaseUnityPlugin)this).Config.Bind<float>("Fit", "MaxSize", 0.45f, new ConfigDescription("Largest dimension (in REPO units) the fitted Sims cosmetic may occupy above the head.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 3f), Array.Empty<object>()));
			_hatHeadLift = ((BaseUnityPlugin)this).Config.Bind<float>("Fit", "HeadLift", 0.42f, new ConfigDescription("Base vertical lift so the diamond sits above the head.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			_hatHeightOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Fit", "HeightOffset", 0f, new ConfigDescription("Extra vertical fine-tuning above the head placement.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 0.5f), Array.Empty<object>()));
			_hatForwardOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Fit", "ForwardOffset", 0f, new ConfigDescription("Moves the model forward(+)/back(-) on the head.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.75f, 0.75f), Array.Empty<object>()));
			_hatSideOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Fit", "SideOffset", 0f, new ConfigDescription("Moves the model right(+)/left(-) on the head.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.75f, 0.75f), Array.Empty<object>()));
			_modelYaw = ((BaseUnityPlugin)this).Config.Bind<float>("Fit", "ModelYaw", 0f, new ConfigDescription("Yaw rotation (degrees) applied to the model so it faces the same way as the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>()));
			_modelPitch = ((BaseUnityPlugin)this).Config.Bind<float>("Fit", "ModelPitch", 0f, new ConfigDescription("Pitch rotation (degrees) applied to every model before per-Sims tuning.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>()));
			_modelRoll = ((BaseUnityPlugin)this).Config.Bind<float>("Fit", "ModelRoll", 0f, new ConfigDescription("Roll rotation (degrees) applied to every model before per-Sims tuning.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>()));
			_rarity = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Rarity", "Rare", new ConfigDescription("Rarity bucket for the cosmetic box / colour outline.", (AcceptableValueBase)(object)new AcceptableValueList<string>(Enum.GetNames(typeof(Rarity))), Array.Empty<object>()));
			_autoUnlock = ((BaseUnityPlugin)this).Config.Bind<bool>("Unlocks", "AutoUnlock", false, "Automatically unlock the Sims cosmetics so they are selectable in Customize without opening cosmetic boxes.");
			_markAutoUnlockedAsSeen = ((BaseUnityPlugin)this).Config.Bind<bool>("Unlocks", "MarkAsSeen", true, "Mark auto-unlocked cosmetics as already seen so Customize doesn't flag every one as new.");
			_resetUnlocksNow = ((BaseUnityPlugin)this).Config.Bind<bool>("Unlocks", "ResetModUnlocksNow", false, "Set to true to remove only Empress Sims Cosmetics unlocks from this save. It turns itself back off after running.");
			try
			{
				((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			}
			catch
			{
			}
			int num = LoadAndRegisterAllBundles();
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Registered {2} Sims cosmetic(s).", "Empress Sims Cosmetics", "1.0.0", num));
			((MonoBehaviour)this).StartCoroutine(AutoUnlockLoop());
		}

		private Rarity SelectedRarity()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!Enum.TryParse<Rarity>(_rarity.Value, out Rarity result))
			{
				return (Rarity)2;
			}
			return result;
		}

		private string CosmeticsDirectory()
		{
			string text = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? Paths.PluginPath;
			string text2 = Path.Combine(text, "cosmetics");
			if (!Directory.Exists(text2))
			{
				return text;
			}
			return text2;
		}

		private int LoadAndRegisterAllBundles()
		{
			string text = CosmeticsDirectory();
			string[] array;
			try
			{
				array = FindBundleFiles(text);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Could not enumerate cosmetics in '" + text + "': " + ex.GetBaseException().Message));
				return 0;
			}
			if (array.Length == 0)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("No .empress or .bundle files found in '" + text + "'. Nothing to register."));
				return 0;
			}
			Array.Sort(array, (IComparer<string>?)StringComparer.Ordinal);
			int num = 0;
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				try
				{
					if (TryRegisterBundle(text2))
					{
						num++;
					}
				}
				catch (Exception ex2)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load '" + Path.GetFileName(text2) + "': " + ex2.GetBaseException().Message));
				}
			}
			return num;
		}

		private static string[] FindBundleFiles(string dir)
		{
			string[] bundleSearchPatterns = BundleSearchPatterns;
			foreach (string searchPattern in bundleSearchPatterns)
			{
				string[] files = Directory.GetFiles(dir, searchPattern, SearchOption.TopDirectoryOnly);
				if (files.Length != 0)
				{
					return files;
				}
			}
			return Array.Empty<string>();
		}

		private bool TryRegisterBundle(string file)
		{
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file);
			AssetBundle val = AssetBundle.LoadFromFile(file);
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Unity refused to load bundle '" + Path.GetFileName(file) + "' (possible CAB id clash)."));
				return false;
			}
			GameObject val2 = FindCosmeticPrefab(val);
			if ((Object)(object)val2 == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("No cosmetic prefab found inside '" + Path.GetFileName(file) + "'."));
				val.Unload(false);
				return false;
			}
			string text = DisplayNameForBundle(fileNameWithoutExtension, val2);
			string text2 = "empress.simscosmetics:" + StableKey(text);
			if (_registeredAssets.ContainsKey(text2))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Skipping duplicate Sims cosmetic ID '" + text2 + "' from '" + Path.GetFileName(file) + "'."));
				val.Unload(false);
				return false;
			}
			_loadedBundles.Add(val);
			GameObject val3 = BuildCosmeticPrefab(val2, text);
			if ((Object)(object)val3 == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("'" + text + "' has no usable renderer; skipped."));
				return false;
			}
			PrefabRef val4 = NetworkPrefabs.RegisterNetworkPrefab("Cosmetics/" + ((Object)val3).name, val3);
			if (val4 == null)
			{
				val3.SetActive(false);
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Network prefab registration failed for '" + text + "'."));
				return false;
			}
			CosmeticAsset val5 = ScriptableObject.CreateInstance<CosmeticAsset>();
			((Object)val5).name = ((Object)val3).name;
			ConfigureCosmeticAsset(val5, ((Object)val3).name, text2, SelectedRarity(), val4);
			Cosmetics.RegisterCosmetic(val5);
			_registeredAssets[text2] = val5;
			_autoUnlockPending = true;
			return true;
		}

		private static GameObject? FindCosmeticPrefab(AssetBundle bundle)
		{
			GameObject[] source = bundle.LoadAllAssets<GameObject>();
			GameObject val = ((IEnumerable<GameObject>)source).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => (Object)(object)go != (Object)null && ((Object)go).name.IndexOf("(DO NOT MOVE)", StringComparison.OrdinalIgnoreCase) >= 0));
			if (val == null)
			{
				val = ((IEnumerable<GameObject>)source).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => (Object)(object)go != (Object)null && go.GetComponentsInChildren<Renderer>(true).Length != 0));
			}
			return val;
		}

		private GameObject? BuildCosmeticPrefab(GameObject modelPrefab, string displayName)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected I4, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: 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_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Expected O, but got Unknown
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			FitProfile fitProfile = FitProfileFor(displayName);
			GameObject val = new GameObject("Sims Hat - " + displayName);
			val.transform.SetParent(GetPrefabVault().transform, false);
			((Object)val).hideFlags = (HideFlags)61;
			Cosmetic val2 = val.AddComponent<Cosmetic>();
			CosmeticTypeRef.Invoke(val2) = (CosmeticType)0;
			CosmeticRarityRef.Invoke(val2) = (Rarity)(int)SelectedRarity();
			CosmeticMeshParentsRef.Invoke(val2) = new List<Transform>();
			GameObject val3 = new GameObject("MeshParent");
			val3.transform.SetParent(val.transform, false);
			CosmeticMeshParentsRef.Invoke(val2).Add(val3.transform);
			GameObject val4 = new GameObject("Visual");
			val4.transform.SetParent(val3.transform, false);
			GameObject val5 = Object.Instantiate<GameObject>(modelPrefab, val4.transform);
			((Object)val5).name = "Model";
			val5.transform.localPosition = Vector3.zero;
			val5.transform.localRotation = Quaternion.Euler(_modelPitch.Value + fitProfile.Pitch, _modelYaw.Value + fitProfile.Yaw, _modelRoll.Value + fitProfile.Roll);
			val5.transform.localScale = Vector3.one;
			List<Bounds> list = new List<Bounds>();
			int num = 0;
			SkinnedMeshRenderer[] componentsInChildren = val5.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val6 in componentsInChildren)
			{
				if (!((Object)(object)val6 == (Object)null) && !((Object)(object)val6.sharedMesh == (Object)null))
				{
					val6.updateWhenOffscreen = true;
					EnsurePlayerMaterial(((Component)val6).gameObject);
					AccumulateBounds(list, val4.transform, ((Component)val6).transform, val6.sharedMesh.bounds);
					num++;
				}
			}
			MeshRenderer[] componentsInChildren2 = val5.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val7 in componentsInChildren2)
			{
				MeshFilter component = ((Component)val7).GetComponent<MeshFilter>();
				if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null))
				{
					EnsurePlayerMaterial(((Component)val7).gameObject);
					AccumulateBounds(list, val4.transform, ((Component)val7).transform, component.sharedMesh.bounds);
					num++;
				}
			}
			if (num == 0 || list.Count == 0)
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			Animator[] componentsInChildren3 = val5.GetComponentsInChildren<Animator>(true);
			foreach (Animator obj in componentsInChildren3)
			{
				obj.cullingMode = (AnimatorCullingMode)0;
				((Behaviour)obj).enabled = true;
			}
			Bounds sourceBounds = list[0];
			for (int j = 1; j < list.Count; j++)
			{
				((Bounds)(ref sourceBounds)).Encapsulate(list[j]);
			}
			float num2 = Mathf.Max(new float[3]
			{
				((Bounds)(ref sourceBounds)).size.x,
				((Bounds)(ref sourceBounds)).size.y,
				((Bounds)(ref sourceBounds)).size.z
			});
			float num3 = ((num2 > 0.001f) ? Mathf.Clamp(_hatMaxSize.Value * fitProfile.Scale / num2, 0.01f, 20f) : 1f);
			float num4 = (0f - ((Bounds)(ref sourceBounds)).center.x) * num3 + fitProfile.Side;
			float num5 = (0f - ((Bounds)(ref sourceBounds)).min.y) * num3 + fitProfile.Up;
			float num6 = (0f - ((Bounds)(ref sourceBounds)).center.z) * num3 + fitProfile.Forward;
			val4.transform.localScale = Vector3.one * num3;
			val4.transform.localPosition = new Vector3(num4, num5, num6);
			val.AddComponent<SimsHeadFollower>().Initialize(val4.transform);
			GameObject val8 = new GameObject("CrownTarget");
			val8.transform.SetParent(val3.transform, false);
			val8.transform.localPosition = new Vector3(num4, num5 + ((Bounds)(ref sourceBounds)).max.y * num3 + 0.03f, num6);
			CosmeticPlayerCrown val9 = val8.AddComponent<CosmeticPlayerCrown>();
			CrownTargetMainRef.Invoke(val9) = val8.transform;
			CrownPriorityRef.Invoke(val9) = 0;
			AddIconMaker(val.transform, sourceBounds, num3);
			val.SetActive(true);
			return val;
		}

		private void EnsurePlayerMaterial(GameObject host)
		{
			PlayerMaterial val = host.GetComponent<PlayerMaterial>();
			if ((Object)(object)val == (Object)null)
			{
				val = host.AddComponent<PlayerMaterial>();
			}
			PlayerMaterialTintableRef.Invoke(val) = false;
			PlayerMaterialCosmeticTypeRef.Invoke(val) = (CosmeticType)0;
		}

		private static void AccumulateBounds(List<Bounds> bounds, Transform modelRoot, Transform rendererTransform, Bounds meshLocalBounds)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			Vector3 min = ((Bounds)(ref meshLocalBounds)).min;
			Vector3 max = ((Bounds)(ref meshLocalBounds)).max;
			Vector3 val = modelRoot.InverseTransformPoint(rendererTransform.TransformPoint(min));
			Bounds item = default(Bounds);
			((Bounds)(ref item))..ctor(val, Vector3.zero);
			Vector3 val2 = default(Vector3);
			for (int i = 0; i <= 1; i++)
			{
				for (int j = 0; j <= 1; j++)
				{
					for (int k = 0; k <= 1; k++)
					{
						((Vector3)(ref val2))..ctor((i == 0) ? min.x : max.x, (j == 0) ? min.y : max.y, (k == 0) ? min.z : max.z);
						((Bounds)(ref item)).Encapsulate(modelRoot.InverseTransformPoint(rendererTransform.TransformPoint(val2)));
					}
				}
			}
			bounds.Add(item);
		}

		private GameObject GetPrefabVault()
		{
			//IL_001b: 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_002d: Expected O, but got Unknown
			if ((Object)(object)_prefabVault != (Object)null)
			{
				return _prefabVault;
			}
			_prefabVault = new GameObject("EmpressSimsCosmetics.PrefabVault")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)(object)_prefabVault);
			_prefabVault.SetActive(false);
			return _prefabVault;
		}

		private void AddIconMaker(Transform root, Bounds sourceBounds, float fitScale)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SemiIconMaker");
			val.transform.SetParent(root, false);
			val.SetActive(false);
			Camera val2 = val.AddComponent<Camera>();
			val2.orthographic = true;
			val2.orthographicSize = Mathf.Clamp(Mathf.Max(((Bounds)(ref sourceBounds)).size.x, ((Bounds)(ref sourceBounds)).size.y) * fitScale * 0.7f, 0.25f, 2f);
			val2.nearClipPlane = 0.01f;
			val2.farClipPlane = 10f;
			val2.clearFlags = (CameraClearFlags)2;
			val2.backgroundColor = new Color(0f, 0f, 0f, 0f);
			((Behaviour)val2).enabled = false;
			val.transform.localPosition = new Vector3(0f, 0.25f, -2f);
			val.transform.localRotation = Quaternion.identity;
			SemiIconMaker val3 = val.AddComponent<SemiIconMaker>();
			IconMakerCameraRef.Invoke(val3) = val2;
			IconMakerRenderTextureRef.Invoke(val3) = new RenderTexture(256, 256, 16, (RenderTextureFormat)0)
			{
				name = "EmpressSimsCosmeticsIcon"
			};
			IconMakerAmbientLightRef.Invoke(val3) = Color.white;
		}

		private void ConfigureCosmeticAsset(CosmeticAsset cosmeticAsset, string assetName, string assetId, Rarity rarity, PrefabRef prefabRef)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected I4, but got Unknown
			CosmeticAssetNameRef.Invoke(cosmeticAsset) = assetName;
			CosmeticAssetIdRef.Invoke(cosmeticAsset) = assetId;
			CosmeticAssetStatusRef.Invoke(cosmeticAsset) = (Status)3;
			CosmeticAssetTypeRef.Invoke(cosmeticAsset) = (CosmeticType)0;
			CosmeticAssetRarityRef.Invoke(cosmeticAsset) = (Rarity)(int)rarity;
			CosmeticAssetPrefabRef.Invoke(cosmeticAsset) = prefabRef;
			CosmeticAssetCustomTypesRef.Invoke(cosmeticAsset) = new List<Type>();
			CosmeticAssetTintableRef.Invoke(cosmeticAsset) = false;
			List<SemiColor> list = (((Object)(object)MetaManager.instance != (Object)null) ? MetaColorsRef.Invoke(MetaManager.instance) : null);
			CosmeticAssetDefaultColorRef.Invoke(cosmeticAsset) = ((list != null && list.Count > 0) ? list[0] : null);
		}

		private IEnumerator AutoUnlockLoop()
		{
			while (true)
			{
				if (_resetUnlocksNow.Value)
				{
					TryResetModUnlocks();
				}
				if (_autoUnlockPending)
				{
					TryAutoUnlock();
				}
				yield return (object)new WaitForSecondsRealtime(2f);
			}
		}

		private void TryAutoUnlock()
		{
			if (!_autoUnlock.Value)
			{
				_autoUnlockPending = false;
			}
			else
			{
				if ((Object)(object)MetaManager.instance == (Object)null || _registeredAssets.Count == 0)
				{
					return;
				}
				List<CosmeticAsset> list = MetaCosmeticAssetsRef.Invoke(MetaManager.instance);
				List<int> list2 = MetaCosmeticUnlocksRef.Invoke(MetaManager.instance);
				List<int> list3 = MetaCosmeticHistoryRef.Invoke(MetaManager.instance);
				if (list == null || list2 == null || list3 == null)
				{
					return;
				}
				bool flag = false;
				foreach (CosmeticAsset value in _registeredAssets.Values)
				{
					int num = list.IndexOf(value);
					if (num < 0)
					{
						return;
					}
					if (!list2.Contains(num))
					{
						list2.Add(num);
						flag = true;
					}
					if (_markAutoUnlockedAsSeen.Value && !list3.Contains(num))
					{
						list3.Add(num);
						flag = true;
					}
				}
				_autoUnlockPending = false;
				if (flag)
				{
					MetaManager.instance.Save();
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Auto-unlocked Sims cosmetics for Customize.");
				}
			}
		}

		private void TryResetModUnlocks()
		{
			if ((Object)(object)MetaManager.instance == (Object)null || _registeredAssets.Count == 0)
			{
				return;
			}
			List<CosmeticAsset> list = MetaCosmeticAssetsRef.Invoke(MetaManager.instance);
			List<int> list2 = MetaCosmeticUnlocksRef.Invoke(MetaManager.instance);
			List<int> list3 = MetaCosmeticHistoryRef.Invoke(MetaManager.instance);
			if (list == null || list2 == null || list3 == null)
			{
				return;
			}
			HashSet<int> hashSet = new HashSet<int>();
			foreach (CosmeticAsset value in _registeredAssets.Values)
			{
				int num = list.IndexOf(value);
				if (num >= 0)
				{
					hashSet.Add(num);
				}
			}
			if (hashSet.Count >= _registeredAssets.Count)
			{
				int num2 = list2.RemoveAll(hashSet.Contains);
				int num3 = list3.RemoveAll(hashSet.Contains);
				_resetUnlocksNow.Value = false;
				((BaseUnityPlugin)this).Config.Save();
				if (num2 > 0 || num3 > 0)
				{
					MetaManager.instance.Save();
					((BaseUnityPlugin)this).Logger.LogInfo((object)$"Reset {num2} Sims cosmetic unlock(s) for testing.");
				}
			}
		}

		private static string StableKey(string value)
		{
			return new string((value ?? string.Empty).Select((char c) => (!char.IsLetterOrDigit(c)) ? '_' : char.ToLowerInvariant(c)).ToArray()).Trim('_');
		}

		private static FitProfile FitProfileFor(string displayName)
		{
			string text = CompactKey(displayName);
			if (text.StartsWith("empress", StringComparison.Ordinal))
			{
				text = text.Substring("empress".Length);
			}
			if (!FitProfiles.TryGetValue(text, out var value))
			{
				return DefaultFitProfile;
			}
			return value;
		}

		private static string CompactKey(string value)
		{
			return new string((value ?? string.Empty).Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray());
		}

		private static string DisplayNameForBundle(string stem, GameObject modelPrefab)
		{
			string text = (((Object)(object)modelPrefab != (Object)null) ? ((Object)modelPrefab).name : string.Empty);
			if (text.StartsWith("Empress", StringComparison.Ordinal))
			{
				return PrettifyName(text);
			}
			if (IsNumberedSimsBundle(stem) && !string.IsNullOrWhiteSpace(text))
			{
				return PrettifyName(text);
			}
			return PrettifyName(stem);
		}

		private static bool IsNumberedSimsBundle(string stem)
		{
			if (stem.StartsWith("sims", StringComparison.OrdinalIgnoreCase) && stem.Length > "sims".Length)
			{
				return stem.Skip("sims".Length).All(char.IsDigit);
			}
			return false;
		}

		private static string PrettifyName(string value)
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return "Sims";
			}
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < value.Length; i++)
			{
				char c = value[i];
				if (i > 0 && char.IsUpper(c) && !char.IsUpper(value[i - 1]))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(c);
			}
			return stringBuilder.ToString();
		}
	}
	public sealed class SimsHeadFollower : MonoBehaviour
	{
		private static readonly FieldRef<PlayerAvatarVisuals, Transform> HeadAnchorRef = AccessTools.FieldRefAccess<PlayerAvatarVisuals, Transform>("attachPointTopHeadMiddle");

		[SerializeField]
		private Transform _visual;

		private Vector3 _localPosition;

		private Quaternion _localRotation;

		private Vector3 _localScale;

		private bool _captured;

		private PlayerAvatarVisuals? _visuals;

		public void Initialize(Transform visual)
		{
			_visual = visual;
		}

		private void LateUpdate()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_00df: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_visual == (Object)null)
			{
				return;
			}
			if (!_captured)
			{
				_localPosition = _visual.localPosition;
				_localRotation = _visual.localRotation;
				_localScale = _visual.localScale;
				_captured = true;
			}
			if ((Object)(object)_visuals == (Object)null)
			{
				_visuals = ((Component)this).GetComponentInParent<PlayerAvatarVisuals>();
				if ((Object)(object)_visuals == (Object)null)
				{
					return;
				}
			}
			Transform val = HeadAnchorRef.Invoke(_visuals);
			if (!((Object)(object)val == (Object)null))
			{
				if ((Object)(object)_visual.parent != (Object)(object)val)
				{
					_visual.SetParent(val, false);
				}
				_visual.localPosition = _localPosition;
				_visual.localRotation = _localRotation;
				_visual.localScale = _localScale;
				EmpressSimsCosmeticsPlugin instance = EmpressSimsCosmeticsPlugin.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					Transform visual = _visual;
					visual.position += val.up * instance.WorldUp + val.forward * instance.WorldForward + val.right * instance.WorldSide;
				}
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)_visual != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_visual).gameObject);
			}
		}
	}
}