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 Sweet Russian Translate v0.1.0
SweetRussianTranslate.dll
Decompiled 3 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Localization.Settings; using UnityEngine.Localization.Tables; using UnityEngine.TextCore; [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("SweetRussianTranslate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("SweetRussianTranslate")] [assembly: AssemblyTitle("SweetRussianTranslate")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 SweetRussianTranslate { [BepInPlugin("sweet.russiantranslate", "Sweet Russian Translate", "0.1.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "sweet.russiantranslate"; internal static ManualLogSource Log; internal static string ModFolder; private void Awake() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ModFolder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); new Harmony("sweet.russiantranslate").PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)("Sweet Russian Translate loaded from " + ModFolder)); } } [HarmonyPatch(typeof(SemiUI), "Start")] internal static class HardcodedLabelPatch { private static Dictionary<string, string> labels; [HarmonyPostfix] private static void Postfix(SemiUI __instance) { if (labels == null) { labels = LoadLabels(); } if (labels.Count == 0) { return; } TMP_Text[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if (val.text != null && labels.TryGetValue(val.text, out var value)) { val.text = value; } } } private static Dictionary<string, string> LoadLabels() { Dictionary<string, string> dictionary = new Dictionary<string, string>(); string path = Path.Combine(Plugin.ModFolder, "Hardcoded.tsv"); if (!File.Exists(path)) { return dictionary; } try { string[] array = File.ReadAllLines(path, Encoding.UTF8); foreach (string text in array) { if (!string.IsNullOrWhiteSpace(text) && !text.StartsWith("#")) { string[] array2 = text.Split('\t'); if (array2.Length == 2 && !string.IsNullOrWhiteSpace(array2[1])) { dictionary[array2[0]] = array2[1].Replace("\\n", "\n"); } } } Plugin.Log.LogInfo((object)("Loaded " + dictionary.Count + " hardcoded label replacements.")); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to read Hardcoded.tsv: " + ex.Message)); } return dictionary; } } [HarmonyPatch(typeof(LocalizationManager), "Awake")] internal static class LocalizationOverridePatch { private static readonly string[] TableNames = new string[3] { "HUD", "Menu", "Game" }; private static bool fontLoaded; [HarmonyPostfix] private static void Postfix() { LoadCyrillicFallbackFont(); string[] tableNames = TableNames; foreach (string text in tableNames) { try { ApplyTable(text); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to apply " + text + ".tsv: " + ex.Message)); } } } private static void ApplyTable(string tableName) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) string text = Path.Combine(Plugin.ModFolder, tableName + ".tsv"); if (!File.Exists(text)) { Plugin.Log.LogWarning((object)("Missing translation file: " + text)); return; } StringTable table = ((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).GetTable(TableReference.op_Implicit(tableName), LocalizationSettings.ProjectLocale); if ((Object)(object)table == (Object)null) { Plugin.Log.LogError((object)("String table not found: " + tableName)); return; } int num = 0; string[] array = File.ReadAllLines(text, Encoding.UTF8); foreach (string text2 in array) { if (string.IsNullOrWhiteSpace(text2) || text2.StartsWith("#")) { continue; } string[] array2 = text2.Split('\t'); if (array2.Length == 2 && !string.IsNullOrWhiteSpace(array2[1])) { string text3 = array2[1].Replace("\\n", "\n"); StringTableEntry entry = ((DetailedLocalizationTable<StringTableEntry>)(object)table).GetEntry(array2[0]); if (entry != null) { entry.Value = text3; } else { ((DetailedLocalizationTable<StringTableEntry>)(object)table).AddEntry(array2[0], text3); } num++; } } Plugin.Log.LogInfo((object)("Applied " + num + " strings to table " + tableName + ".")); } private static void LoadCyrillicFallbackFont() { //IL_005a: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown if (fontLoaded) { return; } fontLoaded = true; string text = Path.Combine(Plugin.ModFolder, "Teko-Cyrillic.ttf"); if (!File.Exists(text)) { Plugin.Log.LogError((object)("Font not found: " + text)); return; } try { TMP_FontAsset val = FindGameTekoAsset(); TMP_FontAsset obj; if (!((Object)(object)val != (Object)null)) { obj = TMP_FontAsset.CreateFontAsset(new Font(text)); } else { Font val2 = new Font(text); FaceInfo faceInfo = val.faceInfo; obj = TMP_FontAsset.CreateFontAsset(val2, ((FaceInfo)(ref faceInfo)).pointSize, val.atlasPadding, val.atlasRenderMode, val.atlasWidth, val.atlasHeight, (AtlasPopulationMode)1, true); } TMP_FontAsset val3 = obj; ((Object)val3).name = "Teko-Cyrillic SDF"; ((Object)val3).hideFlags = (HideFlags)32; if ((Object)(object)val != (Object)null) { CopyVerticalMetrics(val, val3); } TMP_Settings.fallbackFontAssets?.Insert(0, val3); TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); foreach (TMP_FontAsset val4 in array) { if (!((Object)(object)val4 == (Object)(object)val3) && ((Object)val4).name.Contains("Teko")) { if (val4.fallbackFontAssetTable == null) { val4.fallbackFontAssetTable = new List<TMP_FontAsset>(); } val4.fallbackFontAssetTable.Insert(0, val3); } } Plugin.Log.LogInfo((object)("Cyrillic fallback font registered" + (((Object)(object)val != (Object)null) ? (" (matched to " + ((Object)val).name + ").") : " (no Teko reference found)."))); } catch (Exception ex) { Plugin.Log.LogError((object)("Failed to load Cyrillic font: " + ex)); } } private static void CopyVerticalMetrics(TMP_FontAsset from, TMP_FontAsset to) { //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) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) FaceInfo faceInfo = from.faceInfo; FaceInfo faceInfo2 = to.faceInfo; ((FaceInfo)(ref faceInfo2)).scale = ((FaceInfo)(ref faceInfo)).scale; ((FaceInfo)(ref faceInfo2)).lineHeight = ((FaceInfo)(ref faceInfo)).lineHeight; ((FaceInfo)(ref faceInfo2)).ascentLine = ((FaceInfo)(ref faceInfo)).ascentLine; ((FaceInfo)(ref faceInfo2)).capLine = ((FaceInfo)(ref faceInfo)).capLine; ((FaceInfo)(ref faceInfo2)).meanLine = ((FaceInfo)(ref faceInfo)).meanLine; ((FaceInfo)(ref faceInfo2)).baseline = ((FaceInfo)(ref faceInfo)).baseline; ((FaceInfo)(ref faceInfo2)).descentLine = ((FaceInfo)(ref faceInfo)).descentLine; ((FaceInfo)(ref faceInfo2)).superscriptOffset = ((FaceInfo)(ref faceInfo)).superscriptOffset; ((FaceInfo)(ref faceInfo2)).superscriptSize = ((FaceInfo)(ref faceInfo)).superscriptSize; ((FaceInfo)(ref faceInfo2)).subscriptOffset = ((FaceInfo)(ref faceInfo)).subscriptOffset; ((FaceInfo)(ref faceInfo2)).subscriptSize = ((FaceInfo)(ref faceInfo)).subscriptSize; ((FaceInfo)(ref faceInfo2)).underlineOffset = ((FaceInfo)(ref faceInfo)).underlineOffset; ((FaceInfo)(ref faceInfo2)).underlineThickness = ((FaceInfo)(ref faceInfo)).underlineThickness; ((FaceInfo)(ref faceInfo2)).strikethroughOffset = ((FaceInfo)(ref faceInfo)).strikethroughOffset; ((FaceInfo)(ref faceInfo2)).strikethroughThickness = ((FaceInfo)(ref faceInfo)).strikethroughThickness; ((FaceInfo)(ref faceInfo2)).tabWidth = ((FaceInfo)(ref faceInfo)).tabWidth; to.faceInfo = faceInfo2; Plugin.Log.LogInfo((object)$"Metrics aligned to {((Object)from).name}: pointSize {((FaceInfo)(ref faceInfo)).pointSize}, lineHeight {((FaceInfo)(ref faceInfo)).lineHeight}, baseline {((FaceInfo)(ref faceInfo)).baseline}, ascent {((FaceInfo)(ref faceInfo)).ascentLine}, descent {((FaceInfo)(ref faceInfo)).descentLine}."); } private static TMP_FontAsset FindGameTekoAsset() { TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); foreach (TMP_FontAsset val in array) { if (((Object)val).name.Contains("Teko")) { return val; } } return null; } } }