Decompiled source of YuanAPI v0.1.1

BepInEx/plugins/YuanAPI.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
using UnityEngine.UI;
using YuanAPI.LocalizationPatches;
using YuanAPI.PropRegistryPatches;
using YuanAPI.ResourceRegistryPatches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("YuanAPI")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+76d5542aaee300e504f6c2b67b5dd217d0c877b7")]
[assembly: AssemblyProduct("YuanAPI")]
[assembly: AssemblyTitle("YuanAPI")]
[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.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;
		}
	}
	[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 YuanAPI
{
	[MeansImplicitUse]
	[AttributeUsage(AttributeTargets.Class)]
	internal class Submodule : Attribute
	{
		public bool UseAutoPatch = true;
	}
	[AttributeUsage(AttributeTargets.Method)]
	internal class AutoInit : Attribute
	{
	}
	internal static class SubmoduleManager
	{
		private static bool _hasInitialized = false;

		private static Harmony _harmony = new Harmony("cc.lymone.HoL.YuanAPI.Submodule");

		private static Dictionary<Type, Action> _initDelegates = new Dictionary<Type, Action>();

		internal static HashSet<string> HasInitialized = new HashSet<string>();

		internal static void Initialize()
		{
			if (_hasInitialized)
			{
				return;
			}
			YuanLogger.LogDebug("Initializing Submodule");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			List<Type> list = (from t in executingAssembly.GetTypes()
				where t.GetCustomAttribute<Submodule>()?.UseAutoPatch ?? false
				select t).ToList();
			foreach (Type item in list)
			{
				MethodInfo method = item.GetMethod("Initialize", BindingFlags.Static | BindingFlags.Public, null, Type.EmptyTypes, null);
				if (method != null)
				{
					PatchType(item, method);
				}
				else
				{
					YuanLogger.LogWarning("SubmoduleManager: type is submodule but not have Initialize method");
				}
			}
			_hasInitialized = true;
			YuanLogger.LogInfo($"SubmoduleManager: Patched {list.Count} submodule classes");
		}

		private static void PatchType(Type type, MethodInfo initMethod)
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			Type type2 = type;
			List<MethodInfo> list = (from m in type2.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)
				where !m.IsSpecialName
				where m.DeclaringType == type2
				where m.GetCustomAttribute<AutoInit>() != null
				where m.Name != "Initialize"
				select m).ToList();
			MethodInfo method = typeof(InitializePatch).GetMethod("InitializePrefix");
			_harmony.Patch((MethodBase)initMethod, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_initDelegates[type2] = CreateInitDelegate(initMethod);
			foreach (MethodInfo item in list)
			{
				MethodInfo method2 = typeof(InitializePatch).GetMethod("MethodPrefix");
				_harmony.Patch((MethodBase)item, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				YuanLogger.LogDebug("Patched: " + type2.Name + "." + item.Name);
			}
		}

		private static Action CreateInitDelegate(MethodInfo initMethod)
		{
			return (Action)Delegate.CreateDelegate(typeof(Action), initMethod);
		}

		public static bool TryGetInitDelegate(Type type, out Action initDelegate)
		{
			return _initDelegates.TryGetValue(type, out initDelegate);
		}
	}
	[HarmonyPatch]
	public static class InitializePatch
	{
		public static bool MethodPrefix(MethodBase __originalMethod)
		{
			if (SubmoduleManager.TryGetInitDelegate(__originalMethod.DeclaringType, out Action initDelegate))
			{
				initDelegate();
			}
			return true;
		}

		public static bool InitializePrefix(MethodBase __originalMethod)
		{
			if (__originalMethod?.DeclaringType == null)
			{
				return true;
			}
			string fullName = __originalMethod.DeclaringType.FullName;
			return SubmoduleManager.HasInitialized.Add(fullName);
		}
	}
	[BepInPlugin("cc.lymone.HoL.YuanAPI", "YuanAPI", "0.1.1")]
	public class YuanAPIPlugin : BaseUnityPlugin
	{
		public const string MODNAME = "YuanAPI";

		public const string MODGUID = "cc.lymone.HoL.YuanAPI";

		public const string VERSION = "0.1.1";

		internal static Harmony Harmony = new Harmony("cc.lymone.HoL.YuanAPI");

		public static readonly Version BuildFor = new Version(0, 7, 851);

		public static readonly Version Version = Version.Parse("0.1.1");

		internal static event Action OnStart;

		private void Awake()
		{
			YuanLogger.SetLogger(new LoggerWrapper(((BaseUnityPlugin)this).Logger));
			SubmoduleManager.Initialize();
		}

		private void Start()
		{
			YuanAPIPlugin.OnStart?.Invoke();
		}
	}
	[Submodule]
	public class Localization
	{
		public class LocalizationInstance
		{
			[CompilerGenerated]
			[DebuggerBrowsable(DebuggerBrowsableState.Never)]
			private bool <IsSyncGlobalLang>k__BackingField;

			public string Locale { get; set; }

			public string Namespace { get; set; }

			public bool IsSyncGlobalLang
			{
				[CompilerGenerated]
				get
				{
					return <IsSyncGlobalLang>k__BackingField;
				}
				set
				{
					if (<IsSyncGlobalLang>k__BackingField != value)
					{
						if (value)
						{
							OnLanguageChanged += SyncLang;
						}
						else
						{
							OnLanguageChanged -= SyncLang;
						}
						<IsSyncGlobalLang>k__BackingField = value;
					}
				}
			}

			internal LocalizationInstance(string locale, string @namespace, bool syncGlobalLocale)
			{
				Locale = locale;
				Namespace = @namespace;
				IsSyncGlobalLang = syncGlobalLocale;
			}

			private void SyncLang(string locale)
			{
				Locale = locale;
			}

			public string t(string key)
			{
				return GetText(Locale, Namespace, key);
			}

			public string t(string @namespace, string key)
			{
				return GetText(Locale, @namespace, key);
			}

			public string t(string locale, string @namespace, string key)
			{
				return GetText(locale, @namespace, key);
			}

			public string t(string key, params object[] args)
			{
				return t(Locale, Namespace, key, args);
			}

			public string t(string @namespace, string key, params object[] args)
			{
				return t(Locale, @namespace, key, args);
			}

			public string t(string locale, string @namespace, string key, params object[] args)
			{
				return string.Format(GetText(locale, @namespace, key), args);
			}
		}

		private static Dictionary<(string loc, string ns, string key), string> _store = new Dictionary<(string, string, string), string>();

		private static List<string> _locales = new List<string>();

		private static Dictionary<string, string> _localeShowNames = new Dictionary<string, string>();

		private static Dictionary<string, List<string>> _fallbackChains = new Dictionary<string, List<string>>();

		private static Dictionary<string, List<string>> _searchOrders = new Dictionary<string, List<string>>();

		public const string DefaultLocale = "zh-CN";

		public const string DefaultNamespace = "Common";

		public const string VanillaNamespace = "Vanilla";

		private static List<FieldInfo> _vanillaFields = new List<FieldInfo>();

		private static Dictionary<string, int> _itemCounts = new Dictionary<string, int>();

		public static event Action<string> OnLanguageChanged;

		public static void Initialize()
		{
			YuanLogger.LogDebug("Localization Initialize Called");
			YuanAPIPlugin.Harmony.PatchAll(typeof(SetPanelPatch));
			YuanAPIPlugin.Harmony.PatchAll(typeof(YuanAPI.LocalizationPatches.SaveDataPatch));
			RegisterLocale("zh-CN", "简体中文", new List<string>());
			RegisterLocale("en-US", "English(US)", new List<string>(1) { "zh-CN" });
			LoadFromAllText();
			YuanAPIPlugin.OnStart += InjectAllText;
		}

		private static void LoadFromAllText()
		{
			_vanillaFields = (from field in typeof(AllText).GetFields(BindingFlags.Static | BindingFlags.Public)
				where field.FieldType == typeof(List<List<string>>)
				select field).ToList();
			if (_vanillaFields.Count == 0)
			{
				YuanLogger.LogError("Localization:未能成功找到原版字段");
				return;
			}
			int count = ((List<List<string>>)_vanillaFields[0].GetValue(null))[0].Count;
			if (count != _locales.Count)
			{
				YuanLogger.LogError($"Localization:原版的本地化语言数 {count} 与YuanAPI定义不一致,将尝试处理已定义语言,建议升级YuanAPI");
			}
			foreach (FieldInfo vanillaField in _vanillaFields)
			{
				string fieldName = vanillaField.Name;
				List<List<string>> list = (List<List<string>>)vanillaField.GetValue(null);
				_itemCounts[fieldName] = list.Count;
				list.ForEach(delegate(List<string> item, int index)
				{
					if (item.Count == 0)
					{
						_locales.ForEach(delegate(string locale)
						{
							_store[(locale, "Vanilla", $"{fieldName}.{index}")] = "";
						});
					}
					else
					{
						_locales.ForEach(delegate(string locale, int langIndex)
						{
							_store[(locale, "Vanilla", $"{fieldName}.{index}")] = item[langIndex];
						});
					}
				});
			}
			List<List<List<string>>> text_AllShenFen = AllText.Text_AllShenFen;
			text_AllShenFen.ForEach(delegate(List<List<string>> group, int gIndex)
			{
				group.ForEach(delegate(List<string> item, int iIndex)
				{
					_locales.ForEach(delegate(string locale, int langIndex)
					{
						_store[(locale, "Vanilla", $"Text_AllShenFen.{gIndex}.{iIndex}")] = item[langIndex];
					});
				});
			});
			YuanLogger.LogDebug($"Localization:成功读入{_vanillaFields.Count + 1}个字段");
		}

		private static void InjectAllText()
		{
			if (_vanillaFields == null || _vanillaFields.Count == 0)
			{
				YuanLogger.LogError("Localization:原版字段未能成功读入,拒绝注入");
				return;
			}
			foreach (FieldInfo vanillaField in _vanillaFields)
			{
				string fieldName = vanillaField.Name;
				int num = _itemCounts[fieldName];
				List<List<string>> list = new List<List<string>>();
				int j;
				for (j = 0; j < num; j++)
				{
					list.Add(_locales.Select((string locale) => GetText(locale, "Vanilla", $"{fieldName}.{j}")).ToList());
				}
				vanillaField.SetValue(null, list);
			}
			int count = AllText.Text_AllShenFen.Count;
			for (int i = 0; i < count; i++)
			{
				int count2 = AllText.Text_AllShenFen[i].Count;
				List<List<string>> list2 = new List<List<string>>();
				int k;
				for (k = 0; k < count2; k++)
				{
					list2.Add(_locales.Select((string locale) => GetText(locale, "Vanilla", $"Text_AllShenFen.{i}.{k}")).ToList());
				}
				AllText.Text_AllShenFen[i] = list2;
			}
			YuanLogger.LogDebug($"Localization:成功注入{_locales.Count}种语言");
		}

		[AutoInit]
		public static void RegisterLocale(string locale, string showName, List<string> fallbackChain = null)
		{
			if (string.IsNullOrWhiteSpace(locale))
			{
				throw new ArgumentException("locale 必须是非空字符串", "locale");
			}
			if (_locales.Contains(locale))
			{
				YuanLogger.LogWarning("Localization: " + locale + " 语言重复注册,忽略本次注册");
				return;
			}
			_locales.Add(locale);
			_localeShowNames[locale] = showName;
			if (fallbackChain == null)
			{
				fallbackChain = new List<string>(1) { "zh-CN" };
			}
			SetFallbackChain(locale, fallbackChain);
			_searchOrders.Clear();
		}

		[AutoInit]
		public static void SetFallbackChain(string locale, List<string> fallbackChain)
		{
			if (!_locales.Contains(locale))
			{
				throw new ArgumentException("locale 未注册", "locale");
			}
			_fallbackChains[locale] = fallbackChain.Where((string s) => !string.IsNullOrWhiteSpace(s)).ToList();
			EnsureNoCycles();
		}

		[AutoInit]
		public static void LoadFromPath(string path)
		{
			string text = Path.Combine(path, "locales");
			if (string.IsNullOrWhiteSpace(path) || !Directory.Exists(text))
			{
				throw new DirectoryNotFoundException("路径不存在:" + text);
			}
			foreach (string locale in _locales)
			{
				string path2 = Path.Combine(text, locale);
				if (!Directory.Exists(path2))
				{
					continue;
				}
				foreach (string item in Directory.EnumerateFiles(path2, "*.json"))
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item);
					LoadOneFile(locale, fileNameWithoutExtension, item);
				}
			}
		}

		[AutoInit]
		public static void EditText(string loc, string ns, string key, string value)
		{
			_store[(loc, ns, key)] = value ?? string.Empty;
		}

		public static void EditText(string ns, string key, List<string> values)
		{
			int count = values?.Count ?? 0;
			_locales.ForEach(delegate(string locale, int index)
			{
				if (index < count)
				{
					EditText(locale, ns, key, values?[index]);
				}
			});
		}

		public static string GetLocale(int index)
		{
			return _locales[index];
		}

		public static string GetText(string locale, string @namespace, string key)
		{
			if (string.IsNullOrWhiteSpace(key))
			{
				return string.Empty;
			}
			List<string> list = BuildSearchOrders(locale);
			foreach (string item in list)
			{
				if (_store.TryGetValue((item, @namespace, key), out var value))
				{
					return value;
				}
			}
			YuanLogger.LogWarning("Localization: 无法解析 " + locale + "/" + @namespace + ":" + key);
			return @namespace + ":" + key;
		}

		public static List<string> GetTextAllLocales(string @namespace, string key)
		{
			return _locales.Select((string locale) => GetText(locale, @namespace, key)).ToList();
		}

		public static List<string> GetAllLocales()
		{
			return _locales;
		}

		public static List<string> GetAllShowNames()
		{
			return _locales.Select((string locale) => _localeShowNames[locale]).ToList();
		}

		public static int LocaleCount()
		{
			return _locales.Count;
		}

		[AutoInit]
		public static LocalizationInstance CreateInstance(string locale = "zh-CN", string @namespace = "Common", bool syncGlobalLocale = true)
		{
			return new LocalizationInstance(locale, @namespace, syncGlobalLocale);
		}

		internal static void CallLanguageChanged(string locale)
		{
			Localization.OnLanguageChanged?.Invoke(locale);
		}

		private static void LoadOneFile(string locale, string @namespace, string filePath)
		{
			//IL_00cb: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			try
			{
				using FileStream stream = File.OpenRead(filePath);
				using StreamReader streamReader = new StreamReader(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true), detectEncodingFromByteOrderMarks: true);
				JsonTextReader val = new JsonTextReader((TextReader)streamReader);
				try
				{
					JObject val2 = JObject.Load((JsonReader)(object)val);
					if ((int)((JToken)val2).Type != 1)
					{
						throw new InvalidDataException("根必须是对象:" + filePath);
					}
					Dictionary<string, string> dictionary = new Dictionary<string, string>();
					FlattenStringLeaves((JToken)(object)val2, dictionary);
					foreach (KeyValuePair<string, string> item in dictionary)
					{
						EditText(locale, @namespace, item.Key, item.Value);
					}
				}
				finally
				{
					((IDisposable)val)?.Dispose();
				}
			}
			catch (JsonReaderException val3)
			{
				JsonReaderException val4 = val3;
				throw new InvalidDataException($"JSON 语法不合法({val4.LineNumber}:{val4.LinePosition}) : {filePath}", (Exception?)(object)val4);
			}
			catch (Exception ex)
			{
				throw new InvalidDataException("文件读取错误(" + ex.GetType().Name + ") : " + filePath, ex);
			}
		}

		private static void FlattenStringLeaves(JToken token, Dictionary<string, string> output, string prefix = null)
		{
			//IL_005b: 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)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Invalid comparison between Unknown and I4
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			JObject val = (JObject)(object)((token is JObject) ? token : null);
			if (val != null)
			{
				foreach (JProperty item in val.Properties())
				{
					string text = (string.IsNullOrEmpty(prefix) ? item.Name : (prefix + "." + item.Name));
					JToken value = item.Value;
					JTokenType type = value.Type;
					JTokenType val2 = type;
					if ((int)val2 != 1)
					{
						if ((int)val2 != 8)
						{
							throw new InvalidDataException($"JSON 值必须为字符串(键:{text},实际类型:{value.Type})。");
						}
						output[text] = Extensions.Value<string>((IEnumerable<JToken>)value) ?? string.Empty;
					}
					else
					{
						FlattenStringLeaves(value, output, text);
					}
				}
				return;
			}
			throw new InvalidDataException("根必须是对象类型。");
		}

		private static List<string> BuildSearchOrders(string locale)
		{
			if (_searchOrders.TryGetValue(locale, out var value))
			{
				return value;
			}
			List<string> result = new List<string>();
			HashSet<string> visited = new HashSet<string>();
			Dfs(locale);
			result = result.Where((string loc) => _locales.Contains(loc)).ToList();
			_searchOrders[locale] = result;
			return result;
			void Dfs(string loc)
			{
				if (visited.Add(loc))
				{
					result.Add(loc);
					if (_fallbackChains.TryGetValue(loc, out var value2))
					{
						foreach (string item in value2.Where((string n) => !string.IsNullOrWhiteSpace(n)))
						{
							Dfs(item);
						}
					}
				}
			}
		}

		private static void EnsureNoCycles()
		{
			HashSet<string> visiting = new HashSet<string>();
			HashSet<string> visited = new HashSet<string>();
			foreach (string item in _fallbackChains.Keys.Where(Dfs))
			{
				YuanLogger.LogError("Localization: 检测到回退链路的环:起点 " + item);
			}
			bool Dfs(string loc)
			{
				if (visiting.Contains(loc))
				{
					return true;
				}
				if (visited.Contains(loc))
				{
					return false;
				}
				visiting.Add(loc);
				if (_fallbackChains.TryGetValue(loc, out var value) && value.Where((string n) => !string.IsNullOrWhiteSpace(n)).Any(Dfs))
				{
					return true;
				}
				visiting.Remove(loc);
				visited.Add(loc);
				return false;
			}
		}
	}
	public enum PropCategory
	{
		Offering,
		Fertilizer,
		Food,
		Snack,
		Textile,
		Mineral,
		Rouge,
		JewelryF,
		JewelryM,
		Book,
		Ink,
		Art,
		Antique,
		Weapon,
		TeaSet,
		Incense,
		Vase,
		Wine,
		Music,
		Pelt,
		Spell,
		Poison,
		Produce,
		Medicine
	}
	public class PropData
	{
		public string PropNamespace { get; set; } = "Common";


		public string PropID { get; set; }

		public string Uid => PropNamespace + ":" + PropID;

		public int? Price { get; set; } = null;


		public int? Category { get; set; } = null;


		public Dictionary<int, int> PropEffect { get; set; } = new Dictionary<int, int>();


		public string TextNamespace { get; set; } = "Common";


		public string TextKey { get; set; }

		public string PrefabPath { get; set; }

		public bool IsValid()
		{
			return !string.IsNullOrEmpty(PropNamespace) && !string.IsNullOrEmpty(PropID) && !string.IsNullOrEmpty(TextNamespace) && !string.IsNullOrEmpty(TextKey) && !string.IsNullOrEmpty(PrefabPath) && Price.HasValue && Category.HasValue;
		}

		internal static PropData FromVanillaPropData(List<string> listData, int index)
		{
			PropData propData = new PropData();
			propData.PropNamespace = "Vanilla";
			propData.PropID = index.ToString();
			propData.Price = int.Parse(listData[0]);
			propData.Category = int.Parse(listData[1]);
			propData.PropEffect = listData[2].Split(new char[1] { '|' }).Select((string str, int effect) => (effect, int.Parse(str))).ToDictionary<(int, int), int, int>(((int effect, int) x) => x.effect, ((int effect, int) x) => x.Item2);
			propData.TextNamespace = "Vanilla";
			propData.TextKey = $"Prop.{index}";
			propData.PrefabPath = $"AllProp/{index}";
			return propData;
		}

		internal List<string> ToVanillaPropData()
		{
			if (!IsValid())
			{
				throw new InvalidDataException("无法使用非法数据构造数据序列");
			}
			List<string> list = new List<string>();
			list.Add(Price.ToString());
			list.Add(Category.ToString());
			list.Add(string.Join("|", from PropEffectType effect in Enum.GetValues(typeof(PropEffectType))
				select PropEffect.TryGetValue((int)effect, out var value) ? value.ToString() : "0"));
			return list;
		}

		public static PropData operator +(PropData sample, PropData that)
		{
			if (sample == null)
			{
				return that;
			}
			if (that == null)
			{
				return sample;
			}
			PropData propData = new PropData
			{
				PropNamespace = ((that.PropNamespace != "Common") ? that.PropNamespace : sample.PropNamespace),
				PropID = ((!string.IsNullOrEmpty(that.PropID)) ? that.PropID : sample.PropID),
				Price = (that.Price ?? sample.Price),
				Category = (that.Category ?? sample.Category),
				TextNamespace = ((that.TextNamespace != "Common") ? that.TextNamespace : sample.TextNamespace),
				TextKey = ((!string.IsNullOrEmpty(that.TextKey)) ? that.TextKey : sample.TextKey),
				PrefabPath = ((!string.IsNullOrEmpty(that.PrefabPath)) ? that.PrefabPath : sample.PrefabPath),
				PropEffect = new Dictionary<int, int>()
			};
			foreach (KeyValuePair<int, int> item in sample.PropEffect)
			{
				propData.PropEffect[item.Key] = item.Value;
			}
			foreach (KeyValuePair<int, int> item2 in that.PropEffect)
			{
				propData.PropEffect[item2.Key] = item2.Value;
			}
			return propData;
		}
	}
	public enum PropEffectType
	{
		Writing,
		Might,
		Business,
		Arts,
		Health,
		Mood,
		Charisma,
		Luck,
		Life,
		Cunning,
		SorcerySkill,
		MedicineSkill,
		DaoismSkill,
		AugurSkill,
		CharismaSkill,
		CraftSkill
	}
	[Submodule]
	public class PropRegistry
	{
		public class PropRegistryInstance : IDisposable
		{
			private List<PropData> _propList = new List<PropData>();

			private bool _disposed;

			public PropData Sample { get; set; }

			internal PropRegistryInstance(PropData sample, List<PropData> propList)
			{
				Sample = sample;
				propList?.ForEach(Add);
			}

			public void Add(PropData prop)
			{
				_propList.Add(Sample + prop);
			}

			public void Dispose()
			{
				if (!_disposed)
				{
					YuanLogger.LogDebug("PropRegistryInstance RegisterProps");
					RegisterProps(_propList);
					_disposed = true;
				}
			}
		}

		private static List<PropData> _allProps = new List<PropData>();

		private static List<PropData> _patchedVanillaProps = new List<PropData>();

		private static Dictionary<(string ns, string id), int> _uidMap = new Dictionary<(string, string), int>();

		public const string DefaultNamespace = "Common";

		public const string VanillaNamespace = "Vanilla";

		internal static int VanillaPropCount { get; private set; }

		public static void Initialize()
		{
			YuanLogger.LogDebug("PropRegistry Initialize Called");
			ResourceRegistry.Initialize();
			Localization.Initialize();
			YuanAPIPlugin.Harmony.PatchAll(typeof(YuanAPI.PropRegistryPatches.ResourcesPatch));
			YuanAPIPlugin.Harmony.PatchAll(typeof(YuanAPI.PropRegistryPatches.SaveDataPatch));
			YuanAPIPlugin.OnStart += InjectMainload;
		}

		public static PropData GetProp(string @namespace, string id)
		{
			return _allProps[_uidMap[(@namespace, id)]];
		}

		public static PropData GetProp(string uid)
		{
			string[] array = uid.Split(new char[1] { ':' });
			return _allProps[_uidMap[(array[0], array[1])]];
		}

		public static PropData GetProp(int index)
		{
			return _allProps[index];
		}

		public static string GetUid(int index)
		{
			return _allProps[index].PropNamespace + ":" + _allProps[index].PropID;
		}

		public static bool TryGetUid(int index, out string uid)
		{
			bool result = index >= 0 && index < _allProps.Count;
			uid = _allProps[index].PropNamespace + ":" + _allProps[index].PropID;
			return result;
		}

		public static int GetIndex(string @namespace, string id)
		{
			return _uidMap[(@namespace, id)];
		}

		public static bool TryGetIndex(string @namespace, string id, out int index)
		{
			return _uidMap.TryGetValue((@namespace, id), out index);
		}

		public static bool TryGetIndex(string uid, out int index)
		{
			string[] array = uid.Split(new char[1] { ':' });
			if (array.Length == 2)
			{
				return _uidMap.TryGetValue((array[0], array[1]), out index);
			}
			index = -1;
			return false;
		}

		private static void InjectMainload()
		{
			VanillaPropCount = Mainload.AllPropdata.Count;
			foreach (PropData allProp in _allProps)
			{
				List<string> textAllLocales = Localization.GetTextAllLocales(allProp.TextNamespace, allProp.TextKey);
				AllText.Text_AllProp.Add(textAllLocales);
				Localization.EditText("Vanilla", $"Text_AllProp.{VanillaPropCount++}", textAllLocales);
			}
			VanillaPropCount = Mainload.AllPropdata.Count;
			List<PropData> list = Mainload.AllPropdata.Select(PropData.FromVanillaPropData).ToList();
			list.AddRange(_allProps);
			_allProps = list;
			List<(string, string)> list2 = _uidMap.Keys.ToList();
			CollectionExtensions.Do<(string, string)>((IEnumerable<(string, string)>)list2, (Action<(string, string)>)delegate((string ns, string id) str)
			{
				_uidMap[str] += VanillaPropCount;
			});
			for (int i = 0; i < VanillaPropCount; i++)
			{
				_uidMap.Add(("Vanilla", i.ToString()), i);
			}
			foreach (PropData patchedVanillaProp in _patchedVanillaProps)
			{
				if (int.TryParse(patchedVanillaProp.PropID, out var result) && result >= 0 && result < VanillaPropCount)
				{
					_allProps[result] = patchedVanillaProp;
					AllText.Text_AllProp[result] = Localization.GetTextAllLocales(patchedVanillaProp.TextNamespace, patchedVanillaProp.TextKey);
				}
			}
			Mainload.AllPropdata = _allProps.Select((PropData prop) => prop.ToVanillaPropData()).ToList();
			YuanLogger.LogDebug($"PropRegistry: 添加了{Mainload.AllPropdata.Count - VanillaPropCount}个物品");
		}

		[AutoInit]
		public static void RegisterProps(List<PropData> props)
		{
			int count = _allProps.Count;
			foreach (PropData prop in props)
			{
				int value;
				if (!prop.IsValid())
				{
					YuanLogger.LogError("PropRegistry: 名为 " + prop.PropNamespace + ":" + prop.PropID + " 的数据为空或非法,将跳过注册");
				}
				else if (prop.PropNamespace == "Vanilla")
				{
					_patchedVanillaProps.Add(prop);
				}
				else if (_uidMap.TryGetValue((prop.PropNamespace, prop.PropID), out value))
				{
					_allProps[value] = prop;
				}
				else
				{
					_allProps.Add(prop);
					_uidMap.Add((prop.PropNamespace, prop.PropID), count++);
				}
			}
		}

		[AutoInit]
		public static PropRegistryInstance CreateInstance(PropData sample = null, List<PropData> propList = null)
		{
			return new PropRegistryInstance(sample, propList);
		}
	}
	public class PropPrefabData
	{
	}
	public class ResourceData
	{
		public string ModId;

		public string KeyWord;

		public string ModPath;

		public AssetBundle Bundle;

		public ResourceData(string modId, string keyWord, string modPath)
		{
			ModId = modId;
			ModPath = modPath;
			KeyWord = keyWord;
		}

		public ResourceData(string modId, string keyWord)
		{
			ModId = modId;
			ModPath = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			KeyWord = keyWord;
		}

		public bool HasAssetBundle()
		{
			return (Object)(object)Bundle != (Object)null;
		}

		public void LoadAssetBundle(string bundleName)
		{
			Bundle = AssetBundle.LoadFromFile(ModPath + "/" + bundleName);
			if ((Object)(object)Bundle == (Object)null)
			{
				throw new ResourceException("Failed to load asset bundle at " + ModPath + "/" + bundleName);
			}
		}
	}
	public class ResourceException : Exception
	{
		public ResourceException(string message)
			: base(message)
		{
		}
	}
	[Submodule]
	public class ResourceRegistry
	{
		internal static List<ResourceData> ModResources = new List<ResourceData>();

		internal static string[] SpriteFileExtensions = new string[3] { ".jpg", ".png", ".tif" };

		internal static string[] AudioClipFileExtensions = new string[4] { ".mp3", ".ogg", ".waw", ".aif" };

		public static void Initialize()
		{
			YuanAPIPlugin.Harmony.PatchAll(typeof(YuanAPI.ResourceRegistryPatches.ResourcesPatch));
		}

		[AutoInit]
		public static void AddResource(ResourceData resource)
		{
			ModResources.Add(resource);
		}
	}
	public enum TipLv
	{
		Info,
		Warning,
		ShortInfo
	}
	public static class MsgTool
	{
		public static void TipMsg(string msg, TipLv lv = TipLv.Info)
		{
			if (!string.IsNullOrEmpty(msg))
			{
				List<List<string>> tip_Show = Mainload.Tip_Show;
				List<string> list = new List<string>(2);
				int num = (int)lv;
				list.Add(num.ToString());
				list.Add(msg);
				tip_Show.Add(list);
			}
		}
	}
	public static class PropTool
	{
		public static bool AddProp(int propId, int propCount, bool storage = true, bool silence = false)
		{
			if (propId < 0 || propId >= Mainload.AllPropdata.Count)
			{
				return false;
			}
			int.TryParse(Mainload.FamilyData[5], out var result);
			if (storage)
			{
				if (result - propCount < 0)
				{
					if (!silence)
					{
						MsgTool.TipMsg(AllText.Text_TipShow[21][Mainload.SetData[4]], TipLv.Warning);
					}
					return false;
				}
				Mainload.FamilyData[5] = (result - propCount).ToString();
			}
			string text = propId.ToString();
			int count = Mainload.Prop_have.Count;
			for (int i = 0; i < count; i++)
			{
				if (!(Mainload.Prop_have[i][0] != text))
				{
					Mainload.Prop_have[i][1] = (int.Parse(Mainload.Prop_have[i][1]) + propCount).ToString();
					return true;
				}
			}
			Mainload.Prop_have.Add(new List<string>(2)
			{
				text,
				propCount.ToString()
			});
			return true;
		}

		public static bool AddProp(string propId, int propCount, bool storage = true, bool silence = false)
		{
			return AddProp(int.Parse(propId), propCount, storage, silence);
		}
	}
	public static class EnumerableExtension
	{
		public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T, int> action)
		{
			int num = 0;
			foreach (T item in enumerable)
			{
				action(item, num);
				num++;
			}
		}
	}
	public interface IYuanLogger
	{
		void LogFatal(object data);

		void LogError(object data);

		void LogWarning(object data);

		void LogMessage(object data);

		void LogInfo(object data);

		void LogDebug(object data);
	}
	public class LoggerWrapper : IYuanLogger
	{
		public ManualLogSource logSource;

		public LoggerWrapper(ManualLogSource logSource)
		{
			this.logSource = logSource;
		}

		public void LogFatal(object data)
		{
			logSource.LogFatal(data);
		}

		public void LogError(object data)
		{
			logSource.LogError(data);
		}

		public void LogWarning(object data)
		{
			logSource.LogWarning(data);
		}

		public void LogMessage(object data)
		{
			logSource.LogMessage(data);
		}

		public void LogInfo(object data)
		{
			logSource.LogInfo(data);
		}

		public void LogDebug(object data)
		{
			logSource.LogDebug(data);
		}
	}
	public static class YuanLogger
	{
		private static IYuanLogger _logger;

		public static void SetLogger(IYuanLogger logger)
		{
			_logger = logger;
		}

		public static void LogFatal(object data)
		{
			_logger.LogFatal(data);
		}

		public static void LogError(object data)
		{
			_logger.LogError(data);
		}

		public static void LogWarning(object data)
		{
			_logger.LogWarning(data);
		}

		public static void LogMessage(object data)
		{
			_logger.LogMessage(data);
		}

		public static void LogInfo(object data)
		{
			_logger.LogInfo(data);
		}

		public static void LogDebug(object data)
		{
			_logger.LogDebug(data);
		}
	}
	internal static class GameVersion
	{
		public static Version GetGameVersion()
		{
			if (Mainload.Vision_now.Length <= 2)
			{
				return null;
			}
			Version.TryParse(Mainload.Vision_now.Substring(2), out Version version);
			return version;
		}
	}
	public class Version : IComparable<Version>, IEquatable<Version>
	{
		private const string SemVerPattern = "^(?<major>0|[1-9]\\d*)\\.(?<minor>0|[1-9]\\d*)\\.(?<patch>0|[1-9]\\d*)(?:-(?<prerelease>(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$";

		private static readonly Regex SemVerRegex = new Regex("^(?<major>0|[1-9]\\d*)\\.(?<minor>0|[1-9]\\d*)\\.(?<patch>0|[1-9]\\d*)(?:-(?<prerelease>(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", RegexOptions.Compiled);

		public int Major { get; }

		public int Minor { get; }

		public int Patch { get; }

		public string? PreRelease { get; }

		public string? BuildMetadata { get; }

		public Version(int major, int minor, int patch, string? preRelease = null, string? buildMetadata = null)
		{
			if (major < 0)
			{
				throw new ArgumentException("Major version cannot be negative", "major");
			}
			if (minor < 0)
			{
				throw new ArgumentException("Minor version cannot be negative", "minor");
			}
			if (patch < 0)
			{
				throw new ArgumentException("Patch version cannot be negative", "patch");
			}
			Major = major;
			Minor = minor;
			Patch = patch;
			PreRelease = preRelease;
			BuildMetadata = buildMetadata;
		}

		public Version(string versionString)
		{
			if (string.IsNullOrWhiteSpace(versionString))
			{
				throw new ArgumentException("Version string cannot be null or empty", "versionString");
			}
			Match match = SemVerRegex.Match(versionString);
			if (match.Success)
			{
				Major = int.Parse(match.Groups["major"].Value);
				Minor = int.Parse(match.Groups["minor"].Value);
				Patch = int.Parse(match.Groups["patch"].Value);
				PreRelease = (match.Groups["prerelease"].Success ? match.Groups["prerelease"].Value : null);
				BuildMetadata = (match.Groups["buildmetadata"].Success ? match.Groups["buildmetadata"].Value : null);
			}
			throw new ArgumentException("Version string is not SemVer Version", "versionString");
		}

		public static Version Parse(string versionString)
		{
			if (string.IsNullOrWhiteSpace(versionString))
			{
				throw new ArgumentException("Version string cannot be null or empty", "versionString");
			}
			Match match = SemVerRegex.Match(versionString);
			if (match.Success)
			{
				int major = int.Parse(match.Groups["major"].Value);
				int minor = int.Parse(match.Groups["minor"].Value);
				int patch = int.Parse(match.Groups["patch"].Value);
				string preRelease = (match.Groups["prerelease"].Success ? match.Groups["prerelease"].Value : null);
				string buildMetadata = (match.Groups["buildmetadata"].Success ? match.Groups["buildmetadata"].Value : null);
				return new Version(major, minor, patch, preRelease, buildMetadata);
			}
			throw new ArgumentException("Version string is not SemVer Version", "versionString");
		}

		public static bool TryParse(string versionString, out Version? version)
		{
			version = null;
			if (string.IsNullOrWhiteSpace(versionString))
			{
				return false;
			}
			try
			{
				version = Parse(versionString);
				return true;
			}
			catch
			{
				return false;
			}
		}

		public static bool operator ==(Version? left, Version? right)
		{
			if ((object)left == right)
			{
				return true;
			}
			if ((object)left == null || (object)right == null)
			{
				return false;
			}
			return left.CompareTo(right) == 0;
		}

		public static bool operator !=(Version? left, Version? right)
		{
			return !(left == right);
		}

		public static bool operator <(Version? left, Version? right)
		{
			if ((object)left == null)
			{
				return (object)right != null;
			}
			return left.CompareTo(right) < 0;
		}

		public static bool operator <=(Version? left, Version? right)
		{
			if ((object)left == null)
			{
				return true;
			}
			return left.CompareTo(right) <= 0;
		}

		public static bool operator >(Version? left, Version? right)
		{
			return !(left <= right);
		}

		public static bool operator >=(Version? left, Version? right)
		{
			return !(left < right);
		}

		public int CompareTo(Version? other)
		{
			if ((object)other == null)
			{
				return 1;
			}
			int num = Major.CompareTo(other.Major);
			if (num != 0)
			{
				return num;
			}
			int num2 = Minor.CompareTo(other.Minor);
			if (num2 != 0)
			{
				return num2;
			}
			int num3 = Patch.CompareTo(other.Patch);
			if (num3 != 0)
			{
				return num3;
			}
			return ComparePreRelease(PreRelease, other.PreRelease);
		}

		private static int ComparePreRelease(string? preRelease1, string? preRelease2)
		{
			if (string.IsNullOrEmpty(preRelease1) && string.IsNullOrEmpty(preRelease2))
			{
				return 0;
			}
			if (string.IsNullOrEmpty(preRelease1))
			{
				return 1;
			}
			if (string.IsNullOrEmpty(preRelease2))
			{
				return -1;
			}
			string[] array = preRelease1.Split(new char[1] { '.' });
			string[] array2 = preRelease2.Split(new char[1] { '.' });
			int num = Math.Min(array.Length, array2.Length);
			for (int i = 0; i < num; i++)
			{
				string text = array[i];
				string text2 = array2[i];
				int result;
				bool flag = int.TryParse(text, out result);
				int result2;
				bool flag2 = int.TryParse(text2, out result2);
				if (flag && flag2)
				{
					int num2 = result.CompareTo(result2);
					if (num2 != 0)
					{
						return num2;
					}
					continue;
				}
				if (flag)
				{
					return -1;
				}
				if (flag2)
				{
					return 1;
				}
				int num3 = string.Compare(text, text2, StringComparison.Ordinal);
				if (num3 != 0)
				{
					return num3;
				}
			}
			return array.Length.CompareTo(array2.Length);
		}

		public bool Equals(Version? other)
		{
			return CompareTo(other) == 0;
		}

		public override bool Equals(object? obj)
		{
			return obj is Version other && Equals(other);
		}

		public override int GetHashCode()
		{
			int major = Major;
			major = (major * 397) ^ Minor;
			major = (major * 397) ^ Patch;
			return (major * 397) ^ (PreRelease?.GetHashCode() ?? 0);
		}

		public override string ToString()
		{
			string text = $"{Major}.{Minor}.{Patch}";
			if (!string.IsNullOrEmpty(PreRelease))
			{
				text = text + "-" + PreRelease;
			}
			if (!string.IsNullOrEmpty(BuildMetadata))
			{
				text = text + "+" + BuildMetadata;
			}
			return text;
		}
	}
}
namespace YuanAPI.ResourceRegistryPatches
{
	[HarmonyPatch]
	public static class ResourcesPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		[HarmonyPatch(typeof(Resources), "Load", new Type[]
		{
			typeof(string),
			typeof(Type)
		})]
		public static bool Prefix(ref string path, Type systemTypeInstance, ref Object __result, bool __runOriginal)
		{
			if (!__runOriginal)
			{
				return false;
			}
			foreach (ResourceData modResource in ResourceRegistry.ModResources)
			{
				if (!path.Contains(modResource.KeyWord) || !modResource.HasAssetBundle())
				{
					continue;
				}
				if (modResource.Bundle.Contains(path + ".prefab"))
				{
					Object val = modResource.Bundle.LoadAsset(path + ".prefab");
					YuanLogger.LogDebug("Loading registered asset " + path + ": " + ((val != (Object)null) ? "Success" : "Failure"));
					__result = val;
					return false;
				}
				string[] spriteFileExtensions = ResourceRegistry.SpriteFileExtensions;
				foreach (string text in spriteFileExtensions)
				{
					if (modResource.Bundle.Contains(path + text))
					{
						Object val2 = modResource.Bundle.LoadAsset(path + text, systemTypeInstance);
						YuanLogger.LogDebug("Loading registered asset " + path + ": " + ((val2 != (Object)null) ? "Success" : "Failure"));
						__result = val2;
						return false;
					}
				}
				string[] audioClipFileExtensions = ResourceRegistry.AudioClipFileExtensions;
				foreach (string text2 in audioClipFileExtensions)
				{
					if (modResource.Bundle.Contains(path + text2))
					{
						Object val3 = modResource.Bundle.LoadAsset(path + text2, systemTypeInstance);
						YuanLogger.LogDebug("Loading registered asset " + path + ": " + ((val3 != (Object)null) ? "Success" : "Failure"));
						__result = val3;
						return false;
					}
				}
			}
			return true;
		}
	}
}
namespace YuanAPI.PropRegistryPatches
{
	[HarmonyPatch]
	public static class ResourcesPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(400)]
		[HarmonyPatch(typeof(Resources), "Load", new Type[]
		{
			typeof(string),
			typeof(Type)
		})]
		public static bool Prefix(ref string path, Type systemTypeInstance, ref Object __result, bool __runOriginal)
		{
			if (!__runOriginal)
			{
				return false;
			}
			if (!path.StartsWith("AllProp/"))
			{
				return true;
			}
			int index = int.Parse(path.Substring("AllProp/".Length));
			path = PropRegistry.GetProp(index).PrefabPath;
			return true;
		}
	}
	[HarmonyPatch]
	public class SaveDataPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SaveData), "SaveGameData")]
		public static void SaveGameDataPostfix()
		{
			YuanLogger.LogDebug("SaveGameData to UID");
			List<List<string>> propHave = Mainload.Prop_have.Select((List<string> prop) => new List<string>(prop)).ToList();
			int propCount = PropRegistry.VanillaPropCount;
			propHave.ForEach(delegate(List<string> prop)
			{
				if (!int.TryParse(prop[0], out var result))
				{
					YuanLogger.LogError("SaveData: 无法解析数据ID" + prop[0] + ",这可能不是YuanAPI导致的,本次保存将跳过该数据");
					propHave.Remove(prop);
				}
				else if (result >= propCount)
				{
					prop[0] = PropRegistry.GetUid(result);
				}
			});
			ES3.Save<List<List<string>>>("Prop_have", (object)propHave, Mainload.CunDangIndex_now + "/GameData.es3");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SaveData), "ReadGameData")]
		public static void ReadGameDataPostfix()
		{
			YuanLogger.LogDebug("ReadGameData in UID");
			List<List<string>> propHave = Mainload.Prop_have;
			int propCount = PropRegistry.VanillaPropCount;
			propHave.ForEach(delegate(List<string> prop)
			{
				if (!int.TryParse(prop[0], out var result) || result < 0 || result >= propCount)
				{
					if (!PropRegistry.TryGetIndex(prop[0], out var index))
					{
						YuanLogger.LogError("SaveData: 无法解析数据ID" + prop[0] + ",请检查是否有模组未加载,本次加载将跳过该数据");
						propHave.Remove(prop);
					}
					else
					{
						prop[0] = index.ToString();
					}
				}
			});
		}
	}
}
namespace YuanAPI.LocalizationPatches
{
	[HarmonyPatch]
	public class SaveDataPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SaveData), "ReadSetData")]
		public static void LanguageLimitPatch()
		{
			List<int> list = ES3.Load<List<int>>("SetData", "FW/SetData.es3", Mainload.SetData);
			Mainload.SetData[4] = ((list[4] < Localization.LocaleCount()) ? list[4] : 0);
		}
	}
	[HarmonyPatch]
	public class SetPanelPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SetPanel), "SetLanguage")]
		public static void SetLanguagePostFix()
		{
			Localization.CallLanguageChanged(Localization.GetLocale(Mainload.SetData[4]));
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SetPanel), "InitShow")]
		public static void LoadLanguageOption(SetPanel __instance)
		{
			Dropdown component = ((Component)((Component)__instance).transform.Find("Language").Find("AllClass")).GetComponent<Dropdown>();
			component.options = ((IEnumerable<string>)Localization.GetAllShowNames()).Select((Func<string, OptionData>)((string name) => new OptionData(name))).ToList();
			component.value = Mainload.SetData[4];
		}
	}
}