Decompiled source of Skins v0.5.3

Skins.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CellMenu;
using Clonesoft.Json;
using Clonesoft.Json.Linq;
using Clonesoft.Json.Serialization;
using FluffyUnderware.DevTools.Extensions;
using GameData;
using Gear;
using Globals;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Localization;
using MTFO.API;
using Microsoft.CodeAnalysis;
using Player;
using Skins.Config;
using Skins.Data;
using Skins.Interop;
using Skins.Localization;
using Skins.Manifest;
using Skins.Patches;
using Skins.Target;
using Skins.Textures;
using Skins.UI;
using Skins.UI.Menu;
using Skins.Utils;
using Skins.Utils.Ext;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Skins")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Skins")]
[assembly: AssemblyTitle("Skins")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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;
		}
	}
}
namespace Skins
{
	[HarmonyPatch]
	public class Events
	{
		public static event Action? OnGameDataInitialized;

		public static event Action<Item>? OnGearSpawnComplete;

		[HarmonyPatch(typeof(GameDataInit), "Initialize")]
		[HarmonyPostfix]
		public static void Postfix__GameDataInit_Initialize()
		{
			Events.OnGameDataInitialized?.Invoke();
		}

		[HarmonyPatch(typeof(Item), "OnGearSpawnComplete")]
		[HarmonyPostfix]
		public static void Postfix__Item_OnGearSpawnComplete(Item __instance)
		{
			Events.OnGearSpawnComplete?.Invoke(__instance);
		}

		[HarmonyPatch(typeof(ItemEquippable), "OnGearSpawnComplete")]
		[HarmonyPostfix]
		public static void Postfix__ItemEquippable_OnGearSpawnComplete(Item __instance)
		{
			Events.OnGearSpawnComplete?.Invoke(__instance);
		}
	}
	internal static class Logger
	{
		private static ManualLogSource _mLogSource;

		public static bool Ready => _mLogSource != null;

		public static void Setup()
		{
			_mLogSource = Logger.CreateLogSource("io.takina.gtfo.Skins");
		}

		public static void SetupFromInit(ManualLogSource logSource)
		{
			_mLogSource = logSource;
		}

		private static string Format(object data)
		{
			return data.ToString();
		}

		public static void Debug(object msg)
		{
			if (ConfigMgr.Debug)
			{
				_mLogSource.LogDebug((object)Format(msg));
			}
		}

		public static void Debugf(string fmt, params object[] args)
		{
			if (ConfigMgr.Debug)
			{
				_mLogSource.LogDebug((object)Format(string.Format(fmt, args)));
			}
		}

		public static void Info(object msg)
		{
			_mLogSource.LogInfo((object)Format(msg));
		}

		public static void Infof(string fmt, params object[] args)
		{
			_mLogSource.LogInfo((object)Format(string.Format(fmt, args)));
		}

		public static void Warn(object msg)
		{
			_mLogSource.LogWarning((object)Format(msg));
		}

		public static void Warnf(string fmt, params object[] args)
		{
			_mLogSource.LogWarning((object)Format(string.Format(fmt, args)));
		}

		public static void Error(object msg)
		{
			_mLogSource.LogError((object)Format(msg));
		}

		public static void Errorf(string fmt, params object[] args)
		{
			_mLogSource.LogError((object)Format(string.Format(fmt, args)));
		}

		public static void Fatal(object msg)
		{
			_mLogSource.LogFatal((object)Format(msg));
		}

