Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of FixCosmetics v1.0.0
Zichen-FixCosmetics-1.0.0.dll
Decompiled 3 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Zichen-FixCosmetics-1.0.0")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Zichen-FixCosmetics-1.0.0")] [assembly: AssemblyTitle("Zichen-FixCosmetics-1.0.0")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Zichen_FixCosmetics { [BepInPlugin("zichen.fixcosmetics", "FixCosmetics", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { [CompilerGenerated] private sealed class <ReplaceRepoLibLoadModdedCalls>d__38 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable<CodeInstruction> instructions; public IEnumerable<CodeInstruction> <>3__instructions; private MethodInfo <original>5__2; private MethodInfo <replacement>5__3; private IEnumerator<CodeInstruction> <>7__wrap3; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ReplaceRepoLibLoadModdedCalls>d__38(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <original>5__2 = null; <replacement>5__3 = null; <>7__wrap3 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <original>5__2 = AccessTools.Method(AccessTools.TypeByName("REPOLib.Patches.MetaManagerPatch"), "LoadModded", (Type[])null, (Type[])null); <replacement>5__3 = AccessTools.Method(typeof(Plugin), "LoadModdedCosmeticsCompat", (Type[])null, (Type[])null); <>7__wrap3 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } if (<>7__wrap3.MoveNext()) { CodeInstruction current = <>7__wrap3.Current; if (<original>5__2 != null && <replacement>5__3 != null && current.opcode == OpCodes.Call && object.Equals(current.operand, <original>5__2)) { current.operand = <replacement>5__3; } <>2__current = current; <>1__state = 1; return true; } <>m__Finally1(); <>7__wrap3 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap3 != null) { <>7__wrap3.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <ReplaceRepoLibLoadModdedCalls>d__38 <ReplaceRepoLibLoadModdedCalls>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <ReplaceRepoLibLoadModdedCalls>d__ = this; } else { <ReplaceRepoLibLoadModdedCalls>d__ = new <ReplaceRepoLibLoadModdedCalls>d__38(0); } <ReplaceRepoLibLoadModdedCalls>d__.instructions = <>3__instructions; return <ReplaceRepoLibLoadModdedCalls>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } public const string PluginGuid = "zichen.fixcosmetics"; public const string PluginName = "FixCosmetics"; public const string PluginVersion = "1.0.0"; private const string RepoLibGuid = "REPOLib"; private const string RepoLibMaxAffectedVersion = "4.0.1"; private const string InfoSection = "只读信息"; private const string GlobalSection = "A.全局设置"; private const string RepoLibFixSection = "B.REPOLib v4.0.1 修复"; private static readonly FieldInfo MetaSavePathField = AccessTools.Field(typeof(MetaManager), "savePath"); private static readonly FieldInfo MetaCosmeticUnlocksField = AccessTools.Field(typeof(MetaManager), "cosmeticUnlocks"); private static readonly FieldInfo MetaCosmeticHistoryField = AccessTools.Field(typeof(MetaManager), "cosmeticHistory"); private static readonly FieldInfo MetaCosmeticEquippedField = AccessTools.Field(typeof(MetaManager), "cosmeticEquipped"); private static readonly FieldInfo MetaCosmeticPresetsField = AccessTools.Field(typeof(MetaManager), "cosmeticPresets"); private static readonly FieldInfo MetaColorPresetsField = AccessTools.Field(typeof(MetaManager), "colorPresets"); private static readonly FieldInfo MetaColorsEquippedField = AccessTools.Field(typeof(MetaManager), "colorsEquipped"); private static readonly FieldInfo MetaSaveReadyField = AccessTools.Field(typeof(MetaManager), "saveReady"); private static readonly FieldInfo StatsEncryptionPasswordField = AccessTools.Field(typeof(StatsManager), "totallyNormalString"); private static readonly FieldInfo CosmeticAssetIdField = AccessTools.Field(typeof(CosmeticAsset), "assetId"); private static FieldInfo repoLibMissingCosmeticUnlocksField; private static FieldInfo repoLibMissingCosmeticHistoryField; private static FieldInfo repoLibMissingCosmeticEquippedField; private static FieldInfo repoLibMissingCosmeticPresetsField; private static ConfigEntry<bool> modEnabled; private static ConfigEntry<bool> fixRepoLibCosmetics; private Harmony harmony; private string repoLibFixResult; public static bool IsStaticModEnabled() { if (modEnabled != null) { return modEnabled.Value; } return false; } private void Awake() { DetachFromManager(); ResetConfigIfVersionChanged(); BindConfig(); ApplyHarmonyPatches(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"FixCosmetics v1.0.0 loaded."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } private void BindConfig() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Expected O, but got Unknown ((BaseUnityPlugin)this).Config.Bind<string>("只读信息", "模组名称", "自定义化妆品修复", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1000, ReadOnly = true } })); ((BaseUnityPlugin)this).Config.Bind<string>("只读信息", "模组版本号", "1.0.0", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 990, ReadOnly = true } })); ((BaseUnityPlugin)this).Config.Bind<string>("只读信息", "REPO交流QQ群", "824639225", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 980, ReadOnly = true } })); modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("A.全局设置", "模组启用", true, new ConfigDescription("关闭后整个模组全部功能彻底失效。", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 900 } })); fixRepoLibCosmetics = ((BaseUnityPlugin)this).Config.Bind<bool>("B.REPOLib v4.0.1 修复", "修复自定义化妆品", true, new ConfigDescription("修复 REPOLib 4.0.1 及以下版本在 R.E.P.O. v0.4.2 下调用旧 MetaManager.Save() 签名导致自定义化妆品打不开的问题。高于 4.0.1 的 REPOLib 版本不启用此补丁。开关修改后需重启游戏。", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 900 } })); } private void ApplyHarmonyPatches() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (IsStaticModEnabled()) { harmony = new Harmony("zichen.fixcosmetics"); try { TryPatchRepoLibCosmetics(); } catch (Exception ex) { repoLibFixResult = "REPOLib cosmetics fix failed: " + ex; ((BaseUnityPlugin)this).Logger.LogError((object)repoLibFixResult); } ((BaseUnityPlugin)this).Logger.LogInfo((object)repoLibFixResult); } } private void TryPatchRepoLibCosmetics() { //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Expected O, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown if (!fixRepoLibCosmetics.Value) { repoLibFixResult = "REPOLib cosmetics fix skipped: config disabled."; return; } if (!CheckPluginVersionAtOrBelow("REPOLib", "4.0.1", out var detectedVersion)) { repoLibFixResult = (string.IsNullOrWhiteSpace(detectedVersion) ? "REPOLib cosmetics fix skipped: REPOLib not detected." : ("REPOLib cosmetics fix skipped: version above affected range. Max affected 4.0.1, detected " + detectedVersion + ".")); return; } Type type = AccessTools.TypeByName("REPOLib.Patches.MetaManagerPatch"); Type type2 = AccessTools.TypeByName("REPOLib.Modules.Cosmetics"); if (type == null || type2 == null) { repoLibFixResult = "REPOLib cosmetics fix failed: target type not found."; return; } MethodInfo methodInfo = AccessTools.Method(typeof(MetaManager), "Load", new Type[1] { typeof(bool) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "LoadPatch", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(Plugin), "MetaManagerLoadPostfix", (Type[])null, (Type[])null); MethodInfo methodInfo4 = AccessTools.Method(type2, "RegisterCosmetics", (Type[])null, (Type[])null); MethodInfo methodInfo5 = AccessTools.GetDeclaredMethods(type2).FirstOrDefault((MethodInfo method) => method.Name == "RegisterCosmetic" && method.GetParameters().Length == 1 && method.GetParameters()[0].ParameterType == typeof(CosmeticAsset)); MethodInfo methodInfo6 = AccessTools.Method(typeof(Plugin), "ReplaceRepoLibLoadModdedCalls", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null || methodInfo3 == null || methodInfo4 == null || methodInfo5 == null || methodInfo6 == null || !CacheRepoLibMissingFields(type)) { repoLibFixResult = "REPOLib cosmetics fix failed: target method not found."; return; } try { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null); harmony.Unpatch((MethodBase)methodInfo, methodInfo2); } catch { SafeUnpatch(methodInfo, methodInfo3); SafeUnpatch(methodInfo4, methodInfo6); SafeUnpatch(methodInfo5, methodInfo6); throw; } repoLibFixResult = "REPOLib cosmetics fix applied: old Load postfix replaced, LoadModded calls redirected."; } private void SafeUnpatch(MethodInfo original, MethodInfo patch) { try { harmony.Unpatch((MethodBase)original, patch); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to roll back partial patch: " + ex.Message)); } } private static bool CacheRepoLibMissingFields(Type metaManagerPatchType) { repoLibMissingCosmeticUnlocksField = AccessTools.Field(metaManagerPatchType, "missingCosmeticUnlocks"); repoLibMissingCosmeticHistoryField = AccessTools.Field(metaManagerPatchType, "missingCosmeticHistory"); repoLibMissingCosmeticEquippedField = AccessTools.Field(metaManagerPatchType, "missingCosmeticEquipped"); repoLibMissingCosmeticPresetsField = AccessTools.Field(metaManagerPatchType, "missingCosmeticPresets"); if (repoLibMissingCosmeticUnlocksField != null && repoLibMissingCosmeticHistoryField != null && repoLibMissingCosmeticEquippedField != null) { return repoLibMissingCosmeticPresetsField != null; } return false; } private static bool CheckPluginVersionAtOrBelow(string guid, string maxAffectedVersion, out string detectedVersion) { detectedVersion = null; if (!Chainloader.PluginInfos.TryGetValue(guid, out var value) || value == null) { return false; } detectedVersion = value.Metadata.Version?.ToString(); return CompareVersionNumbers(detectedVersion, maxAffectedVersion) <= 0; } private static int CompareVersionNumbers(string left, string right) { int[] array = ParseVersionNumbers(left); int[] array2 = ParseVersionNumbers(right); if (array == null || array2 == null) { return 1; } for (int i = 0; i < array.Length; i++) { int num = array[i].CompareTo(array2[i]); if (num != 0) { return num; } } return 0; } private static int[] ParseVersionNumbers(string version) { if (string.IsNullOrWhiteSpace(version)) { return null; } Match match = Regex.Match(version, "^\\s*(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:\\.(\\d+))?"); if (!match.Success) { return null; } int[] array = new int[4]; for (int i = 0; i < array.Length; i++) { string value = match.Groups[i + 1].Value; array[i] = (int.TryParse(value, out var result) ? result : 0); } return array; } private static void MetaManagerLoadPostfix(MetaManager __instance) { if (!IsStaticModEnabled() || (Object)(object)__instance == (Object)null) { return; } SetFieldValue(MetaSaveReadyField, __instance, false); try { LoadModdedCosmeticsCompat(); } finally { SetFieldValue(MetaSaveReadyField, __instance, true); } } [IteratorStateMachine(typeof(<ReplaceRepoLibLoadModdedCalls>d__38))] private static IEnumerable<CodeInstruction> ReplaceRepoLibLoadModdedCalls(IEnumerable<CodeInstruction> instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ReplaceRepoLibLoadModdedCalls>d__38(-2) { <>3__instructions = instructions }; } private static void LoadModdedCosmeticsCompat() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown MetaManager instance = MetaManager.instance; if ((Object)(object)instance == (Object)null) { return; } string text = (GetFieldValue<string>(MetaSavePathField, instance) ?? "MetaSave") + "Modded.es3"; try { ES3Settings val = new ES3Settings(text, (EncryptionType)1, GetStatsEncryptionPassword(), (ES3Settings)null); if (!ES3.FileExists(val)) { instance.Save(false); return; } if (ES3.KeyExists("cosmeticUnlocks", val)) { List<string> list = ES3.Load<List<string>>("cosmeticUnlocks", val); List<int> intList = GetIntList(MetaCosmeticUnlocksField, instance); List<int> second = ResolveCosmeticIds(list); SetFieldValue(MetaCosmeticUnlocksField, instance, intList.Concat(second).Distinct().ToList()); SetRepoLibMissingList(repoLibMissingCosmeticUnlocksField, list.Where((string x) => !IsValidCosmeticAssetId(x)).ToList()); } if (ES3.KeyExists("cosmeticHistory", val)) { List<string> list2 = ES3.Load<List<string>>("cosmeticHistory", val); List<int> intList2 = GetIntList(MetaCosmeticHistoryField, instance); List<int> second2 = ResolveCosmeticIds(list2); SetFieldValue(MetaCosmeticHistoryField, instance, intList2.Concat(second2).Distinct().ToList()); SetRepoLibMissingList(repoLibMissingCosmeticHistoryField, list2.Where((string x) => !IsValidCosmeticAssetId(x)).ToList()); } if (ES3.KeyExists("cosmeticEquipped", val)) { List<string> list3 = ES3.Load<List<string>>("cosmeticEquipped", val); SetFieldValue(MetaCosmeticEquippedField, instance, ResolveCosmeticIds(list3)); SetRepoLibMissingList(repoLibMissingCosmeticEquippedField, list3.Where((string x) => !IsValidCosmeticAssetId(x)).ToList()); } if (ES3.KeyExists("cosmeticPresets", val)) { LoadCosmeticPresets(val, instance); } if (ES3.KeyExists("colorPresets", val)) { List<List<int>> source = ES3.Load<List<List<int>>>("colorPresets", val); List<List<int>> intListList = GetIntListList(MetaColorPresetsField, instance); CopyPresetLists(source, intListList); } if (ES3.KeyExists("colorsEquipped", val)) { int[] array = ES3.Load<int[]>("colorsEquipped", val); int[] fieldValue = GetFieldValue<int[]>(MetaColorsEquippedField, instance); if (array != null && fieldValue != null) { Array.Copy(array, fieldValue, Math.Min(array.Length, fieldValue.Length)); } } } catch (Exception ex) { Debug.LogError((object)("[FixCosmetics] Failed to load modded cosmetics save: " + ex.Message)); ES3.DeleteFile(text); instance.Save(false); } } private static void LoadCosmeticPresets(ES3Settings settings, MetaManager metaManager) { List<List<string>> list = ES3.Load<List<List<string>>>("cosmeticPresets", settings); List<List<int>> intListList = GetIntListList(MetaCosmeticPresetsField, metaManager); List<List<string>> list2 = EnsureMissingPresetListSize(intListList.Count); if (list == null || intListList == null) { return; } int num = Math.Min(intListList.Count, list.Count); for (int i = 0; i < num; i++) { List<string> list3 = list[i] ?? new List<string>(); intListList[i] = ResolveCosmeticIds(list3); list2[i] = list3.Where((string x) => !IsValidCosmeticAssetId(x)).ToList(); } SetRepoLibMissingPresetList(list2); } private static List<int> ResolveCosmeticIds(IEnumerable<string> assetIds) { if ((Object)(object)MetaManager.instance == (Object)null || assetIds == null) { return new List<int>(); } return (from index in assetIds.Select(FindCosmeticIndexByAssetId) where index >= 0 select index).ToList(); } private static int FindCosmeticIndexByAssetId(string assetId) { if (string.IsNullOrWhiteSpace(assetId) || (Object)(object)MetaManager.instance == (Object)null || MetaManager.instance.cosmeticAssets == null) { return -1; } return MetaManager.instance.cosmeticAssets.FindIndex((CosmeticAsset asset) => (Object)(object)asset != (Object)null && string.Equals(GetCosmeticAssetId(asset), assetId, StringComparison.Ordinal)); } private static bool IsValidCosmeticAssetId(string assetId) { return FindCosmeticIndexByAssetId(assetId) >= 0; } private static string GetStatsEncryptionPassword() { return GetFieldValue<string>(StatsEncryptionPasswordField, StatsManager.instance) ?? "Why would you want to cheat?... :o It's no fun. :') :'D"; } private static string GetCosmeticAssetId(CosmeticAsset asset) { return GetFieldValue<string>(CosmeticAssetIdField, asset); } private static List<int> GetIntList(FieldInfo field, MetaManager metaManager) { return GetFieldValue<List<int>>(field, metaManager) ?? new List<int>(); } private static List<List<int>> GetIntListList(FieldInfo field, MetaManager metaManager) { return GetFieldValue<List<List<int>>>(field, metaManager) ?? new List<List<int>>(); } private static T GetFieldValue<T>(FieldInfo field, object instance) { if (field == null || instance == null) { return default(T); } object value = field.GetValue(instance); if (value is T) { return (T)value; } return default(T); } private static void SetFieldValue(FieldInfo field, object instance, object value) { if (field != null && instance != null) { field.SetValue(instance, value); } } private static void CopyPresetLists(List<List<int>> source, List<List<int>> target) { if (source != null && target != null) { int num = Math.Min(source.Count, target.Count); for (int i = 0; i < num; i++) { target[i] = ((source[i] != null) ? source[i].ToList() : new List<int>()); } } } private static void SetRepoLibMissingList(FieldInfo field, List<string> values) { field?.SetValue(null, values ?? new List<string>()); } private static List<List<string>> EnsureMissingPresetListSize(int size) { FieldInfo fieldInfo = repoLibMissingCosmeticPresetsField; List<List<string>> list = (fieldInfo?.GetValue(null) as List<List<string>>) ?? new List<List<string>>(); while (list.Count < size) { list.Add(new List<string>()); } for (int i = 0; i < list.Count; i++) { list[i] = list[i] ?? new List<string>(); } fieldInfo?.SetValue(null, list); return list; } private static void SetRepoLibMissingPresetList(List<List<string>> values) { repoLibMissingCosmeticPresetsField?.SetValue(null, values ?? new List<List<string>>()); } private void ResetConfigIfVersionChanged() { try { string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath; string text = ReadConfigPluginVersion(configFilePath); if (!string.IsNullOrWhiteSpace(text) && !(text == "1.0.0")) { ((BaseUnityPlugin)this).Config.Clear(); if (File.Exists(configFilePath)) { File.Delete(configFilePath); } ((BaseUnityPlugin)this).Config.Reload(); ((BaseUnityPlugin)this).Logger.LogWarning((object)"Config version changed. Old config was reset to defaults."); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to reset config by version: " + ex.Message)); } } private static string ReadConfigPluginVersion(string configPath) { if (!File.Exists(configPath)) { return null; } Match match = Regex.Match(File.ReadAllText(configPath), "(?m)^模组版本号\\s*=\\s*(.+?)\\s*$"); if (!match.Success) { return null; } return match.Groups[1].Value.Trim(); } private void DetachFromManager() { ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } } internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; } }