Decompiled source of FixCosmetics v1.0.0

Zichen-FixCosmetics-1.0.0.dll

Decompiled 3 days ago
using 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;
	}
}