		public static void Fatalf(string fmt, params object[] args)
		{
			_mLogSource.LogFatal((object)Format(string.Format(fmt, args)));
		}
	}
	[BepInPlugin("io.takina.gtfo.Skins", "Skins", "0.5.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BasePlugin
	{
		public const string NAME = "Skins";

		public const string GUID = "io.takina.gtfo.Skins";

		public const string VERSION = "0.5.3";

		internal const string GUID_MTFO = "com.dak.MTFO";

		public static GameObject? PluginObject;

		public event Action? OnManagersSetup;

		public override void Load()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			Logger.Setup();
			Logger.Info("Skins [io.takina.gtfo.Skins @ 0.5.3]");
			JObject.Parse("{}");
			ConfigMgr.Process();
			ModData.Initialize();
			if (!PersistentConfig<UserConfig>.Load())
			{
				Logger.Fatal("Failed to load user config, aborting plugin load. Please ensure the config file is valid JSON");
				return;
			}
			Events.OnGameDataInitialized += Loc.InsertToGtfoDB;
			GearDump.Load();
			Application.quitting += Action.op_Implicit((Action)GearDump.FlushNow);
			ShaderRefs.Preload();
			InternalData.Write();
			SkinManager.Initialize();
			RegisterIl2CppTypes();
			OnManagersSetup += Initialize;
			Global.OnAllManagersSetup += Action.op_Implicit(this.OnManagersSetup);
			Logger.Info("Patching...");
			ApplyPatches(new Harmony("io.takina.gtfo.Skins"));
			Logger.Info("Finished Patching");
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void ApplyPatches(Harmony h)
		{
			ApplyPatch<Events>(h);
			ApplyPatch<GearPatches>(h);
			ApplyPatch<UIManager>(h);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void ApplyPatchIfLoaded<T>(Harmony h, string guid)
		{
			if (((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey(guid))
			{
				ApplyPatch<T>(h);
				Logger.Info("Applied compat patches for plugin with GUID " + guid + ".");
			}
			else
			{
				Logger.Info("Plugin with GUID " + guid + " not found, skipping compat patches for it.");
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void ApplyPatch<T>(Harmony h)
		{
			h.PatchAll(typeof(T));
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void RegisterIl2CppTypes()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				if (type.GetCustomAttribute<RegisterIl2CppAttribute>() != null)
				{
					ClassInjector.RegisterTypeInIl2Cpp(type);
				}
			}
		}

		private void Initialize()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			Logger.Debug("Initializing...");
			_ = Loc.CurrentLocale;
			UIManager.Initialize();
			PluginObject = new GameObject("io.takina.gtfo.Skins");
			Object.DontDestroyOnLoad((Object)(object)PluginObject);
			PluginObject.AddComponent<SkinProcess>();
		}
	}
	public static class SkinManager
	{
		private static readonly HashSet<ManagedMaterialTarget> MaterialTargets = new HashSet<ManagedMaterialTarget>();

		private static readonly Dictionary<string, SkinGroup> SkinGroups = new Dictionary<string, SkinGroup>();

		public static bool Initialized { get; private set; } = false;


		public static void Initialize()
		{
			if (Initialized)
			{
				Logger.Warn("[SkinManager] Already initialized, skipping initialization.");
				return;
			}
			if (!ConfigMgr.DoNotNormalizeFolders)
			{
				NormalizeFolder(ModData.SkinsFolder);
				NormalizeFolder(ModData.PerProfileSkinsFolder);
			}
			if (ConfigMgr.AutoMovePerProfileSkinsToGlobal)
			{
				MovePerProfileSkinsToGlobal();
			}
			RegisterGroup(SkinGroup.Vanilla);
			LoadSkinsFolder(ModData.SkinsFolder);
			LoadSkinsFolder(ModData.PerProfileSkinsFolder);
			Initialized = true;
		}

		private static void LoadSkinsFolder(string path)
		{
			foreach (string item in FileUtils.FileInEachSubdirectory(path, "manifest.skingroup.json"))
			{
				SkinGroup skinGroup = JsonUtils.DeserializeFromFile<SkinGroup>(item);
				if (skinGroup == null)
				{
					Logger.Warn("[SkinManager] group manifest at '" + item + "' deserialized to null, skipping.");
					continue;
				}
				if (skinGroup.Initialize(item))
				{
					RegisterGroup(skinGroup);
					continue;
				}
				Logger.Error($"[SkinManager] Failed to initialize skin group '{skinGroup.Name}' at '{item}', skipping.");
			}
		}

		private static void NormalizeFolder(string path)
		{
			if (!Directory.Exists(path))
			{
				return;
			}
			string[] directories = Directory.GetDirectories(path);
			foreach (string text in directories)
			{
				string text2 = Path.Combine(text, "manifest.skingroup.json");
				if (!File.Exists(text2))
				{
					Logger.Debug("[SkinManager] NormalizeFolder: no manifest found in '" + text + "', skipping.");
					continue;
				}
				SkinGroup skinGroup = JsonUtils.DeserializeFromFile<SkinGroup>(text2);
				if (skinGroup == null || string.IsNullOrEmpty(skinGroup.Guid))
				{
					Logger.Warn("[SkinManager] NormalizeFolder: could not read a valid GUID from '" + text2 + "', skipping.");
					continue;
				}
				string fileName = Path.GetFileName(text);
				if (string.Equals(fileName, skinGroup.Guid, StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				string text3 = Path.Combine(path, skinGroup.Guid);
				if (Directory.Exists(text3))
				{
					Logger.Warn($"[SkinManager] NormalizeFolder: cannot rename '{fileName}' -> '{skinGroup.Guid}' -- a folder with that name already exists. Skipping.");
					continue;
				}
				try
				{
					Directory.Move(text, text3);
					Logger.Info($"[SkinManager] NormalizeFolder: renamed '{fileName}' -> '{skinGroup.Guid}'");
				}
				catch (Exception ex)
				{
					Logger.Error($"[SkinManager] NormalizeFolder: failed to rename '{fileName}' -> '{skinGroup.Guid}': {ex.Message}");
				}
			}
		}

		private static void MovePerProfileSkinsToGlobal()
		{
			if (!Directory.Exists(ModData.PerProfileSkinsFolder))
			{
				return;
			}
			string[] directories = Directory.GetDirectories(ModData.PerProfileSkinsFolder);
			foreach (string text in directories)
			{
				string fileName = Path.GetFileName(text);
				string text2 = Path.Combine(ModData.SkinsFolder, fileName);
				if (Directory.Exists(text2))
				{
					try
					{
						Directory.Delete(text2, recursive: true);
						Logger.Info("[SkinManager] AutoMove: removed outdated global copy of '" + fileName + "'.");
					}
					catch (Exception ex)
					{
						Logger.Error("[SkinManager] AutoMove: failed to remove existing '" + fileName + "' from global skins folder, skipping move: " + ex.Message);
						continue;
					}
				}
				try
				{
					Directory.Move(text, text2);
					Logger.Info("[SkinManager] AutoMove: moved '" + fileName + "' to global skins folder.");
				}
				catch (Exception ex2)
				{
					Logger.Error("[SkinManager] AutoMove: failed to move '" + fileName + "': " + ex2.Message);
				}
			}
		}

		public static void UpdateTargetsUnder(GameObject go)
		{
			foreach (ManagedMaterialTarget componentsInChild in go.GetComponentsInChildren<ManagedMaterialTarget>())
			{
				componentsInChild.UpdateMaterial();
			}
		}

		public static void UpdateAllTargets()
		{
			foreach (ManagedMaterialTarget materialTarget in MaterialTargets)
			{
				if (!((Object)(object)materialTarget == (Object)null))
				{
					materialTarget.UpdateMaterial();
				}
			}
		}

		public static void Reload()
		{
			Unload();
			Initialize();
			UpdateAllTargets();
		}

		public static void Unload()
		{
			SkinGroups.Clear();
			TextureLibrary.UnloadAll();
			TextureMacro.UnloadAll();
			Initialized = false;
		}

		public static bool TryGetGroup(string guid, [NotNullWhen(true)] out SkinGroup? group)
		{
			return SkinGroups.TryGetValue(guid, out group);
		}

		public static List<SkinGroup> GetAllMatchingGroups(TargetContext ctx)
		{
			List<SkinGroup> list = new List<SkinGroup>();
			foreach (SkinGroup value in SkinGroups.Values)
			{
				if (value.IsMatch(ctx))
				{
					list.Add(value);
				}
			}
			return list;
		}

		public static SkinGroup? GetAnyMatchingGroup(TargetContext ctx)
		{
			foreach (SkinGroup value in SkinGroups.Values)
			{
				if (value.IsMatch(ctx))
				{
					return value;
				}
			}
			return null;
		}

		private static bool RegisterGroup(SkinGroup group)
		{
			if (string.IsNullOrEmpty(group.Guid))
			{
				Logger.Error($"Failed to register skin group '{group.Name}' because it has an empty guid.");
				return false;
			}
			if (!SkinGroups.TryAdd(group.Guid, group))
			{
				Logger.Warn($"Unable to register skin group '{group.Name}' ({group.Guid}) because a group with the same guid already exists. Skipping.");
				return false;
			}
			return true;
		}

		internal static void RegisterMatTarget(ManagedMaterialTarget target)
		{
			MaterialTargets.Add(target);
		}

		internal static void UnregisterMatTarget(ManagedMaterialTarget target)
		{
			MaterialTargets.Remove(target);
		}
	}
	[RegisterIl2Cpp]
	public class SkinProcess : MonoBehaviour
	{
		private void Update()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigMgr.EnableHotReloadKey && Input.GetKeyDown(ConfigMgr.HotReloadKey))
			{
				SkinManager.Reload();
			}
		}
	}
}
namespace Skins.Utils
{
	public static class FileUtils
	{
		public static IEnumerable<string> FileInEachSubdirectory(string dir, string fileName)
		{
			foreach (string item in Directory.EnumerateDirectories(dir))
			{
				string text = Path.Combine(item, fileName);
				if (File.Exists(text))
				{
					yield return text;
				}
			}
		}

		public static IEnumerable<string> FilesWithExtensionRecursive(string dir, string extension)
		{
			if (!Directory.Exists(dir))
			{
				yield break;
			}
			string text = (extension.StartsWith(".") ? extension : ("." + extension));
			foreach (string item in Directory.EnumerateFiles(dir, "*" + text, SearchOption.AllDirectories))
			{
				yield return item;
			}
		}
	}
	public static class GearUtils
	{
		private const string GearIdPattern = "^OfflineGear_ID_(\\d+)$";

		private static readonly Regex GearIdRe = new Regex("^OfflineGear_ID_(\\d+)$", RegexOptions.Compiled);

		public static int? ExtractOfflineGearId(string gearPartId)
		{
			Match match = GearIdRe.Match(gearPartId);
			if (!match.Success)
			{
				return null;
			}
			if (int.TryParse(match.Groups[1].Value, out var result))
			{
				return result;
			}
			return null;
		}

		public static bool TryGetOfflineGearId(BackpackItem item, out int gearId)
		{
			if (item.GearIDRange != null)
			{
				return TryGetOfflineGearId(item.GearIDRange, out gearId);
			}
			gearId = -1;
			return false;
		}

		public static bool TryGetOfflineGearId(ItemEquippable item, out int gearId)
		{
			if (item.GearIDRange != null)
			{
				return TryGetOfflineGearId(item.GearIDRange, out gearId);
			}
			gearId = -1;
			return false;
		}

		public static bool TryGetOfflineGearId(GearIDRange idRange, out int gearId)
		{
			int? num = ExtractOfflineGearId(idRange.PlayfabItemInstanceId);
			if (num.HasValue)
			{
				gearId = num.Value;
				return true;
			}
			gearId = -1;
			return false;
		}
	}
	public static class GuiUtils
	{
		public static void SetItemColor(CM_Item item, Color spriteColor, Color textColorAll)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0046: 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_005f: 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_006b: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			Color spriteColorOut = default(Color);
			((Color)(ref spriteColorOut))..ctor(spriteColor.r, spriteColor.g, spriteColor.b, item.m_spriteAlphaOut);
			Color spriteColorOver = default(Color);
			((Color)(ref spriteColorOver))..ctor(spriteColor.r, spriteColor.g, spriteColor.b, item.m_spriteAlphaOver);
			Color val = default(Color);
			((Color)(ref val))..ctor(textColorAll.r, textColorAll.g, textColorAll.b, item.m_textAlphaOut);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(textColorAll.r, textColorAll.g, textColorAll.b, item.m_textAlphaOver);
			item.m_spriteColorOrg = spriteColor;
			item.m_spriteColorOut = spriteColorOut;
			item.m_spriteColorOver = spriteColorOver;
			for (int i = 0; i < ((Il2CppArrayBase<TextMeshPro>)(object)item.m_texts).Count; i++)
			{
				((Il2CppArrayBase<Color>)(object)item.m_textColorOrg)[i] = textColorAll;
				((Il2CppArrayBase<Color>)(object)item.m_textColorOut)[i] = val;
				((Il2CppArrayBase<Color>)(object)item.m_textColorOver)[i] = val2;
			}
			item.OnHoverOut();
		}

		public static void FixLobbyScrollItem(CM_LobbyScrollItem item, float? newX = null, float? newY = null, float leftLineThickness = 12f, float lineThickness = 4f)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = ((Il2CppObjectBase)((Component)item).transform).TryCast<RectTransform>();
			RectTransform component = ((Component)CustomExtensions.FindChildRecursive((Transform)(object)obj, "StretchLineT", true)).GetComponent<RectTransform>();
			RectTransform component2 = ((Component)CustomExtensions.FindChildRecursive((Transform)(object)obj, "StretchLineB", true)).GetComponent<RectTransform>();
			RectTransform component3 = ((Component)CustomExtensions.FindChildRecursive((Transform)(object)obj, "StretchLineL", true)).GetComponent<RectTransform>();
			RectTransform component4 = ((Component)CustomExtensions.FindChildRecursive((Transform)(object)obj, "StretchLineR", true)).GetComponent<RectTransform>();
			RectTransform component5 = ((Component)((Transform)component).parent).GetComponent<RectTransform>();
			RectTransform component6 = ((Component)CustomExtensions.FindChildRecursive((Transform)(object)component5, "Background", true)).GetComponent<RectTransform>();
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(newX ?? component5.sizeDelta.x, newY ?? component5.sizeDelta.y);
			component5.sizeDelta = val;
			component6.anchorMin = Vector2.zero;
			component6.anchorMax = Vector2.one;
			component6.offsetMin = Vector2.zero;
			component6.offsetMax = Vector2.zero;
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.offsetMin = new Vector2(0f, 0f - lineThickness);
			component.offsetMax = new Vector2(0f, 0f);
			component2.anchorMin = new Vector2(0f, 0f);
			component2.anchorMax = new Vector2(1f, 0f);
			component2.offsetMin = new Vector2(0f, 0f - lineThickness);
			component2.offsetMax = new Vector2(0f, 0f);
			component3.anchorMin = new Vector2(0f, 0f);
			component3.anchorMax = new Vector2(0f, 1f);
			component3.offsetMin = new Vector2(0f, 0f);
			component3.offsetMax = new Vector2(leftLineThickness, 0f);
			component4.anchorMin = new Vector2(1f, 0f);
			component4.anchorMax = new Vector2(1f, 1f);
			component4.offsetMin = new Vector2(0f, 0f);
			component4.offsetMax = new Vector2(lineThickness, 0f);
			foreach (UI_SpriteResizer componentsInChild in ((Component)item).GetComponentsInChildren<UI_SpriteResizer>())
			{
				if (Object.op_Implicit((Object)(object)componentsInChild))
				{
					componentsInChild.Resize();
				}
			}
			((CM_Item)item).m_collider.size = val;
		}
	}
	public static class JsonUtils
	{
		public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
		{
			ContractResolver = (IContractResolver)(object)new SkinsContractResolver()
		};

		public static T? Deserialize<T>(string json)
		{
			return JsonConvert.DeserializeObject<T>(json, Settings);
		}

		public static T? DeserializeFromFile<T>(string path)
		{
			if (!File.Exists(path))
			{
				Logger.Warn("[JsonUtils] File not found: '" + path + "'");
				return default(T);
			}
			return Deserialize<T>(File.ReadAllText(path));
		}
	}
	public class SkinsContractResolver : DefaultContractResolver
	{
		protected override JsonConverter? ResolveContractConverter(Type objectType)
		{
			if (objectType == typeof(IMaterialProperty))
			{
				return (JsonConverter?)(object)new MaterialPropertyConverter();
			}
			return ((DefaultContractResolver)this).ResolveContractConverter(objectType);
		}
	}
	[RegisterIl2Cpp]
	public class LifecycleHook : MonoBehaviour
	{
		public event Action? OnStarted;

		public event Action? OnDestroyed;

		private void Start()
		{
			this.OnStarted?.Invoke();
		}

		private void OnDestroy()
		{
			this.OnDestroyed?.Invoke();
		}
	}
	public class LocaleUtils
	{
		public static readonly Dictionary<string, string> LocaleKeyToDisplayName = new Dictionary<string, string>
		{
			{ "en", "English" },
			{ "fr", "Français" },
			{ "de", "Deutsch" },
			{ "es", "Español" },
			{ "it", "Italiano" },
			{ "ja", "日本語" },
			{ "ko", "한국어" },
			{ "pt-BR", "Português (Brasil)" },
			{ "ru", "Русский" },
			{ "pl", "Polski" },
			{ "zh-Hans", "简体中文" },
			{ "zh-Hant", "繁體中文" }
		};

		public static string LocaleKeyFromEnum(Language key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected I4, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			return (key - 1) switch
			{
				0 => "en", 
				1 => "fr", 
				3 => "de", 
				4 => "es", 
				2 => "it", 
				8 => "ja", 
				9 => "ko", 
				6 => "pt-BR", 
				5 => "ru", 
				7 => "pl", 
				11 => "zh-Hans", 
				10 => "zh-Hant", 
				_ => throw new ArgumentOutOfRangeException("key", key, null), 
			};
		}

		public static void SetTranslation(TextDataBlock db, string locale, string text)
		{
			switch (locale)
			{
			case "en":
				db.English = text;
				break;
			case "fr":
				db.French = LanguageData.op_Implicit(text);
				break;
			case "de":
				db.German = LanguageData.op_Implicit(text);
				break;
			case "es":
				db.Spanish = LanguageData.op_Implicit(text);
				break;
			case "it":
				db.Italian = LanguageData.op_Implicit(text);
				break;
			case "ja":
				db.Japanese = LanguageData.op_Implicit(text);
				break;
			case "ko":
				db.Korean = LanguageData.op_Implicit(text);
				break;
			case "pt-BR":
				db.Portuguese_Brazil = LanguageData.op_Implicit(text);
				break;
			case "ru":
				db.Russian = LanguageData.op_Implicit(text);
				break;
			case "pl":
				db.Polish = LanguageData.op_Implicit(text);
				break;
			case "zh-Hans":
				db.Chinese_Simplified = LanguageData.op_Implicit(text);
				break;
			case "zh-Hant":
				db.Chinese_Traditional = LanguageData.op_Implicit(text);
				break;
			}
		}

		public static uint GetSlotGearSelectTextDbId(InventorySlot slot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected I4, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			switch (slot - 1)
			{
			default:
				if ((int)slot == 10)
				{
					return 490u;
				}
				return 0u;
			case 0:
				return 487u;
			case 1:
				return 488u;
			case 2:
				return 489u;
			}
		}

		public static string GetSlotGearSelectLocalizedText(InventorySlot slot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Text.Get(GetSlotGearSelectTextDbId(slot));
		}
	}
	public static class LogDumper
	{
		private static readonly Dictionary<string, StreamWriter> LogStreams = new Dictionary<string, StreamWriter>();

		private static readonly Dictionary<string, HashSet<int>> LoggedIds = new Dictionary<string, HashSet<int>>();

		public static void Dump(string name, string content, bool append = false)
		{
			if (!LogStreams.TryGetValue(name, out StreamWriter value))
			{
				value = new StreamWriter(Path.Combine(ModData.DumpFolder, name + ".log"), append);
				LogStreams[name] = value;
				LoggedIds[name] = new HashSet<int>();
			}
			value.WriteLine(content);
			value.Flush();
		}

		public static void DumpUnique(string name, int id, string content, bool append = false)
		{
			if (!LogStreams.TryGetValue(name, out StreamWriter value))
			{
				value = new StreamWriter(Path.Combine(ModData.DumpFolder, name + ".log"), append);
				LogStreams[name] = value;
				LoggedIds[name] = new HashSet<int>();
			}
			if (!LoggedIds[name].Contains(id))
			{
				value.WriteLine(content);
				value.Flush();
				LoggedIds[name].Add(id);
			}
		}
	}
	public static class NameUtils
	{
		private static readonly Regex CleanPattern = new Regex("\\s*\\((?:Clone|Instance)\\).*$", RegexOptions.Compiled);

		public static string GetCleanMaterialName(string name)
		{
			return CleanPattern.Replace(name, "");
		}
	}
	public static class PluginUtils
	{
		public static bool IsPluginLoaded(string pluginGuid)
		{
			return ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey(pluginGuid);
		}
	}
	public static class TextureUtils
	{
		public static Texture2D CreateBlankWhiteTexture()
		{
			//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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, Color.white);
			val.Apply();
			return val;
		}

		public static Texture2D CreateBlankTexture(Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0017: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		public static Sprite SpriteFromRenderTexture(RenderTexture rt)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0038: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(((Texture)rt).width, ((Texture)rt).height, (TextureFormat)4, false);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = rt;
			val.ReadPixels(new Rect(0f, 0f, (float)((Texture)rt).width, (float)((Texture)rt).height), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		public static Sprite SpriteFromTexture2D(Texture2D tex)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Texture)tex).width;
			float num2 = ((Texture)tex).height;
			return Sprite.Create(tex, new Rect(0f, 0f, num, num2), new Vector2(0.5f, 0.5f));
		}

		public static TextureOptions InferOptionsFromSlot(string slot)
		{
			return new TextureOptions(slot switch
			{
				"_BumpMap" => true, 
				"_MetallicGlossMap" => true, 
				"_AOCurveTex" => true, 
				"_SpecGlossMap" => true, 
				"_HeightMap" => true, 
				"_DistortionTex" => true, 
				"_DistortionSignal" => true, 
				_ => false, 
			}, Mipmaps: false);
		}
	}
}
namespace Skins.Utils.Ext
{
	public static class BackpackExtensions
	{
		public static TargetContext GetContextForSlot(this PlayerBackpack bkpk, InventorySlot slot)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			TargetContext targetContext = new TargetContext();
			BackpackItem item = default(BackpackItem);
			if ((slot - 1 <= 2 || (int)slot == 10) && bkpk.TryGetBackpackItem(slot, ref item) && GearUtils.TryGetOfflineGearId(item, out var gearId))
			{
				targetContext.OfflineGearId = gearId;
			}
			return targetContext;
		}
	}
}
namespace Skins.UI
{
	[HarmonyPatch]
	public class UIManager
	{
		private static readonly Color AccentColor = Color32.op_Implicit(new Color32((byte)137, (byte)180, (byte)250, byte.MaxValue));

