Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of R2API Language v1.1.0
plugins/R2API.Language/R2API.Language.dll
Decompiled 3 weeks agousing 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 { } }