Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of AF JPRefine v1.0.0
AF_JPRefine.dll
Decompiled 4 hours agousing System; using System.Collections; 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.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Localization; using UnityEngine.Localization.Components; using UnityEngine.Localization.Settings; using UnityEngine.Localization.Tables; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("Kuraputi")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("AF_JPRefine")] [assembly: AssemblyTitle("AF_JPRefine")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 AF_JPRefine { [BepInPlugin("Kuraputi.AF_JPRefine", "AF_JPRefine", "1.0.0")] public class AF_JPRefine : BaseUnityPlugin { private const string TableName = "Game"; private ConfigEntry<bool> DumpEnabled; internal static AF_JPRefine Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Patch(); DumpEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDump", false, "ゲーム起動時に翻訳データのダンプを行う(OFF推奨)"); ((MonoBehaviour)this).StartCoroutine(DumpTables()); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } internal void Patch() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0025: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { } private IEnumerator DumpTables() { yield return null; AsyncOperationHandle<LocalizationSettings> init = LocalizationSettings.InitializationOperation; yield return init; if ((int)init.Status != 1) { Logger.LogError((object)$"Localization init failed: {init.OperationException}"); yield break; } _ = LocalizationSettings.AvailableLocales.Locales; Locale ja = FindLocale("ja-JP", "Japanese"); Locale en = FindLocale("en-US", "English"); if ((Object)(object)ja == (Object)null || (Object)(object)en == (Object)null) { Logger.LogError((object)"Japanese or English locale not found."); yield break; } if (DumpEnabled.Value) { AsyncOperationHandle<IList<StringTable>> allJaOp = ((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).GetAllTables(ja); yield return allJaOp; if ((int)allJaOp.Status != 1 || allJaOp.Result == null) { Logger.LogError((object)"Failed to load Japanese tables."); yield break; } StringBuilder sb = new StringBuilder(); sb.AppendLine("Table\tKeyId\tKey\tEnglish\tJapanese"); int total = 0; foreach (StringTable jaTable in allJaOp.Result) { string tableName = ((LocalizationTable)jaTable).TableCollectionName; AsyncOperationHandle<StringTable> enOp = ((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).GetTableAsync(TableReference.op_Implicit(tableName), en); yield return enOp; StringTable result = enOp.Result; int num = 0; foreach (SharedTableEntry entry3 in ((LocalizationTable)jaTable).SharedData.Entries) { object obj; if (result == null) { obj = null; } else { StringTableEntry entry = ((DetailedLocalizationTable<StringTableEntry>)(object)result).GetEntry(entry3.Id); obj = ((entry != null) ? entry.Value : null); } if (obj == null) { obj = ""; } string s = (string)obj; StringTableEntry entry2 = ((DetailedLocalizationTable<StringTableEntry>)(object)jaTable).GetEntry(entry3.Id); string s2 = ((entry2 != null) ? entry2.Value : null) ?? ""; sb.AppendLine($"{tableName}\t{entry3.Id}\t{entry3.Key}\t{Escape(s)}\t{Escape(s2)}"); num++; } Logger.LogInfo((object)$"Table '{tableName}': {num} entries"); total += num; } string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "dump_All.tsv"); File.WriteAllText(text, sb.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)); Logger.LogInfo((object)$"Dumped {total} entries to {text}"); } yield return ((MonoBehaviour)this).StartCoroutine(ApplyOverrides(ja)); RefreshDisplayedTexts(); } private static Locale? FindLocale(string code, string nameHint) { List<Locale> locales = LocalizationSettings.AvailableLocales.Locales; return ((IEnumerable<Locale>)locales).FirstOrDefault((Func<Locale, bool>)delegate(Locale l) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) LocaleIdentifier identifier = l.Identifier; return ((LocaleIdentifier)(ref identifier)).Code == code; }) ?? ((IEnumerable<Locale>)locales).FirstOrDefault((Func<Locale, bool>)((Locale l) => l.LocaleName.Contains(nameHint))); } private static string Escape(string s) { return s.Replace("\\", "\\\\").Replace("\t", "\\t").Replace("\r", "") .Replace("\n", "\\n"); } private IEnumerator ApplyOverrides(Locale ja) { string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "translation_ja.tsv"); if (!File.Exists(path)) { Logger.LogWarning((object)("Translation file not found: " + path)); yield break; } int applied = 0; int lineNo = 0; Dictionary<string, StringTable?> tableCache = new Dictionary<string, StringTable>(); string[] array = File.ReadAllLines(path, Encoding.UTF8); foreach (string text in array) { lineNo++; if (string.IsNullOrWhiteSpace(text) || text.StartsWith("#") || text.StartsWith("Table\t")) { continue; } string[] array2 = text.Split('\t'); string tableName; string key; string text2; if (array2.Length >= 5) { tableName = array2[0].Trim(); key = array2[2].Trim(); text2 = Unescape(array2[4]); } else { if (array2.Length < 3) { Logger.LogWarning((object)$"Line {lineNo}: column count is wrong ({array2.Length})"); continue; } tableName = array2[0].Trim(); key = array2[1].Trim(); text2 = Unescape(array2[2]); } if (string.IsNullOrEmpty(text2)) { continue; } if (!tableCache.TryGetValue(tableName, out StringTable value)) { AsyncOperationHandle<StringTable> op = ((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).GetTableAsync(TableReference.op_Implicit(tableName), ja); yield return op; value = (tableCache[tableName] = op.Result); } if ((Object)(object)value == (Object)null) { Logger.LogWarning((object)$"Line {lineNo}: table '{tableName}' not found"); continue; } if (!((LocalizationTable)value).SharedData.Contains(key)) { Logger.LogWarning((object)$"Line {lineNo}: key '{key}' not found in '{tableName}'"); continue; } StringTableEntry entry = ((DetailedLocalizationTable<StringTableEntry>)(object)value).GetEntry(key); if (entry == null) { ((DetailedLocalizationTable<StringTableEntry>)(object)value).AddEntry(key, text2); } else { entry.Value = text2; } applied++; } Logger.LogInfo((object)$"Applied {applied} translation overrides from {path}"); } private static string Unescape(string s) { StringBuilder stringBuilder = new StringBuilder(s.Length); for (int i = 0; i < s.Length; i++) { if (s[i] == '\\' && i + 1 < s.Length) { switch (s[i + 1]) { case 'n': stringBuilder.Append('\n'); i++; continue; case 't': stringBuilder.Append('\t'); i++; continue; case '\\': stringBuilder.Append('\\'); i++; continue; } } stringBuilder.Append(s[i]); } return stringBuilder.ToString(); } private void RefreshDisplayedTexts() { LocalizeStringEvent[] array = Object.FindObjectsByType<LocalizeStringEvent>((FindObjectsInactive)1, (FindObjectsSortMode)0); LocalizeStringEvent[] array2 = array; foreach (LocalizeStringEvent val in array2) { val.RefreshString(); } Logger.LogInfo((object)$"Refreshed {array.Length} localized texts"); } } }