		private static readonly Action<int> OnOfflineGearShowSkinSelectPopup = OpenOfflineGearSkinSelect;

		private static readonly List<InventorySlot> GearSlots = new List<InventorySlot>
		{
			(InventorySlot)1,
			(InventorySlot)2,
			(InventorySlot)3,
			(InventorySlot)10
		};

		private static Sprite? _pluginIcon = null;

		public static void Initialize()
		{
			Text.UpdateAllTexts();
			Texture2D val = TextureLibrary.Load(Path.Combine(ModData.PluginFolder, "icon.png"), default(TextureOptions), managed: false);
			if ((Object)(object)val != (Object)null)
			{
				_pluginIcon = TextureUtils.SpriteFromTexture2D(val);
			}
		}

		private static void OpenOfflineGearSkinSelect(int _)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			PlayerBackpack localBackpack = PlayerBackpackManager.LocalBackpack;
			SelectionPopupMenu selectionPopupMenu = new SelectionPopupMenu();
			BackpackItem val = default(BackpackItem);
			foreach (InventorySlot gearSlot in GearSlots)
			{
				SelectionPopupHeader header = new SelectionPopupHeader(LocaleUtils.GetSlotGearSelectLocalizedText(gearSlot))
				{
					SetActiveConfirmText = "<color=orange>" + Loc.T("gear.select.clickAgain") + "</color>",
					IsActiveText = "<color=green>" + Loc.T("gear.select.active") + "</color>"
				};
				TargetContext ctx = localBackpack.GetContextForSlot(gearSlot);
				BackpackItem bkpkItem = (localBackpack.TryGetBackpackItem(gearSlot, ref val) ? val : null);
				SelectionPopupHeader selectionPopupHeader = header;
				UserConfig? instance = PersistentConfig<UserConfig>.Instance;
				selectionPopupHeader.ActiveItemID = ((instance != null && instance.CurrentSkinConfig.OfflineGear.TryGetValue(ctx.OfflineGearId ?? (-1), out string value)) ? value : "10chambers.vanilla");
				AddGroup(SkinGroup.Vanilla);
				foreach (SkinGroup allMatchingGroup in SkinManager.GetAllMatchingGroups(ctx))
				{
					AddGroup(allMatchingGroup);
				}
				selectionPopupMenu.AddHeader(header);
				void AddGroup(SkinGroup group)
				{
					SkinSelectionPopupItem obj = new SkinSelectionPopupItem
					{
						DisplayName = group.Name.Resolve(),
						ID = group.Guid,
						SubTitle = group.Author.Resolve(),
						Description = group.Description?.Resolve(),
						setActiveAction = OnOfflineGearSkinSelected,
						upperTextCustomization = AuthorTextDecoration,
						subtitleTextCustomization = DescriptionTextDecoration,
						Context = ctx
					};
					BackpackItem obj2 = bkpkItem;
					object obj3;
					if (obj2 == null)
					{
						obj3 = null;
					}
					else
					{
						Item instance2 = obj2.Instance;
						obj3 = ((instance2 != null) ? ((Component)instance2).gameObject : null);
					}
					if (obj3 == null)
					{
						obj3 = null;
					}
					obj.ApplicationTarget = (GameObject?)obj3;
					obj.SkinGUID = group.Guid;
					obj.IsVanilla = group.Guid == SkinGroup.Vanilla.Guid;
					SkinSelectionPopupItem skinSelectionPopupItem = obj;
					if ((Object)(object)_pluginIcon != (Object)null)
					{
						skinSelectionPopupItem.SpriteLarge = _pluginIcon;
						skinSelectionPopupItem.SpriteSmall = _pluginIcon;
					}
					header.AddItem(skinSelectionPopupItem);
				}
			}
			selectionPopupMenu.Show();
		}

		private static void OnOfflineGearSkinSelected(ISelectionPopupItem item)
		{
			if (!(item is SkinSelectionPopupItem skinSelectionPopupItem))
			{
				Logger.Warn("[UIManager] OnSkinSelected called with non-skin item.");
				return;
			}
			TargetContext context = skinSelectionPopupItem.Context;
			if (PersistentConfig<UserConfig>.Instance != null)
			{
				if (!context.OfflineGearId.HasValue)
				{
					Logger.Warn("[UIManager] Selected skin for item with no offline gear id - context: " + context);
					return;
				}
				PersistentConfig<UserConfig>.Instance.CurrentSkinConfig.OfflineGear[context.OfflineGearId.Value] = (skinSelectionPopupItem.IsVanilla ? "10chambers.vanilla" : skinSelectionPopupItem.SkinGUID);
				PersistentConfig<UserConfig>.Save();
			}
			if ((Object)(object)skinSelectionPopupItem.ApplicationTarget != (Object)null)
			{
				SkinManager.UpdateTargetsUnder(skinSelectionPopupItem.ApplicationTarget);
			}
		}

		private static string AuthorTextDecoration(ISelectionPopupItem item, string text)
		{
			return text;
		}

		private static string DescriptionTextDecoration(ISelectionPopupItem item, string text)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return "<" + ColorExt.ToHtml(AccentColor) + ">" + text + "</color>";
		}

