Decompiled source of R2API Language v1.1.0

plugins/R2API.Language/R2API.Language.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using On.RoR2;
using R2API.AutoVersionGen;
using RoR2;
using SimpleJSON;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("R2API.Language")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+ffc5850733a2a6b46fa7b73101a8b66014adc773")]
[assembly: AssemblyProduct("R2API.Language")]
[assembly: AssemblyTitle("R2API.Language")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[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 System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[DebuggerNonUserCode]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace R2API
{
	[AutoVersion]
	public static class LanguageAPI
	{
		public class LanguageOverlay
		{
			public readonly ReadOnlyCollection<OverlayTokenData> readOnlyOverlays;

			private readonly List<OverlayTokenData> overlayTokenDatas;

			internal LanguageOverlay(List<OverlayTokenData> data)
			{
				overlayTokenDatas = data;
				readOnlyOverlays = overlayTokenDatas.AsReadOnly();
				temporaryOverlays.Add(this);
				Add();
			}

			private void Add()
			{
				foreach (OverlayTokenData readOnlyOverlay in readOnlyOverlays)
				{
					if (!OverlayLanguage.ContainsKey(readOnlyOverlay.lang))
					{
						OverlayLanguage.Add(readOnlyOverlay.lang, new Dictionary<string, string>());
					}
					OverlayLanguage[readOnlyOverlay.lang][readOnlyOverlay.key] = readOnlyOverlay.value;
				}
			}

			public void Remove()
			{
				SetHooks();
				temporaryOverlays.Remove(this);
				OverlayLanguage.Clear();
				foreach (LanguageOverlay temporaryOverlay in temporaryOverlays)
				{
					temporaryOverlay.Add();
				}
			}
		}

		public struct OverlayTokenData
		{
			public string key;

			public string value;

			public string lang;

			public bool isGeneric;

			internal OverlayTokenData(string _key, string _value, string _lang)
			{
				key = _key;
				value = _value;
				isGeneric = _lang == "generic";
				lang = _lang;
			}

			internal OverlayTokenData(string _key, string _value)
			{
				key = _key;
				value = _value;
				lang = "generic";
				isGeneric = true;
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_GetLocalizedStringByToken <0>__Language_GetLocalizedStringByToken;

			public static hook_TokenIsRegistered <1>__Language_TokenIsRegistered;
		}

		public const string PluginGUID = "com.bepis.r2api.language";

		public const string PluginName = "R2API.Language";

		private static readonly Dictionary<string, Dictionary<string, string>> CustomLanguage = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Dictionary<string, string>> OverlayLanguage = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

		private static readonly List<LanguageOverlay> temporaryOverlays = new List<LanguageOverlay>();

		private const string GenericLanguage = "generic";

		private const string GenericLanguageButNamedDifferentlyBecauseReasons = "strings";

		private static bool _hooksEnabled = false;

		public const string PluginVersion = "1.1.0";

		[Obsolete("All submodules are automatically loaded and this property is now unused")]
		public static bool Loaded => true;

		internal static void SetHooks()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			if (!_hooksEnabled)
			{
				_hooksEnabled = true;
				LoadLanguageFilesFromPluginFolder();
				_hooksEnabled = false;
				object obj = <>O.<0>__Language_GetLocalizedStringByToken;
				if (obj == null)
				{
					hook_GetLocalizedStringByToken val = Language_GetLocalizedStringByToken;
					<>O.<0>__Language_GetLocalizedStringByToken = val;
					obj = (object)val;
				}
				Language.GetLocalizedStringByToken += (hook_GetLocalizedStringByToken)obj;
				object obj2 = <>O.<1>__Language_TokenIsRegistered;
				if (obj2 == null)
				{
					hook_TokenIsRegistered val2 = Language_TokenIsRegistered;
					<>O.<1>__Language_TokenIsRegistered = val2;
					obj2 = (object)val2;
				}
				Language.TokenIsRegistered += (hook_TokenIsRegistered)obj2;
				_hooksEnabled = true;
			}
		}

		private static void LoadLanguageFilesFromPluginFolder()
		{
			string[] files = Directory.GetFiles(Paths.PluginPath, "*.language", SearchOption.AllDirectories);
			for (int i = 0; i < files.Length; i++)
			{
				AddPath(files[i]);
			}
		}

		internal static void UnsetHooks()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//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)
			//IL_003b: Expected O, but got Unknown
			object obj = <>O.<0>__Language_GetLocalizedStringByToken;
			if (obj == null)
			{
				hook_GetLocalizedStringByToken val = Language_GetLocalizedStringByToken;
				<>O.<0>__Language_GetLocalizedStringByToken = val;
				obj = (object)val;
			}
			Language.GetLocalizedStringByToken -= (hook_GetLocalizedStringByToken)obj;
			object obj2 = <>O.<1>__Language_TokenIsRegistered;
			if (obj2 == null)
			{
				hook_TokenIsRegistered val2 = Language_TokenIsRegistered;
				<>O.<1>__Language_TokenIsRegistered = val2;
				obj2 = (object)val2;
			}
			Language.TokenIsRegistered -= (hook_TokenIsRegistered)obj2;
			_hooksEnabled = false;
		}

		private static bool Language_TokenIsRegistered(orig_TokenIsRegistered orig, Language self, string token)
		{
			string name = self.name;
			if (OverlayLanguage.ContainsKey(name) && OverlayLanguage[name].ContainsKey(token))
			{
				return true;
			}
			if (OverlayLanguage.ContainsKey("generic") && OverlayLanguage["generic"].ContainsKey(token))
			{
				return true;
			}
			if (CustomLanguage.ContainsKey(name) && CustomLanguage[name].ContainsKey(token))
			{
				return true;
			}
			if (CustomLanguage.ContainsKey("generic") && CustomLanguage["generic"].ContainsKey(token))
			{
				return true;
			}
			return orig.Invoke(self, token);
		}

		private static string Language_GetLocalizedStringByToken(orig_GetLocalizedStringByToken orig, Language self, string token)
		{
			string name = self.name;
			if (OverlayLanguage.ContainsKey(name) && OverlayLanguage[name].ContainsKey(token))
			{
				return OverlayLanguage[name][token];
			}
			if (OverlayLanguage.ContainsKey("generic") && OverlayLanguage["generic"].ContainsKey(token))
			{
				return OverlayLanguage["generic"][token];
			}
			if (CustomLanguage.ContainsKey(name) && CustomLanguage[name].ContainsKey(token))
			{
				return CustomLanguage[name][token];
			}
			if (CustomLanguage.ContainsKey("generic") && CustomLanguage["generic"].ContainsKey(token))
			{
				return CustomLanguage["generic"][token];
			}
			return orig.Invoke(self, token);
		}

		private static Dictionary<string, Dictionary<string, string>>? LoadFile(string fileContent)
		{
			Dictionary<string, Dictionary<string, string>> dictionary = new Dictionary<string, Dictionary<string, string>>();
			try
			{
				JSONNode val = JSON.Parse(fileContent);
				if (val == (object)null)
				{
					return null;
				}
				foreach (string key in val.Keys)
				{
					JSONNode val2 = val[key];
					if (val2 == (object)null)
					{
						continue;
					}
					string text = key;
					if (text == "strings")
					{
						text = "generic";
					}
					if (!dictionary.ContainsKey(text))
					{
						dictionary.Add(text, new Dictionary<string, string>());
					}
					Dictionary<string, string> dictionary2 = dictionary[text];
					foreach (string key2 in val2.Keys)
					{
						dictionary2.Add(key2, val2[key2].Value);
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogFormat("Parsing error in language file , Error: {0}", new object[1] { ex });
				return null;
			}
			if (dictionary.Count == 0)
			{
				return null;
			}
			return dictionary;
		}

		public static void Add(string? key, string? value)
		{
			SetHooks();
			if (key == null)
			{
				throw new NullReferenceException("param key is null");
			}
			if (value == null)
			{
				throw new NullReferenceException("param value is null");
			}
			Add(key, value, "generic");
		}

		public static void Add(string? key, string? value, string? language)
		{
			SetHooks();
			if (key == null)
			{
				throw new NullReferenceException("param key is null");
			}
			if (value == null)
			{
				throw new NullReferenceException("param value is null");
			}
			if (language == null)
			{
				throw new NullReferenceException("param language is null");
			}
			if (!CustomLanguage.ContainsKey(language))
			{
				CustomLanguage.Add(language, new Dictionary<string, string>());
			}
			Dictionary<string, string> dictionary = CustomLanguage[language];
			if (!dictionary.ContainsKey(key))
			{
				dictionary.Add(key, value);
			}
		}

		public static void AddPath(string? path)
		{
			SetHooks();
			if (path == null)
			{
				throw new NullReferenceException("param path is null");
			}
			Add(File.ReadAllText(path));
		}

		public static void Add(string? file)
		{
			SetHooks();
			if (file == null)
			{
				throw new NullReferenceException("param file is null");
			}
			Dictionary<string, Dictionary<string, string>> dictionary = LoadFile(file);
			if (dictionary != null)
			{
				Add(dictionary);
			}
		}

		public static void Add(Dictionary<string, string?>? tokenDictionary)
		{
			SetHooks();
			Add(tokenDictionary, "generic");
		}

		public static void Add(Dictionary<string, string?>? tokenDictionary, string? language)
		{
			SetHooks();
			if (tokenDictionary == null)
			{
				throw new NullReferenceException("param tokenDictionary is null");
			}
			foreach (KeyValuePair<string, string> item in tokenDictionary)
			{
				if (item.Value != null)
				{
					Add(item.Key, item.Value, language);
				}
			}
		}

		public static void Add(Dictionary<string, Dictionary<string, string?>?>? languageDictionary)
		{
			SetHooks();
			if (languageDictionary == null)
			{
				throw new NullReferenceException("param languageDictionary is null");
			}
			foreach (KeyValuePair<string, Dictionary<string, string>> item in languageDictionary)
			{
				Add(item.Value, item.Key);
			}
		}

		public static LanguageOverlay AddOverlay(string? key, string? value)
		{
			SetHooks();
			if (key == null)
			{
				throw new NullReferenceException("param key is null");
			}
			if (value == null)
			{
				throw new NullReferenceException("param value is null");
			}
			return AddOverlay(key, value, "generic");
		}

		public static LanguageOverlay AddOverlay(string? key, string? value, string? lang)
		{
			SetHooks();
			if (key == null)
			{
				throw new NullReferenceException("param key is null");
			}
			if (value == null)
			{
				throw new NullReferenceException("param value is null");
			}
			if (lang == null)
			{
				throw new NullReferenceException("param lang is null");
			}
			return new LanguageOverlay(new List<OverlayTokenData>(1)
			{
				new OverlayTokenData(key, value, lang)
			});
		}

		public static LanguageOverlay? AddOverlayPath(string? path)
		{
			SetHooks();
			if (path == null)
			{
				throw new NullReferenceException("param path is null");
			}
			string text = File.ReadAllText(path);
			if (text == null)
			{
				return null;
			}
			return AddOverlay(text);
		}

		public static LanguageOverlay? AddOverlay(string? file)
		{
			SetHooks();
			if (file == null)
			{
				throw new NullReferenceException("param file is null");
			}
			Dictionary<string, Dictionary<string, string>> dictionary = LoadFile(file);
			if (dictionary == null)
			{
				return null;
			}
			return AddOverlay(dictionary);
		}

		public static LanguageOverlay AddOverlay(Dictionary<string, string?>? tokenDictionary)
		{
			SetHooks();
			if (tokenDictionary == null)
			{
				throw new NullReferenceException("param tokenDictionary is null");
			}
			return AddOverlay(tokenDictionary, "generic");
		}

		public static LanguageOverlay AddOverlay(Dictionary<string, string?>? tokenDictionary, string? language)
		{
			SetHooks();
			if (tokenDictionary == null)
			{
				throw new NullReferenceException("param tokenDictionary is null");
			}
			if (language == null)
			{
				throw new NullReferenceException("param language is null");
			}
			List<OverlayTokenData> list = new List<OverlayTokenData>(tokenDictionary.Count);
			AddTokensToList(list, language, tokenDictionary);
			return new LanguageOverlay(list);
		}

		public static LanguageOverlay AddOverlay(Dictionary<string, Dictionary<string, string?>?>? languageDictionary)
		{
			SetHooks();
			if (languageDictionary == null)
			{
				throw new NullReferenceException("param languageDictionary is null");
			}
			List<OverlayTokenData> list = new List<OverlayTokenData>();
			foreach (var (language, dictionary2) in languageDictionary)
			{
				if (dictionary2 != null)
				{
					AddTokensToList(list, language, dictionary2);
				}
			}
			return new LanguageOverlay(list);
		}

		private static void AddTokensToList(List<OverlayTokenData> list, string language, Dictionary<string, string?> tokens)
		{
			foreach (var (key, text3) in tokens)
			{
				if (text3 != null)
				{
					list.Add(new OverlayTokenData(key, text3, language));
				}
			}
		}
	}
	[BepInPlugin("com.bepis.r2api.language", "R2API.Language", "1.1.0")]
	public sealed class LanguagePlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
		}

		private void OnEnable()
		{
			LanguageAPI.SetHooks();
		}

		private void OnDisable()
		{
			LanguageAPI.UnsetHooks();
		}
	}
}
namespace R2API.AutoVersionGen
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	internal class AutoVersionAttribute : Attribute
	{
	}
}