using BepInEx; using BepInEx.Common; using Harmony; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; namespace DynamicTranslationLoader { public class DynamicTranslator : BaseUnityPlugin { private static Dictionary translations = new Dictionary(); private static List untranslated = new List(); public override string Name => "Dynamic Translator"; public DynamicTranslator() { string[] translation = File.ReadAllLines(Utility.CombinePaths(Utility.PluginsDirectory, "translation", "translation.txt")); for (int i = 0; i < translation.Length; i++) { string line = translation[i]; if (!line.Contains('=')) continue; string[] split = line.Split('='); translations[split[0]] = split[1]; } var harmony = HarmonyInstance.Create("com.bepis.bepinex.dynamictranslationloader"); MethodInfo original = AccessTools.Property(typeof(TMP_Text), "text").GetSetMethod(); HarmonyMethod prefix = new HarmonyMethod(typeof(DynamicTranslator).GetMethod("LabelTextHook")); harmony.Patch(original, prefix, null); } protected override void LevelFinishedLoading(Scene scene, LoadSceneMode mode) { TranslateAll(); } void OnUpdate() { if (UnityEngine.Event.current.Equals(Event.KeyboardEvent("f10"))) { Dump(); Console.WriteLine($"Text dumped to \"{Path.GetFullPath("dumped-tl.txt")}\""); } } void TranslateAll() { foreach (TextMeshProUGUI gameObject in GameObject.FindObjectsOfType()) { //gameObject.text = "Harsh is shit"; if (translations.ContainsKey(gameObject.text)) gameObject.text = translations[gameObject.text]; else if (!untranslated.Contains(gameObject.text)) untranslated.Add(gameObject.text); } } void Dump() { string output = ""; foreach (var kv in translations) output += $"{kv.Key.Trim()}={kv.Value.Trim()}\r\n"; foreach (var text in untranslated) if (!text.IsNullOrWhiteSpace() && !text.Contains("Reset") && !Regex.Replace(text, @"[\d-]", string.Empty).IsNullOrWhiteSpace() && !translations.ContainsValue(text.Trim())) output += $"{text.Trim()}=\r\n"; File.WriteAllText("dumped-tl.txt", output); } static string Translate(string input) { if (translations.ContainsKey(input)) return translations[input]; if (!untranslated.Contains(input)) untranslated.Add(input); return input; } public static void LabelTextHook(ref string value) { value = Translate(value); } } }