		[HarmonyPatch(typeof(CM_PlayerLobbyBar), "SetupFromPage")]
		[HarmonyPostfix]
		private static void AddLobbyBarSelectSkinEntryPoint(CM_PlayerLobbyBar __instance)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = ((Il2CppObjectBase)__instance.m_weaponsHeaderText.transform).TryCast<RectTransform>();
			CM_LobbyScrollItem val2 = Object.Instantiate<CM_LobbyScrollItem>(__instance.m_clothesButton, ((Component)__instance.m_clothesButton).transform.parent, true);
			((RectTransformComp)val2).Setup();
			((Object)((Component)val2).gameObject).name = "Skins Select Button";
			((CM_Item)val2).SetOnBtnPressCallback(Action<int>.op_Implicit(OnOfflineGearShowSkinSelectPopup));
			RectTransform val3 = ((Il2CppObjectBase)((Component)val2).transform).TryCast<RectTransform>();
			if ((Object)(object)val3 != (Object)null && (Object)(object)val != (Object)null)
			{
				Vector2 anchoredPosition = val3.anchoredPosition;
				anchoredPosition.y = val.anchoredPosition.y + 15f;
				val3.anchoredPosition = anchoredPosition;
				Vector2 val4 = default(Vector2);
				((Vector2)(ref val4))..ctor(1f, 0.5f);
				val3.anchorMax = val4;
				val3.anchorMin = val4;
				((Transform)val3).Translate(new Vector3(32f, 0f, 0f));
				GuiUtils.FixLobbyScrollItem(val2, val3.sizeDelta.x * 0.4f);
				GuiUtils.SetItemColor((CM_Item)(object)val2, AccentColor, Color.white);
			}
			Loc.TrySetTMP((Component)(object)val2, "ui.skinsButton");
			GameStateCache.LobbyBar2LobbyScrollItem.Save((Component)(object)__instance, val2);
		}

		[HarmonyPatch(typeof(CM_PlayerLobbyBar), "PrepareForIntro")]
		[HarmonyPostfix]
		private static void Postfix__LobbyBar_PrepareForIntro(CM_PlayerLobbyBar __instance)
		{
			CM_LobbyScrollItem val = GameStateCache.LobbyBar2LobbyScrollItem.Get((Component)(object)__instance);
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.SetActive(false);
			}
		}

		[HarmonyPatch(typeof(CM_PlayerLobbyBar), "SpawnPlayerModel")]
		[HarmonyPostfix]
		private static void Postfix__LobbyBar_SpawnPlayerModel(CM_PlayerLobbyBar __instance)
		{
			CM_LobbyScrollItem val = GameStateCache.LobbyBar2LobbyScrollItem.Get((Component)(object)__instance);
			if ((Object)(object)val != (Object)null && (Object)(object)__instance.m_player != (Object)null && __instance.m_player.IsLocal)
			{
				CoroutineManager.BlinkIn((CM_Item)(object)val, 1.2f, (Transform)null);
			}
		}

		[HarmonyPatch(typeof(CM_PlayerLobbyBar), "ShowWeaponSelectionPopup")]
		[HarmonyPostfix]
		private static void AddWeaponSelectSkinEntryPoint(CM_PlayerLobbyBar __instance)
		{
		}

		[HarmonyPatch(typeof(CM_PageSettings), "Setup")]
		[HarmonyPostfix]
		[HarmonyPriority(800)]
		private static void AddHotReloadButton(CM_PageSettings __instance)
		{
			//IL_0036: 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)
			Logger.Warn("Uhh... maybe TheArchive should find a better way to store offset, because I hate to have to take first priority ;)");
			CM_Item val = __instance.CreateSingleButton(__instance.m_redMenuButtonPrefab, Loc.ID("settings.reload"));
			if ((Object)(object)val != (Object)null)
			{
				val.SetText("Reload Skins");
				GuiUtils.SetItemColor(val, AccentColor, AccentColor);
				val.OnBtnPressCallback += Action<int>.op_Implicit((Action<int>)OnPageMenuSettingReloadButtonPressed);
			}
		}

		private static void OnPageMenuSettingReloadButtonPressed(int _)
		{
			SkinManager.Reload();
		}
	}
}
namespace Skins.UI.Utils
{
	[RegisterIl2Cpp]
	public class ColliderDebugDraw : MonoBehaviour
	{
		private BoxCollider2D _col;

		private Material _mat;

		private void Start()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			_col = ((Component)this).GetComponent<BoxCollider2D>();
			_mat = new Material(Shader.Find("Hidden/Internal-Colored"));
		}

		private void OnRenderObject()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_col == (Object)null))
			{
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(((Collider2D)_col).offset.x, ((Collider2D)_col).offset.y, 0f);
				float num = _col.size.x * 0.5f;
				float num2 = _col.size.y * 0.5f;
				Vector3 val2 = ((Component)this).transform.TransformPoint(val + new Vector3(0f - num, num2, 0f));
				Vector3 val3 = ((Component)this).transform.TransformPoint(val + new Vector3(num, num2, 0f));
				Vector3 val4 = ((Component)this).transform.TransformPoint(val + new Vector3(num, 0f - num2, 0f));
				Vector3 val5 = ((Component)this).transform.TransformPoint(val + new Vector3(0f - num, 0f - num2, 0f));
				_mat.SetPass(0);
				GL.Begin(1);
				GL.Color(Color.green);
				GL.Vertex(val2);
				GL.Vertex(val3);
				GL.Vertex(val3);
				GL.Vertex(val4);
				GL.Vertex(val4);
				GL.Vertex(val5);
				GL.Vertex(val5);
				GL.Vertex(val2);
				GL.End();
			}
		}
	}
}
namespace Skins.UI.Menu
{
	internal interface ISelectionPopupItem
	{
		string DisplayName { get; }

		string ID { get; }

		string SubTitle { get; }

		string Description { get; }

		Sprite SpriteSmall { get; }

		Sprite SpriteLarge { get; }

		bool WasDoubleClick { get; set; }

		bool IsActive { get; set; }

		bool IsSelected { get; set; }

		bool IsAllowedToSelect { get; set; }

		bool CloseMenu { get; set; }

		float ScrollPosition { get; set; }

		void OnClicked();

		void OnSetActive();

		void SubtitleTextCustomization(ref string suptitleText, ref string subtitleText)
		{
		}
	}
	internal sealed class SelectionPopupHeader
	{
		private Action<int> _drawAction;

		private CM_PlayerLobbyBar _lobbyBar;

		public string HeaderText { get; set; } = "No Text Set";


		public string IsActiveText { get; set; } = "<color=orange>Selected</color>";


		public string SetActiveConfirmText { get; set; } = "<color=orange>Click again to select.</color>";


		public Func<SelectionPopupHeader, ISelectionPopupItem, bool> AllowedToSelectItem { get; set; }

		public List<ISelectionPopupItem> Items { get; } = new List<ISelectionPopupItem>();


		public string ActiveItemID { get; set; }

		public string LastSelectedItemID { get; set; }

		public Vector2? SpriteLargeSize { get; set; }

		public Action<SelectionPopupHeader> PreDraw { get; set; }

		internal Action<int> DrawAction => Draw;

		internal SelectionPopupMenu Parent { get; set; }

		public bool IsUpdating { get; private set; }

		public ISelectionPopupItem LastClickedItem { get; private set; }

		public SelectionPopupHeader(string headerText)
		{
			HeaderText = headerText;
		}

		public void Show()
		{
			Parent.Show(Parent.GetKey(this));
			TrySetLargeSpriteSize();
		}

		public void Hide()
		{
			Parent.Hide();
		}

		public SelectionPopupHeader AddItem(ISelectionPopupItem item)
		{
			if (Items.Contains(item))
			{
				return this;
			}
			Items.Add(item);
			return this;
		}

		internal void Setup(CM_PlayerLobbyBar lobbyBar)
		{
			_lobbyBar = lobbyBar;
		}

		internal void Draw(int key)
		{
			Draw(key, null);
		}

		internal void Draw(int key, float? scrollPosOffset)
		{
			if (!((Object)(object)_lobbyBar == (Object)null))
			{
				IsUpdating = false;
				UpdateContent(key, scrollPosOffset);
			}
		}

