Decompiled source of BepisLocaleLoader v1.2.2

plugins/BepisLocaleLoader/BepisLocaleLoader.dll

Decompiled 2 weeks 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.InteropServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.NET.Common;
using BepInExResoniteShim;
using Elements.Assets;
using Elements.Core;
using FrooxEngine;
using HarmonyLib;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")]
[assembly: AssemblyCompany("ResoniteModding")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) ResoniteModding 2026")]
[assembly: AssemblyDescription("Loads locale files for plugins.")]
[assembly: AssemblyFileVersion("1.2.2.0")]
[assembly: AssemblyInformationalVersion("1.2.2+d11bdf3dd0df63aef1cc48eb3de7de5de4fa3235")]
[assembly: AssemblyProduct("Bepis Locale Loader")]
[assembly: AssemblyTitle("BepisLocaleLoader")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ResoniteModding/BepisLocaleLoader")]
[assembly: AssemblyVersion("1.2.2.0")]
[module: RefSafetyRules(11)]
namespace BepInEx
{
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : global::System.Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null, string? authors = null, string? link = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : global::System.Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	internal sealed class EmbeddedAttribute : global::System.Attribute
	{
	}
}
namespace BepisLocaleLoader
{
	public struct ConfigLocale
	{
		public LocaleString Name;

		public LocaleString Description;

		public ConfigLocale(string name, string description)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			Name = LocaleHelper.AsLocaleKey(name, (string)null, true, (Dictionary<string, object>)null);
			Description = LocaleHelper.AsLocaleKey(description, (string)null, true, (Dictionary<string, object>)null);
		}

		public ConfigLocale(LocaleString name, LocaleString description)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Name = name;
			Description = description;
		}
	}
	public static class ConfigLocaleHelper
	{
		public static ConfigEntry<T> BindLocalized<T>(this ConfigFile config, string guid, string section, string key, T defaultValue, string englishDescription)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_001d: Expected O, but got Unknown
			return config.BindLocalized(guid, new ConfigDefinition(section, key), defaultValue, new ConfigDescription(englishDescription, (AcceptableValueBase)null, global::System.Array.Empty<object>()));
		}

		public static ConfigEntry<T> BindLocalized<T>(this ConfigFile config, string guid, string section, string key, T defaultValue, ConfigDescription? configDescription = null)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			return config.BindLocalized(guid, new ConfigDefinition(section, key), defaultValue, configDescription);
		}

		public static ConfigEntry<T> BindLocalized<T>(this ConfigFile config, string guid, ConfigDefinition configDefinition, T defaultValue, ConfigDescription? configDescription = null)
		{
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			string text = $"Settings.{guid}.{configDefinition.Section}.{configDefinition.Key}";
			string description = text + ".Description";
			ConfigLocale configLocale = new ConfigLocale(text, description);
			string text2 = ((configDescription != null) ? configDescription.Description : null) ?? string.Empty;
			AcceptableValueBase val = ((configDescription != null) ? configDescription.AcceptableValues : null);
			object obj;
			if (configDescription == null)
			{
				obj = new object[1] { configLocale };
			}
			else
			{
				object[] tags = configDescription.Tags;
				int num = 0;
				object[] array = new object[1 + tags.Length];
				global::System.ReadOnlySpan<object> readOnlySpan = new global::System.ReadOnlySpan<object>(tags);
				readOnlySpan.CopyTo(new global::System.Span<object>(array).Slice(num, readOnlySpan.Length));
				num += readOnlySpan.Length;
				array[num] = configLocale;
				obj = array;
			}
			object[] array2 = (object[])obj;
			return config.Bind<T>(configDefinition, defaultValue, new ConfigDescription(text2, val, array2));
		}
	}
	[HarmonyPatch(typeof(LocaleResource), "LoadTargetVariant")]
	internal static class LocaleInjectionPatch
	{
		[CompilerGenerated]
		private sealed class <LoadTargetVariantMoveNextTranspiler>d__3 : global::System.Collections.Generic.IEnumerable<CodeInstruction>, global::System.Collections.IEnumerable, global::System.Collections.Generic.IEnumerator<CodeInstruction>, global::System.Collections.IEnumerator, global::System.IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private global::System.Collections.Generic.IEnumerable<CodeInstruction> instructions;

			public global::System.Collections.Generic.IEnumerable<CodeInstruction> <>3__instructions;

			private global::System.Collections.Generic.IEnumerator<CodeInstruction> <>7__wrap1;

			CodeInstruction global::System.Collections.Generic.IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object global::System.Collections.IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadTargetVariantMoveNextTranspiler>d__3(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void global::System.IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 1u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>7__wrap1 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					case 2:
						<>1__state = -3;
						break;
					}
					if (((global::System.Collections.IEnumerator)<>7__wrap1).MoveNext())
					{
						CodeInstruction current = <>7__wrap1.Current;
						if (!CodeInstructionExtensions.Calls(current, OnLoadStateChangedMethod))
						{
							<>2__current = current;
							<>1__state = 1;
							return true;
						}
						CodeInstruction val = new CodeInstruction(OpCodes.Pop, (object)null);
						val.labels.AddRange((global::System.Collections.Generic.IEnumerable<Label>)current.labels);
						val.blocks.AddRange((global::System.Collections.Generic.IEnumerable<ExceptionBlock>)current.blocks);
						<>2__current = val;
						<>1__state = 2;
						return true;
					}
					<>m__Finally1();
					<>7__wrap1 = null;
					return false;
				}
				catch
				{
					//try-fault
					((global::System.IDisposable)this).Dispose();
					throw;
				}
			}

			bool global::System.Collections.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__wrap1 != null)
				{
					((global::System.IDisposable)<>7__wrap1).Dispose();
				}
			}

			[DebuggerHidden]
			void global::System.Collections.IEnumerator.Reset()
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			global::System.Collections.Generic.IEnumerator<CodeInstruction> global::System.Collections.Generic.IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<LoadTargetVariantMoveNextTranspiler>d__3 <LoadTargetVariantMoveNextTranspiler>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<LoadTargetVariantMoveNextTranspiler>d__ = this;
				}
				else
				{
					<LoadTargetVariantMoveNextTranspiler>d__ = new <LoadTargetVariantMoveNextTranspiler>d__3(0);
				}
				<LoadTargetVariantMoveNextTranspiler>d__.instructions = <>3__instructions;
				return <LoadTargetVariantMoveNextTranspiler>d__;
			}

			[DebuggerHidden]
			global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator()
			{
				return (global::System.Collections.IEnumerator)((global::System.Collections.Generic.IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		[StructLayout((LayoutKind)3)]
		[CompilerGenerated]
		private struct <Postfix>d__4 : IAsyncStateMachine
		{
			public int <>1__state;

			public AsyncTaskMethodBuilder <>t__builder;

			public global::System.Threading.Tasks.Task __result;

			public LocaleResource __instance;

			public bool __state;

			private TaskAwaiter <>u__1;

			private void MoveNext()
			{
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Expected O, but got Unknown
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Expected O, but got Unknown
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_012f: Expected O, but got Unknown
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				try
				{
					bool flag = default(bool);
					try
					{
						TaskAwaiter val;
						if (num != 0)
						{
							val = __result.GetAwaiter();
							if (!((TaskAwaiter)(ref val)).IsCompleted)
							{
								num = (<>1__state = 0);
								<>u__1 = val;
								((AsyncTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted<TaskAwaiter, <Postfix>d__4>(ref val, ref this);
								return;
							}
						}
						else
						{
							val = <>u__1;
							<>u__1 = default(TaskAwaiter);
							num = (<>1__state = -1);
						}
						((TaskAwaiter)(ref val)).GetResult();
					}
					catch (global::System.Exception ex)
					{
						ManualLogSource log = Plugin.Log;
						BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(50, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("LoadTargetVariant failed before locale injection: ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<global::System.Exception>(ex);
						}
						log.LogError(val2);
						goto end_IL_0007;
					}
					if (__instance.Data == null)
					{
						Plugin.Log.LogWarning((object)"LoadTargetVariant completed but Data is null - skipping locale injection");
					}
					else
					{
						try
						{
							InjectAllPluginLocales(__instance.Data);
						}
						catch (global::System.Exception ex2)
						{
							ManualLogSource log2 = Plugin.Log;
							BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(30, 1, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to inject mod locales: ");
								((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<global::System.Exception>(ex2);
							}
							log2.LogError(val2);
						}
						if (__state)
						{
							try
							{
								((MethodBase)OnLoadStateChangedMethod).Invoke((object)__instance, (object[])null);
							}
							catch (global::System.Exception ex3)
							{
								ManualLogSource log3 = Plugin.Log;
								BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(35, 1, ref flag);
								if (flag)
								{
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to notify locale observers: ");
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<global::System.Exception>(ex3);
								}
								log3.LogError(val2);
							}
						}
					}
					end_IL_0007:;
				}
				catch (global::System.Exception exception)
				{
					<>1__state = -2;
					((AsyncTaskMethodBuilder)(ref <>t__builder)).SetException(exception);
					return;
				}
				<>1__state = -2;
				((AsyncTaskMethodBuilder)(ref <>t__builder)).SetResult();
			}

			[DebuggerHidden]
			private void SetStateMachine(IAsyncStateMachine stateMachine)
			{
				((AsyncTaskMethodBuilder)(ref <>t__builder)).SetStateMachine(stateMachine);
			}
		}

		private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
		{
			PropertyNameCaseInsensitive = true,
			ReadCommentHandling = (JsonCommentHandling)1,
			AllowTrailingCommas = true
		};

		private static readonly MethodInfo OnLoadStateChangedMethod = AccessTools.Method(typeof(Asset), "OnLoadStateChanged", (global::System.Type[])null, (global::System.Type[])null) ?? throw new MissingMethodException(typeof(Asset).FullName, "OnLoadStateChanged");

		[HarmonyPrefix]
		private static void Prefix(LocaleResource __instance, out bool __state)
		{
			__state = __instance.Data != null;
		}

		[IteratorStateMachine(typeof(<LoadTargetVariantMoveNextTranspiler>d__3))]
		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static global::System.Collections.Generic.IEnumerable<CodeInstruction> LoadTargetVariantMoveNextTranspiler(global::System.Collections.Generic.IEnumerable<CodeInstruction> instructions)
		{
			global::System.Collections.Generic.IEnumerator<CodeInstruction> enumerator = instructions.GetEnumerator();
			try
			{
				while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
				{
					CodeInstruction current = enumerator.Current;
					if (!CodeInstructionExtensions.Calls(current, OnLoadStateChangedMethod))
					{
						yield return current;
						continue;
					}
					CodeInstruction val = new CodeInstruction(OpCodes.Pop, (object)null);
					val.labels.AddRange((global::System.Collections.Generic.IEnumerable<Label>)current.labels);
					val.blocks.AddRange((global::System.Collections.Generic.IEnumerable<ExceptionBlock>)current.blocks);
					yield return val;
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator)?.Dispose();
			}
		}

		[AsyncStateMachine(typeof(<Postfix>d__4))]
		[HarmonyPostfix]
		private static global::System.Threading.Tasks.Task Postfix(global::System.Threading.Tasks.Task __result, LocaleResource __instance, LocaleVariantDescriptor variant, bool __state)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			<Postfix>d__4 <Postfix>d__ = default(<Postfix>d__4);
			<Postfix>d__.<>t__builder = AsyncTaskMethodBuilder.Create();
			<Postfix>d__.__result = __result;
			<Postfix>d__.__instance = __instance;
			<Postfix>d__.__state = __state;
			<Postfix>d__.<>1__state = -1;
			((AsyncTaskMethodBuilder)(ref <Postfix>d__.<>t__builder)).Start<<Postfix>d__4>(ref <Postfix>d__);
			return ((AsyncTaskMethodBuilder)(ref <Postfix>d__.<>t__builder)).Task;
		}

		private static void InjectAllPluginLocales(LocaleResource localeData)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			if (((BaseChainloader<BasePlugin>)(object)NetChainloader.Instance)?.Plugins == null || ((BaseChainloader<BasePlugin>)(object)NetChainloader.Instance).Plugins.Count == 0)
			{
				Plugin.Log.LogDebug((object)"No BepInEx plugins loaded - skipping locale injection");
				return;
			}
			int num = 0;
			int num2 = 0;
			Enumerator<string, PluginInfo> enumerator = ((BaseChainloader<BasePlugin>)(object)NetChainloader.Instance).Plugins.Values.GetEnumerator();
			bool flag = default(bool);
			try
			{
				while (enumerator.MoveNext())
				{
					PluginInfo current = enumerator.Current;
					string directoryName = Path.GetDirectoryName(current.Location);
					if (string.IsNullOrEmpty(directoryName))
					{
						continue;
					}
					string text = Path.Combine(directoryName, "Locale");
					if (!Directory.Exists(text))
					{
						continue;
					}
					ManualLogSource log = Plugin.Log;
					BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(21, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loading locales from ");
						BepInExDebugLogInterpolatedStringHandler obj = val;
						BepInPlugin metadata = current.Metadata;
						((BepInExLogInterpolatedStringHandler)obj).AppendFormatted<string>(((metadata != null) ? metadata.GUID : null) ?? "unknown");
					}
					log.LogDebug(val);
					string[] files = Directory.GetFiles(text, "*.json", (SearchOption)1);
					foreach (string text2 in files)
					{
						LocaleData val2 = LoadLocaleDataFromFile(text2);
						if (val2 != null)
						{
							localeData.LoadDataAdditively(val2);
							num2 += val2.Messages.Count;
							ManualLogSource log2 = Plugin.Log;
							val = new BepInExDebugLogInterpolatedStringHandler(17, 3, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  - ");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Path.GetFileName(text2));
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(val2.LocaleCode);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
								((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(val2.Messages.Count);
								((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" messages");
							}
							log2.LogDebug(val);
						}
					}
					LocaleLoader.PluginsWithLocales.Add(current);
					num++;
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (num > 0)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(39, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Injected ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num2);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" locale messages from ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" plugins");
				}
				log3.LogInfo(val3);
			}
		}

		private static LocaleData? LoadLocaleDataFromFile(string path)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			string text;
			bool flag = default(bool);
			try
			{
				text = File.ReadAllText(path);
			}
			catch (global::System.Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(28, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Error reading locale file ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(path);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<global::System.Exception>(ex);
				}
				log.LogError(val);
				return null;
			}
			LocaleData val2;
			try
			{
				val2 = JsonSerializer.Deserialize<LocaleData>(text, JsonOptions);
			}
			catch (global::System.Exception ex2)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(28, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Error parsing locale file ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(path);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<global::System.Exception>(ex2);
				}
				log2.LogError(val);
				return null;
			}
			if (((val2 != null) ? val2.Messages : null) == null)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(40, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Invalid locale file (missing messages): ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(path);
				}
				log3.LogError(val);
				return null;
			}
			return val2;
		}
	}
	public static class LocaleLoader
	{
		internal static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions
		{
			PropertyNameCaseInsensitive = true,
			ReadCommentHandling = (JsonCommentHandling)1,
			AllowTrailingCommas = true
		};

		private static readonly object _pluginsLock = new object();

		public static readonly HashSet<PluginInfo> PluginsWithLocales = new HashSet<PluginInfo>();

		internal static void TrackPluginWithLocale(PluginInfo plugin)
		{
			lock (_pluginsLock)
			{
				PluginsWithLocales.Add(plugin);
			}
		}

		public static void AddLocaleString(string rawString, string localeString, bool force = false, string? authors = null)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			List<string> authors2 = Enumerable.ToList<string>((global::System.Collections.Generic.IEnumerable<string>)((!string.IsNullOrWhiteSpace(authors)) ? authors : ((!string.IsNullOrWhiteSpace("ResoniteModding")) ? "ResoniteModding" : "BepInEx")).Split(", ", (StringSplitOptions)1));
			LocaleData val = new LocaleData
			{
				LocaleCode = "en-US",
				Authors = authors2
			};
			Dictionary<string, string> obj = new Dictionary<string, string>();
			obj.Add(rawString, localeString);
			val.Messages = obj;
			InjectLocaleData(val, force);
		}

		public static void AddLocaleFromPlugin(PluginInfo plugin)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//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)
			List<string> val = Enumerable.ToList<string>(GetPluginLocaleFiles(plugin));
			if (val.Count == 0)
			{
				return;
			}
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExDebugLogInterpolatedStringHandler val2 = new BepInExDebugLogInterpolatedStringHandler(18, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Adding locale for ");
				BepInPlugin metadata = plugin.Metadata;
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((metadata != null) ? metadata.GUID : null) ?? "unknown");
			}
			log.LogDebug(val2);
			Enumerator<string> enumerator = val.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					AddLocaleFromFile(enumerator.Current);
				}
			}
			finally
			{
				((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			TrackPluginWithLocale(plugin);
		}

		internal static global::System.Collections.Generic.IEnumerable<string> GetPluginLocaleFiles(PluginInfo plugin)
		{
			string directoryName = Path.GetDirectoryName(plugin.Location);
			if (string.IsNullOrEmpty(directoryName))
			{
				return global::System.Array.Empty<string>();
			}
			string text = Path.Combine(directoryName, "Locale");
			if (!Directory.Exists(text))
			{
				return global::System.Array.Empty<string>();
			}
			return Directory.GetFiles(text, "*.json", (SearchOption)1);
		}

		public static void AddLocaleFromFile(string path)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			LocaleData val = LoadLocaleDataFromFile(path);
			if (val != null)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExDebugLogInterpolatedStringHandler val2 = new BepInExDebugLogInterpolatedStringHandler(31, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("- LocaleCode: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(val.LocaleCode);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", Message Count: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(val.Messages.Count);
				}
				log.LogDebug(val2);
				InjectLocaleData(val, force: true);
			}
		}

		internal static LocaleData? LoadLocaleDataFromFile(string path)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			if (!File.Exists(path))
			{
				return null;
			}
			string text;
			bool flag = default(bool);
			try
			{
				text = File.ReadAllText(path);
			}
			catch (global::System.Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(28, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Error reading locale file ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(path);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<global::System.Exception>(ex);
				}
				log.LogError(val);
				return null;
			}
			LocaleData val2;
			try
			{
				val2 = JsonSerializer.Deserialize<LocaleData>(text, JsonOptions);
			}
			catch (global::System.Exception ex2)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(28, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Error parsing locale file ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(path);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<global::System.Exception>(ex2);
				}
				log2.LogError(val);
				return null;
			}
			if (((val2 != null) ? val2.Messages : null) == null)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(40, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Invalid locale file (missing messages): ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(path);
				}
				log3.LogError(val);
				return null;
			}
			return val2;
		}

		private static void InjectLocaleData(LocaleData localeData, bool force)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			World userspaceWorld = Userspace.UserspaceWorld;
			StaticLocaleProvider val = ((userspaceWorld != null) ? LocaleHelper.GetCoreLocale((IWorldElement)(object)userspaceWorld) : null);
			object obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				LocaleResource asset = ((AssetProvider<LocaleResource>)(object)val).Asset;
				obj = ((asset != null) ? asset.Data : null);
			}
			if (obj == null)
			{
				Plugin.Log.LogWarning((object)"Cannot inject locale data - locale provider not available yet");
				return;
			}
			if (!force)
			{
				string firstKey = Enumerable.FirstOrDefault<string>((global::System.Collections.Generic.IEnumerable<string>)localeData.Messages.Keys);
				if (firstKey != null && Enumerable.Any<KeyValuePair<string, Message>>((global::System.Collections.Generic.IEnumerable<KeyValuePair<string, Message>>)(object)((AssetProvider<LocaleResource>)(object)val).Asset.Data.Messages, (Func<KeyValuePair<string, Message>, bool>)((KeyValuePair<string, Message> ld) => ld.Key == firstKey)))
				{
					return;
				}
			}
			((AssetProvider<LocaleResource>)(object)val).Asset.Data.LoadDataAdditively(localeData);
		}

		private static string GetFormattedLocaleString(this string key, string? format, Dictionary<string, object>? dict, ValueTuple<string, object>[]? arguments)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			World userspaceWorld = Userspace.UserspaceWorld;
			StaticLocaleProvider val = ((userspaceWorld != null) ? LocaleHelper.GetCoreLocale((IWorldElement)(object)userspaceWorld) : null);
			Dictionary<string, object> val2 = ((dict != null) ? new Dictionary<string, object>((IDictionary<string, object>)(object)dict) : new Dictionary<string, object>());
			if (arguments != null)
			{
				for (int i = 0; i < arguments.Length; i++)
				{
					ValueTuple<string, object> val3 = arguments[i];
					string item = val3.Item1;
					object item2 = val3.Item2;
					val2[item] = item2;
				}
			}
			object obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				LocaleResource asset = ((AssetProvider<LocaleResource>)(object)val).Asset;
				obj = ((asset != null) ? asset.Format(key, val2, false) : null);
			}
			string text = (string)obj;
			if (!string.IsNullOrWhiteSpace(format))
			{
				text = string.Format(format, (object)text);
			}
			return text ?? key;
		}

		public static string GetFormattedLocaleString(this string key)
		{
			return key.GetFormattedLocaleString((string?)null, (Dictionary<string, object>?)null, (ValueTuple<string, object>[]?)null);
		}

		public static string GetFormattedLocaleString(this string key, string format)
		{
			return key.GetFormattedLocaleString(format, (Dictionary<string, object>?)null, (ValueTuple<string, object>[]?)null);
		}

		public static string GetFormattedLocaleString(this string key, string argName, object argField)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return key.GetFormattedLocaleString(null, null, new ValueTuple<string, object>[1]
			{
				new ValueTuple<string, object>(argName, argField)
			});
		}

		public static string GetFormattedLocaleString(this string key, string format, string argName, object argField)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return key.GetFormattedLocaleString(format, null, new ValueTuple<string, object>[1]
			{
				new ValueTuple<string, object>(argName, argField)
			});
		}

		public static string GetFormattedLocaleString(this string key, params ValueTuple<string, object>[] arguments)
		{
			return key.GetFormattedLocaleString(null, null, arguments);
		}

		public static string GetFormattedLocaleString(this string key, string format, params ValueTuple<string, object>[] arguments)
		{
			return key.GetFormattedLocaleString(format, null, arguments);
		}

		public static LocaleString T(this string str, string argName, object argField)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return LocaleHelper.AsLocaleKey(str, (string)null, new ValueTuple<string, object>[1]
			{
				new ValueTuple<string, object>(argName, argField)
			});
		}

		public static LocaleString T(this string str, string format, string argName, object argField)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return LocaleHelper.AsLocaleKey(str, format, new ValueTuple<string, object>[1]
			{
				new ValueTuple<string, object>(argName, argField)
			});
		}

		public static LocaleString T(this string str, params ValueTuple<string, object>[] arguments)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return LocaleHelper.AsLocaleKey(str, (string)null, arguments);
		}

		public static LocaleString T(this string str, string format, params ValueTuple<string, object>[] arguments)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return LocaleHelper.AsLocaleKey(str, format, arguments);
		}

		public static LocaleString T(this string str, bool continuous, Dictionary<string, object>? arguments = null)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return new LocaleString(str, (string)null, true, continuous, arguments);
		}

		public static LocaleString T(this string str, string? format = null, bool continuous = true, Dictionary<string, object>? arguments = null)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return new LocaleString(str, format, true, continuous, arguments);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[ResonitePlugin("ResoniteModding.BepisLocaleLoader", "Bepis Locale Loader", "1.2.2+d11bdf3dd0df63aef1cc48eb3de7de5de4fa3235", "ResoniteModding", "https://github.com/ResoniteModding/BepisLocaleLoader")]
	public class Plugin : BasePlugin
	{
		internal static ManualLogSource Log;

		public const string GUID = "ResoniteModding.BepisLocaleLoader";

		public const string NAME = "Bepis Locale Loader";

		public const string VERSION = "1.2.2+d11bdf3dd0df63aef1cc48eb3de7de5de4fa3235";

		public const string AUTHORS = "ResoniteModding";

		public const string REPOSITORY_URL = "https://github.com/ResoniteModding/BepisLocaleLoader";

		public override void Load()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			((BasePlugin)this).HarmonyInstance.PatchAll();
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("ResoniteModding.BepisLocaleLoader");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
			}
			log.LogInfo(val);
		}
	}
}