Decompiled source of Skins v0.5.3
Skins.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
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)