		private void UpdateContent(int key, float? scrollPosOffset = null)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_00cb: 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)
			PreDraw?.Invoke(this);
			List<iScrollWindowContent> val = new List<iScrollWindowContent>();
			int num = 0;
			foreach (ISelectionPopupItem item in Items)
			{
				CM_LobbyScrollItem val2 = GOUtil.SpawnChildAndGetComp<CM_LobbyScrollItem>(_lobbyBar.m_clothesCardPrefab, ((Component)_lobbyBar).transform);
				val.Add(new iScrollWindowContent(((Il2CppObjectBase)val2).Pointer));
				((CM_Item)val2).TextMeshRoot = ((Component)_lobbyBar.m_parentPage).transform;
				val2.SetupFromLobby(((Component)_lobbyBar).transform, _lobbyBar, true);
				((RectTransformComp)val2).ForcePopupLayer(true, (GameObject)null);
				((Component)val2).transform.localScale = Vector3.one;
				((TMP_Text)val2.m_nameText).SetText(item.DisplayName ?? "", true);
				bool flag = item.ID == LastSelectedItemID;
				item.IsSelected = flag;
				val2.IsSelected = flag;
				bool flag2 = item.ID == ActiveItemID;
				item.IsActive = flag2;
				((Component)((Component)val2).transform.FindChild("EmptyIcon")).gameObject.SetActive(false);
				((Component)((Component)val2).transform.FindChild("Background")).gameObject.SetActive(flag);
				string suptitleText = string.Empty;
				item.IsAllowedToSelect = AllowedToSelectItem?.Invoke(this, item) ?? true;
				if (flag)
				{
					_lobbyBar.m_popupScrollWindow.InfoBox.SetInfoBox(item.DisplayName, item.SubTitle, item.Description, string.Empty, string.Empty, (Sprite)null);
					_lobbyBar.m_popupScrollWindow.InfoBox.SetInfoBox(item.DisplayName, item.SubTitle, item.Description, string.Empty, string.Empty, item.SpriteLarge);
					TrySetLargeSpriteSize();
					if (item.IsAllowedToSelect)
					{
						suptitleText = SetActiveConfirmText;
					}
				}
				if (flag2)
				{
					suptitleText = IsActiveText;
					item.OnSetActive();
				}
				string subtitleText = item.ID;
				item.SubtitleTextCustomization(ref suptitleText, ref subtitleText);
				((TMP_Text)val2.m_subTitleText).SetText(suptitleText, true);
				((TMP_Text)val2.m_descText).SetText("   <#666>" + subtitleText + "</color>", true);
				((CM_Item)val2).OnBtnPressCallback = Action<int>.op_Implicit((Action<int>)delegate
				{
					bool flag3 = LastSelectedItemID == item.ID;
					item.WasDoubleClick = flag3;
					item.OnClicked();
					if (item.CloseMenu)
					{
						item.CloseMenu = false;
						Hide();
					}
					else
					{
						if (flag3)
						{
							ActiveItemID = item.ID;
						}
						LastSelectedItemID = item.ID;
						_lobbyBar.m_popupScrollWindow.InfoBox.SetInfoBox(item.DisplayName, item.SubTitle, item.Description, string.Empty, string.Empty, item.SpriteLarge);
						IsUpdating = true;
						LastClickedItem = item;
						UpdateContent(key, _lobbyBar.m_popupScrollWindow.m_posOffset);
					}
				});
				if ((Object)(object)item.SpriteSmall != (Object)null)
				{
					val2.m_icon.sprite = item.SpriteSmall;
				}
				val2.PlayIntro((float)num * 0.1f, -1);
				((CM_Item)val2).m_alphaSpriteOnHover = true;
				((CM_Item)val2).m_alphaTextOnHover = true;
				num++;
			}
			_lobbyBar.m_popupScrollWindow.SetContentItems(val, 0f);
			for (int i = 0; i < val.Count; i++)
			{
				CM_LobbyScrollItem val3 = ((Il2CppObjectBase)val[i]).TryCast<CM_LobbyScrollItem>();
				if (!((Object)(object)val3 == (Object)null))
				{
					val3.UpdateSizesAndOffsets();
					Items[i].ScrollPosition = val3.PosYStartEnd.x;
				}
			}
			if (scrollPosOffset.HasValue)
			{
				ScrollTo(scrollPosOffset.Value);
			}
			_lobbyBar.Select();
			_lobbyBar.ShowPopup();
			_lobbyBar.m_popupScrollWindow.SelectHeader(key);
		}

		private void TrySetLargeSpriteSize()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (SpriteLargeSize.HasValue)
			{
				_lobbyBar.m_popupScrollWindow.InfoBox.m_infoMainIcon.size = SpriteLargeSize.Value;
			}
		}

		public void ScrollTo(ISelectionPopupItem item)
		{
			ScrollTo(item.ScrollPosition);
		}

		public void ScrollTo(float posOffset)
		{
			//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_0060: Unknown result type (might be due to invalid IL or missing references)
			CM_ScrollWindow popupScrollWindow = _lobbyBar.m_popupScrollWindow;
			if (popupScrollWindow.m_scrollBar.Visible)
			{
				float num = popupScrollWindow.m_contentContainerHeight - popupScrollWindow.m_windowHeight;
				popupScrollWindow.m_posOffset = Mathf.Clamp(posOffset, 0f, num);
				Vector2 position = popupScrollWindow.m_contentContainer.GetPosition();
				position.y = popupScrollWindow.m_posStart + popupScrollWindow.m_posOffset;
				popupScrollWindow.m_contentContainer.SetPosition(position);
				popupScrollWindow.UpdateContentItemVisibility();
				popupScrollWindow.m_scrollBar.SetHandlePosition(Mathf.Clamp01(posOffset / num), popupScrollWindow.m_windowHeight);
			}
		}
	}
	internal class SelectionPopupItem : ISelectionPopupItem
	{
		public Action<ISelectionPopupItem> clickedAction;

		public Action<ISelectionPopupItem> setActiveAction;

		public Func<ISelectionPopupItem, string, string> upperTextCustomization;

		public Func<ISelectionPopupItem, string, string> subtitleTextCustomization;

		public string DisplayName { get; set; }

		public string ID { get; set; }

		public string SubTitle { get; set; }

		public string Description { get; set; }

		public Sprite SpriteSmall { get; set; }

		public Sprite SpriteLarge { get; set; }

		public bool WasDoubleClick { get; set; }

		public bool IsActive { get; set; }

		public bool IsSelected { get; set; }

		public bool IsAllowedToSelect { get; set; }

		public bool CloseMenu { get; set; }

		public float ScrollPosition { get; set; }

		public void OnClicked()
		{
			clickedAction?.Invoke(this);
		}

		public void OnSetActive()
		{
			setActiveAction?.Invoke(this);
		}

		public void SubtitleTextCustomization(ref string suptitleText, ref string subtitleText)
		{
			string text = upperTextCustomization?.Invoke(this, suptitleText);
			if (text != null)
			{
				suptitleText = text;
			}
			string text2 = subtitleTextCustomization?.Invoke(this, subtitleText);
			if (text2 != null)
			{
				subtitleText = text2;
			}
		}
	}
	internal sealed class SelectionPopupMenu
	{
		private readonly List<SelectionPopupHeader> _headers = new List<SelectionPopupHeader>();

		private CM_PlayerLobbyBar _lobbyBar;

		public SelectionPopupMenu AddHeader(SelectionPopupHeader header)
		{
			if (_headers.Contains(header))
			{
				return this;
			}
			_headers.Add(header);
			header.Parent = this;
			return this;
		}

		public void Show(int key = 0)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			FocusStateManager.EnterMenu((eCM_MenuPage)13, false);
			eGameStateName currentStateName = GameStateManager.CurrentStateName;
			if ((int)currentStateName == 6 || (int)currentStateName == 10)
			{
				FocusStateManager.Current.m_previousToggleState = (eFocusState)4;
			}
			_lobbyBar = ((IEnumerable<CM_PlayerLobbyBar>)CM_PageLoadout.Current.m_playerLobbyBars).FirstOrDefault((Func<CM_PlayerLobbyBar, bool>)((CM_PlayerLobbyBar plb) => ((Behaviour)plb).isActiveAndEnabled));
			if ((Object)(object)_lobbyBar == (Object)null)
			{
				_lobbyBar = ((Il2CppArrayBase<CM_PlayerLobbyBar>)(object)CM_PageLoadout.Current.m_playerLobbyBars)[0];
			}
			Transform popupAlign = CM_PageLoadout.Current.m_popupAlign;
			ShowSelectionPopup(_lobbyBar, popupAlign, key);
		}

		public void Hide()
		{
			if (!((Object)(object)_lobbyBar == (Object)null))
			{
				_lobbyBar.HidePopup();
			}
		}

		public int GetKey(SelectionPopupHeader header)
		{
			return _headers.IndexOf(header);
		}

		public bool TryGetHeader(int key, out SelectionPopupHeader header)
		{
			header = null;
			if (key < 0 || key >= _headers.Count)
			{
				return false;
			}
			header = _headers[key];
			return header != null;
		}

		private void ShowSelectionPopup(CM_PlayerLobbyBar lobbyBar, Transform align, int keyToShow)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			lobbyBar.m_popupVisible = true;
			((Component)lobbyBar.m_popupHolder).transform.position = align.position + new Vector3(300f, 0f, 0f);
			lobbyBar.m_popupScrollWindow.m_infoBoxWidth = 600f;
			((Component)lobbyBar.m_popupHolder).gameObject.SetActive(true);
			((Component)lobbyBar.m_popupItemHolder).gameObject.SetActive(true);
			((RectTransformComp)lobbyBar.m_popupScrollWindow).SetSize(new Vector2(1600f, 760f));
			lobbyBar.m_popupScrollWindow.ResetHeaders();
			int num = 0;
			foreach (SelectionPopupHeader header in _headers)
			{
				header.Setup(lobbyBar);
				int keyLocal = num;
				lobbyBar.m_popupScrollWindow.AddHeader(header.HeaderText, num, Action<int>.op_Implicit((Action<int>)delegate
				{
					header.DrawAction(keyLocal);
				}));
				num++;
			}
			((RectTransformComp)lobbyBar.m_popupScrollWindow).SetPosition(new Vector2(0f, 350f));
			lobbyBar.m_popupScrollWindow.RespawnInfoBoxFromPrefab(lobbyBar.m_popupInfoBoxWeaponPrefab);
			if (TryGetHeader(keyToShow, out var header2))
			{
				header2.Draw(keyToShow);
			}
		}
	}
	internal class SkinSelectionPopupItem : SelectionPopupItem
	{
		public GameObject? ApplicationTarget { get; set; }

		public TargetContext Context { get; set; } = new TargetContext();


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


		public bool IsVanilla { get; set; }
	}
}
namespace Skins.Textures
{
	public class ShaderRefs
	{
		public static readonly string[] ShadersToPreload = new string[18]
		{
			"Cell/Player/CustomGearShader", "Unlit/HolographicSight_3Layers", "GTFO/BlendHS", "GTFO/MeshDecal", "Cell/Player/GearShader", "FX/FX_ParticleAdditive", "Cell/Player/Display_GearShader", "Unlit/HolographicSight_Thermal", "Cell/Player/Display_Hologram", "GTFO/Standard",
			"GTFO/Glass", "GTFO/Glass_DoubleSided", "GTFO/RefractiveGlass", "GTFO/RefractiveGlass_V2", "GTFO/TankGlass", "GTFO/Persistence/Clothing", "GTFO/FleshBulb", "GTFO/CMS_WorldProp"
		};

		public static readonly Dictionary<string, Shader> ShaderReferences = new Dictionary<string, Shader>();

		public static void Preload()
		{
			string[] shadersToPreload = ShadersToPreload;
			foreach (string text in shadersToPreload)
			{
				Shader val = Shader.Find(text);
				if ((Object)(object)val == (Object)null)
				{
					Logger.Error("Failed to preload shader '" + text + "'");
				}
				else
				{
					ShaderReferences[text] = val;
				}
			}
		}

		public static Shader? Get(string shaderName)
		{
			if (ShaderReferences.TryGetValue(shaderName, out Shader value))
			{
				return value;
			}
			value = Shader.Find(shaderName);
			if ((Object)(object)value == (Object)null)
			{
				Logger.Error("Failed to load shader '" + shaderName + "'");
				return null;
			}
			ShaderReferences[shaderName] = value;
			return value;
		}
	}
	public static class TextureLibrary
	{
		private static readonly Dictionary<string, Texture2D> _textures = new Dictionary<string, Texture2D>();

		public static Texture2D? Load(string path, TextureOptions options = default(TextureOptions), bool managed = true)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			string key = CacheKey(path, options);
			if (_textures.TryGetValue(key, out Texture2D value))
			{
				return value;
			}
			string path2 = NormalizePath(path);
			if (!File.Exists(path2))
			{
				Logger.Warn("[TextureLibrary] Texture not found: " + path);
				return null;
			}
			byte[] array = File.ReadAllBytes(path2);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, options.Mipmaps, options.Linear);
			if (!ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array), !options.Mipmaps))
			{
				Logger.Warn("[TextureLibrary] Failed to decode image: " + path);
				Object.Destroy((Object)(object)val);
				return null;
			}
			if (options.Mipmaps)
			{
				val.Apply(true, true);
			}
			((Object)val).name = Path.GetFileNameWithoutExtension(path2);
			if (managed)
			{
				_textures[key] = val;
			}
			return val;
		}

		public static void Unload(string path, TextureOptions options = default(TextureOptions))
		{
			string key = CacheKey(path, options);
			if (_textures.Remove(key, out Texture2D value))
			{
				Object.Destroy((Object)(object)value);
			}
		}

		public static void UnloadAll()
		{
			foreach (Texture2D value in _textures.Values)
			{
				Object.Destroy((Object)(object)value);
			}
			_textures.Clear();
		}

		private static string CacheKey(string path, TextureOptions options)
		{
			return $"{NormalizePath(path)}|l={options.Linear}|m={options.Mipmaps}";
		}

		private static string NormalizePath(string path)
		{
			return Path.GetFullPath(path).ToLowerInvariant();
		}
	}
	public enum MacroParamType
	{
		Float01,
		Float255,
		Degrees,
		Percent,
		PositiveInt
	}
	public record MacroParam(string Name, MacroParamType Type);
	public interface ITextureMacroImpl
	{
		string Name { get; }

		string Description { get; }

		IReadOnlyList<MacroParam> Parameters { get; }

		string Signature
		{
			get
			{
				if (Parameters.Count != 0)
				{
					return $"@{Name}({string.Join(",", Parameters.Select((MacroParam p) => p.Name))})[width,height]";
				}
				return "@" + Name + "[width,height]";
			}
		}

		Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions options);
	}
	public static class TextureMacro
	{
		private sealed class WhiteMacro : ITextureMacroImpl
		{
			public string Name => "WHITE";

			public string Description => "Solid white texture";

			public IReadOnlyList<MacroParam> Parameters => NoParams;

			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				return Solid(Color.white, ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private sealed class BlackMacro : ITextureMacroImpl
		{
			public string Name => "BLACK";

			public string Description => "Solid black texture";

			public IReadOnlyList<MacroParam> Parameters => NoParams;

			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				return Solid(Color.black, ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private sealed class TransparentMacro : ITextureMacroImpl
		{
			public string Name => "TRANSPARENT";

			public string Description => "Fully transparent texture";

			public IReadOnlyList<MacroParam> Parameters => NoParams;

			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				return Solid(Color.clear, ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private sealed class NormalMacro : ITextureMacroImpl
		{
			public string Name => "NORMAL";

			public string Description => "Default normal map (0.5, 0.5, 1, 1)";

			public IReadOnlyList<MacroParam> Parameters => NoParams;

			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				return Solid(new Color(0.5f, 0.5f, 1f, 1f), ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private sealed class GreyMacro : ITextureMacroImpl
		{
			public string Name => "GREY";

			public string Description => "Grey texture; value 0-255";

			public IReadOnlyList<MacroParam> Parameters { get; } = new MacroParam[1]
			{
				new MacroParam("value", MacroParamType.Float255)
			};


			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				float result;
				float num = ((args.Length != 0 && float.TryParse(args[0], out result)) ? (result / 255f) : 0.5f);
				return Solid(new Color(num, num, num, 1f), ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private sealed class RgbaMacro : ITextureMacroImpl
		{
			public string Name => "RGBA";

			public string Description => "Solid color, channels 0-1";

			public IReadOnlyList<MacroParam> Parameters => RgbaParams01;

			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				if (args.Length < 4)
				{
					Logger.Warn("[TextureMacro] @RGBA requires 4 arguments (R,G,B,A) in 0-1 range");
					return null;
				}
				return Solid(ParseColor01(args), ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private sealed class Rgba32Macro : ITextureMacroImpl
		{
			public string Name => "RGBA32";

			public string Description => "Solid color, channels 0-255";

			public IReadOnlyList<MacroParam> Parameters => RgbaParams255;

			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				if (args.Length < 4)
				{
					Logger.Warn("[TextureMacro] @RGBA32 requires 4 arguments (R,G,B,A) in 0-255 range");
					return null;
				}
				return Solid(ParseColor255(args), ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private sealed class HslMacro : ITextureMacroImpl
		{
			public string Name => "HSL";

			public string Description => "HSL color (H: 0-360, S/L: 0-100)";

			public IReadOnlyList<MacroParam> Parameters { get; } = new MacroParam[3]
			{
				new MacroParam("h", MacroParamType.Degrees),
				new MacroParam("s", MacroParamType.Percent),
				new MacroParam("l", MacroParamType.Percent)
			};


			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				if (args.Length < 3)
				{
					Logger.Warn("[TextureMacro] @HSL requires 3 arguments (H, S, L)");
					return null;
				}
				return Solid(HslToColor(args), ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private sealed class MetallicSmoothnessMacro : ITextureMacroImpl
		{
			public string Name => "METALLIC_SMOOTHNESS";

			public string Description => "Metallic/smoothness map: R = metallic, G = smoothness, B = 0, A = 1";

			public IReadOnlyList<MacroParam> Parameters { get; } = new MacroParam[2]
			{
				new MacroParam("metallic", MacroParamType.Float01),
				new MacroParam("smoothness", MacroParamType.Float01)
			};


			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				float result;
				float num = ((args.Length != 0 && float.TryParse(args[0], out result)) ? result : 0f);
				float result2;
				float num2 = ((args.Length > 1 && float.TryParse(args[1], out result2)) ? result2 : 0f);
				return Solid(new Color(num, num2, 0f, 1f), ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private sealed class CheckerMacro : ITextureMacroImpl
		{
			public string Name => "CHECKER";

			public string Description => "Checkerboard with two RGBA colors";

			public IReadOnlyList<MacroParam> Parameters { get; } = new MacroParam[9]
			{
				new MacroParam("r1", MacroParamType.Float01),
				new MacroParam("g1", MacroParamType.Float01),
				new MacroParam("b1", MacroParamType.Float01),
				new MacroParam("a1", MacroParamType.Float01),
				new MacroParam("r2", MacroParamType.Float01),
				new MacroParam("g2", MacroParamType.Float01),
				new MacroParam("b2", MacroParamType.Float01),
				new MacroParam("a2", MacroParamType.Float01),
				new MacroParam("cells", MacroParamType.PositiveInt)
			};


			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_000f: 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_0023: 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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				Color a = ((args.Length >= 4) ? ParseColor01(args) : Color.white);
				Color b = ((args.Length >= 8) ? ParseColor01(args, 4) : Color.black);
				int result;
				int cells = ((args.Length >= 9 && int.TryParse(args[8], out result)) ? result : 2);
				return Checker(a, b, cells, ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private sealed class GradientHMacro : ITextureMacroImpl
		{
			public string Name => "GRADIENT_H";

			public string Description => "Horizontal gradient between two colors";

			public IReadOnlyList<MacroParam> Parameters => TwoColorsParams01;

			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_000f: 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_0023: 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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				Color a = ((args.Length >= 4) ? ParseColor01(args) : Color.black);
				Color b = ((args.Length >= 8) ? ParseColor01(args, 4) : Color.white);
				return GradientH(a, b, ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private sealed class GradientVMacro : ITextureMacroImpl
		{
			public string Name => "GRADIENT_V";

			public string Description => "Vertical gradient between two colors";

			public IReadOnlyList<MacroParam> Parameters => TwoColorsParams01;

			public Texture2D? Evaluate(string[] args, Vector2Int size, TextureOptions opts)
			{
				//IL_000f: 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_0023: 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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				Color a = ((args.Length >= 4) ? ParseColor01(args) : Color.black);
				Color b = ((args.Length >= 8) ? ParseColor01(args, 4) : Color.white);
				return GradientV(a, b, ((Vector2Int)(ref size)).x, ((Vector2Int)(ref size)).y, opts);
			}
		}

		private const int DefaultSize = 4;

		private static readonly Regex MacroRe = new Regex("@(\\w+)(?:\\(([^)]*)\\))?(?:\\[(\\d+),\\s*(\\d+)\\])?", RegexOptions.IgnoreCase | RegexOptions.Compiled);

		private static readonly Dictionary<string, ITextureMacroImpl> ByName = Registry.ToDictionary<ITextureMacroImpl, string, ITextureMacroImpl>((ITextureMacroImpl m) => m.Name, (ITextureMacroImpl m) => m, StringComparer.OrdinalIgnoreCase);

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

		private static readonly MacroParam[] NoParams = Array.Empty<MacroParam>();

		private static readonly MacroParam[] RgbaParams01 = new MacroParam[4]
		{
			new MacroParam("r", MacroParamType.Float01),
			new MacroParam("g", MacroParamType.Float01),
			new MacroParam("b", MacroParamType.Float01),
			new MacroParam("a", MacroParamType.Float01)
		};

		private static readonly MacroParam[] RgbaParams255 = new MacroParam[4]
		{
			new MacroParam("r", MacroParamType.Float255),
			new MacroParam("g", MacroParamType.Float255),
			new MacroParam("b", MacroParamType.Float255),
			new MacroParam("a", MacroParamType.Float255)
		};

		private static readonly MacroParam[] TwoColorsParams01 = new MacroParam[8]
		{
			new MacroParam("r1", MacroParamType.Float01),
			new MacroParam("g1", MacroParamType.Float01),
			new MacroParam("b1", MacroParamType.Float01),
			new MacroParam("a1", MacroParamType.Float01),
			new MacroParam("r2", MacroParamType.Float01),
			new MacroParam("g2", MacroParamType.Float01),
			new MacroParam("b2", MacroParamType.Float01),
			new MacroParam("a2", MacroParamType.Float01)
		};

		public static IReadOnlyList<ITextureMacroImpl> Registry { get; } = new List<ITextureMacroImpl>
		{
			new WhiteMacro(),
			new BlackMacro(),
			new TransparentMacro(),
			new NormalMacro(),
			new GreyMacro(),
			new RgbaMacro(),
			new Rgba32Macro(),
			new HslMacro(),
			new MetallicSmoothnessMacro(),
			new CheckerMacro(),
			new GradientHMacro(),
			new GradientVMacro()
		}.AsReadOnly();


		public static bool IsMacro(string value)
		{
			return MacroRe.IsMatch(value.Trim());
		}

		public static Texture2D? Resolve(string value, TextureOptions options = default(TextureOptions))
		{
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			string text = value.Trim();
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			string key = $"{text}|l={options.Linear}|m={options.Mipmaps}";
			if (Cache.TryGetValue(key, out Texture2D value2))
			{
				return value2;
			}
			Match match = MacroRe.Match(text);
			if (!match.Success)
			{
				Logger.Warn("[TextureMacro] Invalid macro format: '" + text + "'");
				return null;
			}
			string value3 = match.Groups[1].Value;
			string[] args = (match.Groups[2].Success ? match.Groups[2].Value.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) : Array.Empty<string>());
			int result;
			int num = ((match.Groups[3].Success && int.TryParse(match.Groups[3].Value, out result)) ? result : 4);
			int result2;
			int num2 = ((match.Groups[4].Success && int.TryParse(match.Groups[4].Value, out result2)) ? result2 : 4);
			if (!ByName.TryGetValue(value3, out ITextureMacroImpl value4))
			{
				Logger.Warn("[TextureMacro] Unknown macro: '@" + value3 + "'");
				return null;
			}
			Texture2D val = value4.Evaluate(args, new Vector2Int(num, num2), options);
			if ((Object)(object)val != (Object)null)
			{
				((Object)val).name = "macro_" + text;
				Cache[key] = val;
			}
			return val;
		}

		public static void UnloadAll()
		{
			foreach (Texture2D value in Cache.Values)
			{
				Object.Destroy((Object)(object)value);
			}
			Cache.Clear();
		}

		internal static Texture2D Solid(Color color, int w, int h, TextureOptions options)
		{
			//IL_0011: 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_0026: 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_0041: Expected O, but got Unknown
			Texture2D val = new Texture2D(w, h, (TextureFormat)4, options.Mipmaps, options.Linear);
			Color[] array = (Color[])(object)new Color[w * h];
			Array.Fill(array, color);
			val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
			val.Apply(options.Mipmaps, true);
			return val;
		}

		internal static Texture2D Checker(Color a, Color b, int cells, int w, int h, TextureOptions options)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_004b: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h, (TextureFormat)4, options.Mipmaps, options.Linear);
			Color[] array = (Color[])(object)new Color[w * h];
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					int num = j * cells / w;
					int num2 = i * cells / h;
					array[i * w + j] = (((num + num2) % 2 == 0) ? a : b);
				}
			}
			val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
			val.Apply(options.Mipmaps, true);
			return val;
		}

		internal static Texture2D GradientH(Color a, Color b, int w, int h, TextureOptions options)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h, (TextureFormat)4, options.Mipmaps, options.Linear);
			Color[] array = (Color[])(object)new Color[w * h];
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					array[i * w + j] = Color.Lerp(a, b, (float)j / (float)Mathf.Max(1, w - 1));
				}
			}
			val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
			val.Apply(options.Mipmaps, true);
			return val;
		}

		internal static Texture2D GradientV(Color a, Color b, int w, int h, TextureOptions options)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h, (TextureFormat)4, options.Mipmaps, options.Linear);
			Color[] array = (Color[])(object)new Color[w * h];
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					array[i * w + j] = Color.Lerp(a, b, (float)i / (float)Mathf.Max(1, h - 1));
				}
			}
			val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
			val.Apply(options.Mipmaps, true);
			return val;
		}

		internal static Color ParseColor01(string[] args, int offset = 0)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			float result;
			float result2;
			float result3;
			float result4;
			return new Color(float.TryParse(args[offset], out result) ? result : 0f, float.TryParse(args[offset + 1], out result2) ? result2 : 0f, float.TryParse(args[offset + 2], out result3) ? result3 : 0f, float.TryParse(args[offset + 3], out result4) ? result4 : 1f);
		}

		internal static Color ParseColor255(string[] args, int offset = 0)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			float result;
			float result2;
			float result3;
			float result4;
			return new Color(float.TryParse(args[offset], out result) ? (result / 255f) : 0f, float.TryParse(args[offset + 1], out result2) ? (result2 / 255f) : 0f, float.TryParse(args[offset + 2], out result3) ? (result3 / 255f) : 0f, float.TryParse(args[offset + 3], out result4) ? (result4 / 255f) : 1f);
		}

		internal static Color HslToColor(string[] args)
		{
			//IL_0080: 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)
			float result;
			float num = (float.TryParse(args[0], out result) ? (result / 360f) : 0f);
			float result2;
			float num2 = (float.TryParse(args[1], out result2) ? (result2 / 100f) : 0f);
			float result3;
			float num3 = (float.TryParse(args[2], out result3) ? (result3 / 100f) : 0f);
			float result4;
			float num4 = ((args.Length >= 4 && float.TryParse(args[3], out result4)) ? result4 : 1f);
			if (num2 == 0f)
			{
				return new Color(num3, num3, num3, num4);
			}
			float num5 = ((num3 < 0.5f) ? (num3 * (1f + num2)) : (num3 + num2 - num3 * num2));
			float p = 2f * num3 - num5;
			return new Color(HueToRgb(p, num5, num + 1f / 3f), HueToRgb(p, num5, num), HueToRgb(p, num5, num - 1f / 3f), num4);
		}

		internal static float HueToRgb(float p, float q, float t)
		{
			if (t < 0f)
			{
				t += 1f;
			}
			if (t > 1f)
			{
				t -= 1f;
			}
			if (t < 1f / 6f)
			{
				return p + (q - p) * 6f * t;
			}
			if (t < 0.5f)
			{
				return q;
			}
			if (t < 2f / 3f)
			{
				return p + (q - p) * (2f / 3f - t) * 6f;
			}
			return p;
		}
	}
	[JsonConverter(typeof(TextureOptionsConverter))]
	public readonly record struct TextureOptions(bool Linear, bool Mipmaps)
	{
		public static readonly TextureOptions Albedo = new TextureOptions(Linear: false, Mipmaps: true);

		public static readonly TextureOptions Data = new TextureOptions(Linear: true, Mipmaps: true);

		public static readonly TextureOptions AlbedoNoMips = new TextureOptions(Linear: false, Mipmaps: false);

		public static readonly TextureOptions DataNoMips = new TextureOptions(Linear: true, Mipmaps: false);
	}
	public class TextureOptionsConverter : JsonConverter<TextureOptions>
	{
		public override void WriteJson(JsonWriter writer, TextureOptions value, JsonSerializer serializer)
		{
			string text = (value.Equals(TextureOptions.Albedo) ? "Albedo" : (value.Equals(TextureOptions.Data) ? "Data" : (value.Equals(TextureOptions.AlbedoNoMips) ? "AlbedoNoMips" : ((!value.Equals(TextureOptions.DataNoMips)) ? null : "DataNoMips"))));
			string text2 = text;
			if (text2 != null)
			{
				writer.WriteValue(text2);
				return;
			}
			writer.WriteStartObject();
			writer.WritePropertyName("linear");
			writer.WriteValue(value.Linear);
			writer.WritePropertyName("mipmaps");
			writer.WriteValue(value.Mipmaps);
			writer.WriteEndObject();
		}

		public override TextureOptions ReadJson(JsonReader reader, Type objectType, TextureOptions existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Invalid comparison between Unknown and I4
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Invalid comparison between Unknown and I4
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if ((int)reader.TokenType == 9)
			{
				string text = (string)reader.Value;
				return text switch
				{
					"Albedo" => TextureOptions.Albedo, 
					"Data" => TextureOptions.Data, 
					"AlbedoNoMips" => TextureOptions.AlbedoNoMips, 
					"DataNoMips" => TextureOptions.DataNoMips, 
					_ => throw new JsonException("Unknown TextureOptions preset: " + text), 
				};
			}
			bool linear = false;
			bool mipmaps = true;
			while (reader.Read() && (int)reader.TokenType != 13)
			{
				if ((int)reader.TokenType != 4)
				{
					continue;
				}
				string text2 = (string)reader.Value;
				if (!(text2 == "linear"))
				{
					if (text2 == "mipmaps")
					{
						mipmaps = reader.ReadAsBoolean() ?? true;
					}
				}
				else
				{
					linear = reader.ReadAsBoolean().GetValueOrDefault();
				}
			}
			return new TextureOptions(linear, mipmaps);
		}
	}
}
namespace Skins.Target
{
	[RegisterIl2Cpp]
	public class ManagedItemTarget : MonoBehaviour
	{
	}
	[RegisterIl2Cpp]
	public class ManagedMaterialTarget : MonoBehaviour
	{
		private MeshRenderer _meshRenderer;

		private MeshFilter _meshFilter;

		private Material _material;

		private bool _clean = true;

		private MaterialSnapshot _originalMatSnapshot;

		private Dictionary<string, string?> _originalTextureNames = new Dictionary<string, string>();

		public MeshRenderer MeshRenderer => _meshRenderer;

		public MeshFilter MeshFilter => _meshFilter;

		public Material Material => _material;

		public Shader? OriginalShader => _originalMatSnapshot.Shader;

		public string? OriginalShaderName
		{
			get
			{
				Shader? shader = _originalMatSnapshot.Shader;
				if (shader == null)
				{
					return null;
				}
				return ((Object)shader).name;
			}
		}

		public int OwnerOfflineGearId { get; private set; } = -1;


		public string CleanMaterialName { get; private set; } = "";


		public TargetContext Context { get; private set; } = new TargetContext();


		private void Awake()
		{
			SkinManager.RegisterMatTarget(this);
		}

		private void OnDestroy()
		{
			SkinManager.UnregisterMatTarget(this);
		}

		private void Start()
		{
			if ((Object)(object)((Component)this).GetComponent<TMP_Text>() != (Object)null)
			{
				Logger.Error("[ManagedMaterialTarget] cannot be attached to a GameObject with a TMP_Text component.");
				Object.Destroy((Object)(object)this);
				return;
			}
			_meshRenderer = ((Component)this).GetComponent<MeshRenderer>();
			_meshFilter = ((Component)this).GetComponent<MeshFilter>();
			if ((Object)(object)_meshRenderer == (Object)null || (Object)(object)_meshFilter == (Object)null)
			{
				Logger.Error("[ManagedMaterialTarget] cannot attach to target without MeshRenderer and MeshFilter components.");
				Object.Destroy((Object)(object)this);
				return;
			}
			_material = ((Renderer)_meshRenderer).material;
			CleanMaterialName = NameUtils.GetCleanMaterialName(((Object)_material).name);
			_originalMatSnapshot = MaterialSnapshot.Capture(_material);
			_originalTextureNames = _originalMatSnapshot.GetTextureNames();
			UpdateContext();
			UpdateMaterial();
		}

		public bool UpdateMaterial(bool overrideGroup = false, string overrideGroupGuid = "", bool matchAny = false)
		{
			string value = null;
			Revert();
			bool flag = false;
			if (overrideGroup)
			{
				value = overrideGroupGuid;
			}
			else if (PersistentConfig<UserConfig>.Instance == null)
			{
				if (!matchAny)
				{
					return false;
				}
			}
			else
			{
				flag = PersistentConfig<UserConfig>.Instance.CurrentSkinConfig.OfflineGear.TryGetValue(OwnerOfflineGearId, out value);
				if (!flag && !matchAny)
				{
					return false;
				}
			}
			SkinGroup group = null;
			if (value == null)
			{
				group = SkinManager.GetAnyMatchingGroup(Context);
				if (group == null)
				{
					Logger.Warn($"[ManagedMaterialTarget] failed to find any matching skin group for target with context: {Context}");
					return false;
				}
			}
			else if (!SkinManager.TryGetGroup(value, out group))
			{
				Logger.Error("[ManagedMaterialTarget] failed to find skin group with guid '" + value + "'");
				if (flag)
				{
					PersistentConfig<UserConfig>.Instance.CurrentSkinConfig.OfflineGear[OwnerOfflineGearId] = "10chambers.vanilla";
					Logger.Warn($"[ManagedMaterialTarget] Reverted to vanilla skin group for OfflineGearID={OwnerOfflineGearId}");
				}
				return false;
			}
			if (!group.TryGetMaterialTarget(CleanMaterialName, _originalTextureNames, out MaterialTarget targetOut))
			{
				Logger.Debug($"[ManagedMaterialTarget] skin group '{group.Name}' does not have a matching material target for material '{CleanMaterialName}' with the required textures. This might be intentional.");
				return false;
			}
			if (targetOut.Shader != null && targetOut.Shader != ((Object)_material.shader).name)
			{
				Shader val = ShaderRefs.Get(targetOut.Shader);
				if ((Object)(object)val == (Object)null)
				{
					Logger.Warn($"[ManagedMaterialTarget] failed to load shader '{targetOut.Shader}' for material target '{targetOut.MaterialNameToMatch}' in skin group '{group.Name}'. Shader will not be substituted.");
				}
				else
				{
					_material.shader = val;
				}
			}
			_clean = false;
			foreach (var (propertyName, materialProperty2) in targetOut.Properties)
			{
				materialProperty2?.Apply(_material, propertyName);
			}
			Logger.Info($"[ManagedMaterialTarget] updated material '{CleanMaterialName}' ({((Object)_material).GetInstanceID()}) with skin group '{group.Name}'");
			return true;
		}

		public void Revert()
		{
			if (!_clean)
			{
				_originalMatSnapshot.Restore(_material);
				_clean = true;
			}
		}

		internal void SetAssociatedOfflineGearId(int? id)
		{
			OwnerOfflineGearId = id ?? (-1);
			UpdateContext();
		}

		private void UpdateContext()
		{
			Context = new TargetContext
			{
				OfflineGearId = OwnerOfflineGearId
			};
		}
	}
	public class MaterialSnapshot
	{
		public Dictionary<string, float> Floats { get; } = new Dictionary<string, float>();


		public Dictionary<string, Color> Colors { get; } = new Dictionary<string, Color>();


		public Dictionary<string, Vector4> Vectors { get; } = new Dictionary<string, Vector4>();


		public Dictionary<string, Texture?> Textures { get; } = new Dictionary<string, Texture>();


		public Shader? Shader { get; private set; }

		public List<string> EnabledKeywords { get; } = new List<string>();


		public static MaterialSnapshot Capture(Material mat)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected I4, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			MaterialSnapshot materialSnapshot = new MaterialSnapshot();
			materialSnapshot.Shader = mat.shader;
			foreach (string item in (Il2CppArrayBase<string>)(object)mat.GetShaderKeywords())
			{
				if (mat.IsKeywordEnabled(item))
				{
					materialSnapshot.EnabledKeywords.Add(item);
				}
			}
			Shader shader = mat.shader;
			for (int i = 0; i < shader.GetPropertyCount(); i++)
			{
				string propertyName = shader.GetPropertyName(i);
				ShaderPropertyType propertyType = shader.GetPropertyType(i);
				switch ((int)propertyType)
				{
				case 2:
				case 3:
					materialSnapshot.Floats[propertyName] = mat.GetFloat(propertyName);
					break;
				case 0:
					materialSnapshot.Colors[propertyName] = mat.GetColor(propertyName);
					break;
				case 1:
					materialSnapshot.Vectors[propertyName] = mat.GetVector(propertyName);
					break;
				case 4:
					materialSnapshot.Textures[propertyName] = mat.GetTexture(propertyName);
					break;
				}
			}
			return materialSnapshot;
		}

		public void Restore(Material mat)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Shader != (Object)null)
			{
				mat.shader = Shader;
			}
			string key;
			foreach (KeyValuePair<string, float> @float in Floats)
			{
				@float.Deconstruct(out key, out var value);
				string text = key;
				float num = value;
				mat.SetFloat(text, num);
			}
			foreach (KeyValuePair<string, Color> color in Colors)
			{
				color.Deconstruct(out key, out var value2);
				string text2 = key;
				Color val = value2;
				mat.SetColor(text2, val);
			}
			foreach (KeyValuePair<string, Vector4> vector in Vectors)
			{
				vector.Deconstruct(out key, out var value3);
				string text3 = key;
				Vector4 val2 = value3;
				mat.SetVector(text3, val2);
			}
			foreach (KeyValuePair<string, Texture> texture in Textures)
			{
				texture.Deconstruct(out key, out var value4);
				string text4 = key;
				Texture val3 = value4;
				mat.SetTexture(text4, val3);
			}
			foreach (string item in (Il2CppArrayBase<string>)(object)mat.shaderKeywords)
			{
				mat.DisableKeyword(item);
			}
			foreach (string enabledKeyword in EnabledKeywords)
			{
				mat.EnableKeyword(enabledKeyword);
			}
		}

		public Dictionary<string, string?> GetTextureNames()
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (KeyValuePair<string, Texture> texture in Textures)
			{
				texture.Deconstruct(out var key, out var value);
				string key2 = key;
				Texture val = value;
				dictionary[key2] = ((val != null) ? ((Object)val).name : null);
			}
			return dictionary;
		}
	}
	public class TargetContext
	{
		public int? OfflineGearId;
	}
}
namespace Skins.Patches
{
	[HarmonyPatch]
	public class GearPatches
	{
		[HarmonyPatch(typeof(GearPartHolder), "OnAllPartsSpawned")]
		[HarmonyPostfix]
		private static void Postfix__GearPartHolder_OnAllPartsSpawned(GearPartHolder __instance)
		{
			if (__instance.GearIDRange == null)
			{
				return;
			}
			string text = ((Object)__instance).name.Replace("GearPartHolder_", "");
			int? num = GearUtils.ExtractOfflineGearId(__instance.GearIDRange.PlayfabItemInstanceId);
			string text2 = $"[Gear] '{text}' #{num}\n";
			foreach (MeshRenderer componentsInChild in ((Component)__instance).GetComponentsInChildren<MeshRenderer>())
			{
				if (ConfigMgr.DumpGearTree)
				{
					text2 = text2 + "    [Group] '" + ((Object)((Component)componentsInChild).gameObject).name + "'\n";
					MeshFilter component = ((Component)componentsInChild).GetComponent<MeshFilter>();
					if ((Object)(object)((Component)componentsInChild).gameObject.GetComponent<TMP_Text>() != (Object)null)
					{
						continue;
					}
					text2 += $"        [MeshRenderer] '{((Object)componentsInChild).name}' ({((Object)componentsInChild).GetInstanceID()})\n            [Material] '{NameUtils.GetCleanMaterialName(((Object)((Renderer)componentsInChild).material).name)}' ({((Object)((Renderer)componentsInChild).material).GetInstanceID()})\n            [Shader] '{((Object)((Renderer)componentsInChild).material.shader).name}' ({((Object)((Renderer)componentsInChild).material.shader).GetInstanceID()})\n";
					foreach (string item in (Il2CppArrayBase<string>)(object)((Renderer)componentsInChild).material.GetTexturePropertyNames())
					{
						Texture texture = ((Renderer)componentsInChild).material.GetTexture(item);
						text2 += $"            [Texture] {item}: {(((Object)(object)texture == (Object)null) ? "null" : $"'{((Object)texture).name}' ({((Object)texture).GetInstanceID()})")}\n";
					}
					text2 += $"        [MeshFilter] '{((Object)component).name}' ({((Object)component).GetInstanceID()})\n            [Mesh] '{((Object)component.mesh).name}' ({((Object)component.mesh).GetInstanceID()})\n";
				}
				if ((Object)(object)((Component)componentsInChild).gameObject.GetComponent<TMP_Text>() == (Object)null)
				{
					Dictionary<string, string> dictionary = new Dictionary<string, string>();
					foreach (string item2 in (Il2CppArrayBase<string>)(object)((Renderer)componentsInChild).material.GetTexturePropertyNames())
					{
						Texture texture2 = ((Renderer)componentsInChild).material.GetTexture(item2);
						dictionary[item2] = ((texture2 != null) ? ((Object)texture2).name : null);
					}
					GearDump.RecordMaterial(NameUtils.GetCleanMaterialName(((Object)((Renderer)componentsInChild).material).name), ((Object)((Renderer)componentsInChild).material.shader).name, dictionary, text, num ?? (-1));
				}
				if (!((Object)(object)((Component)componentsInChild).gameObject.GetComponent<ManagedMaterialTarget>() != (Object)null))
				{
					((Component)componentsInChild).gameObject.AddComponent<ManagedMaterialTarget>().SetAssociatedOfflineGearId(num);
				}
			}
			LogDumper.DumpUnique("GearTree", num ?? (-1), text2);
		}
	}
}
namespace Skins.Manifest
{
	public interface IMaterialProperty
	{
		void Initialize(string? dirBase, string propertyName)
		{
		}

		void Apply(Material material, string propertyName);
	}
	[JsonObject]
	public class Texture2DProperty : IMaterialProperty
	{
		[JsonIgnore]
		private Texture2D? _resolved;

		[JsonProperty("src")]
		public string Source { get; set; } = "";


		[JsonProperty("options")]
		public TextureOptions? Options { get; set; }

		public void Initialize(string? dirBase, string propertyName)
		{
			if (string.IsNullOrWhiteSpace(Source))
			{
				Logger.Warn("[Texture2DProperty] Empty source for property '" + propertyName + "'. This is interpreted as no substitution — please remove empty texture entries.");
				return;
			}
			if (TextureMacro.IsMacro(Source))
			{
				_resolved = TextureMacro.Resolve(Source, TextureUtils.InferOptionsFromSlot(propertyName));
				if ((Object)(object)_resolved == (Object)null)
				{
					Logger.Warn($"[Texture2DProperty] Bad texture macro '{Source}' for property '{propertyName}'.");
				}
				return;
			}
			if (dirBase == null)
			{
				Logger.Error("[Texture2DProperty] Cannot resolve relative path '" + Source + "' for property '" + propertyName + "': manifest directory is invalid.");
				return;
			}
			TextureOptions options = Options ?? TextureUtils.InferOptionsFromSlot(propertyName);
			_resolved = TextureLibrary.Load(Path.Combine(dirBase, Source), options);
			if ((Object)(object)_resolved == (Object)null)
			{
				Logger.Error($"[Texture2DProperty] Failed to load texture from '{Source}' for property '{propertyName}'.");
			}
		}

		public void Apply(Material material, string propertyName)
		{
			if (!((Object)(object)_resolved == (Object)null) && ShaderPropCheck.Verify(material, propertyName, "Texture2DProperty", (ShaderPropertyType)4))
			{
				if (propertyName == "_EmissiveMap")
				{
					material.EnableKeyword("ENABLE_EMISSIVE");
				}
				material.SetTexture(propertyName, (Texture)(object)_resolved);
			}
		}
	}
	[JsonObject]
	public class FloatProperty : IMaterialProperty
	{
		[JsonProperty("value")]
		public float Value { get; set; }

		public void Apply(Material material, string propertyName)
		{
			if (ShaderPropCheck.Verify(material, propertyName, "FloatProperty", (ShaderPropertyType)2, (ShaderPropertyType)3))
			{
				material.SetFloat(propertyName, Value);
			}
		}
	}
	[JsonObject]
	public class ColorProperty : IMaterialProperty
	{
		[JsonProperty("r")]
		public float R { get; set; }

		[JsonProperty("g")]
		public float G { get; set; }

		[JsonProperty("b")]
		public float B { get; set; }

		[JsonProperty("a")]
		public float A { get; set; } = 1f;


		public void Apply(Material material, string propertyName)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (ShaderPropCheck.Verify(material, propertyName, "ColorProperty", (ShaderPropertyType)0))
			{
				material.SetColor(propertyName, new Color(R, G, B, A));
			}
		}
	}
	[JsonObject]
	public class VectorProperty : IMaterialProperty
	{
		[JsonProperty("x")]
		public float X { get; set; }

		[JsonProperty("y")]
		public float Y { get; set; }

		[JsonProperty("z")]
		public float Z { get; set; }

		[JsonProperty("w")]
		public float W { get; set; }

		public void Apply(Material material, string propertyName)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (ShaderPropCheck.Verify(material, propertyName, "VectorProperty", (ShaderPropertyType)1))
			{
				material.SetVector(propertyName, new Vector4(X, Y, Z, W));
			}
		}
	}
	public static class ShaderPropCheck
	{
		internal static bool Verify(Material material, string propertyName, string callerTag, ShaderPropertyType expected, ShaderPropertyType? expected2 = null)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)