Localization mod for Gamecraft.
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

194 satır
7.9KB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Reflection;
  7. using TechbloxModdingAPI;
  8. using TechbloxModdingAPI.App;
  9. using TechbloxModdingAPI.Commands;
  10. using TechbloxModdingAPI.Utility;
  11. using HarmonyLib;
  12. using IllusionPlugin;
  13. using Newtonsoft.Json;
  14. using Newtonsoft.Json.Linq;
  15. using ServiceLayer;
  16. namespace Localization
  17. {
  18. public class LocalizationMod : IEnhancedPlugin
  19. {
  20. private readonly DirectoryInfo _pluginFolder = new DirectoryInfo(Path.Combine("Plugins", "Localization"));
  21. private Dictionary<string, string> _origStrings;
  22. private readonly string[] _embeddedLanguages = Assembly.GetExecutingAssembly().GetManifestResourceNames();
  23. public override void OnApplicationStart()
  24. {
  25. Main.Init();
  26. if (!_pluginFolder.Exists)
  27. _pluginFolder.Create();
  28. string settingsPath = Path.Combine(_pluginFolder.FullName, "settings.json");
  29. JObject settings;
  30. if (File.Exists(settingsPath))
  31. {
  32. try
  33. {
  34. using (var stream = new JsonTextReader(File.OpenText(settingsPath)))
  35. settings = JObject.Load(stream);
  36. string lang = (string) (settings["lang"] ?? (settings["lang"] = "en"));
  37. lang = lang.ToLower();
  38. if (lang != "en")
  39. LoadTranslation(lang);
  40. }
  41. catch (Exception e)
  42. {
  43. Logging.LogError(e);
  44. settings = new JObject();
  45. }
  46. }
  47. else
  48. settings = new JObject();
  49. CommandBuilder.Builder("SetLanguage", "Sets the game's language")
  50. .Action<string>(lang =>
  51. {
  52. lang = lang.ToLower();
  53. settings["lang"] = lang;
  54. using (var stream = new JsonTextWriter(new StreamWriter(File.OpenWrite(settingsPath))))
  55. settings.WriteTo(stream);
  56. LoadTranslation(lang);
  57. }).Build();
  58. CommandBuilder.Builder("ListLanguages", "Lists available languages")
  59. .Action(() =>
  60. {
  61. Logging.CommandLog(new[] {"en"}.Concat(_pluginFolder.EnumerateFiles()
  62. .Where(file => file.Extension == ".json"
  63. && (file.Name.Length < 8 || file.Name.Contains("-")))
  64. .Select(file => file.Name.Replace(file.Extension, "")))
  65. .Concat(_embeddedLanguages)
  66. .Select(lang => lang.Replace("Localization.", "").Replace(".json", ""))
  67. .Distinct().Aggregate((a, b) => a + ", " + b));
  68. }).Build();
  69. CommandBuilder.Builder("DumpLangStrings", "Dumps the current strings. Set language to en first.")
  70. .Action(() =>
  71. {
  72. File.WriteAllText(Path.Combine(_pluginFolder.FullName, "dumped.json"),
  73. JsonConvert.SerializeObject(_origStrings, Formatting.Indented));
  74. }).Build();
  75. if (!settings.ContainsKey("autoload"))
  76. {
  77. settings["autoload"] = true;
  78. using (var stream = new JsonTextWriter(new StreamWriter(File.OpenWrite(settingsPath))))
  79. settings.WriteTo(stream);
  80. }
  81. if ((bool) settings["autoload"])
  82. Client.EnterMenu += TryLoadSystemLanguageMenuEnterEvent;
  83. }
  84. public override void OnApplicationQuit()
  85. {
  86. Main.Shutdown();
  87. }
  88. private void LoadTranslation(string lang)
  89. {
  90. Logging.CommandLog("Loading translation for " + lang + "...");
  91. LoadOriginalStrings();
  92. string langPath = Path.Combine(_pluginFolder.FullName, lang + ".json");
  93. if (!File.Exists(langPath))
  94. {
  95. if (_embeddedLanguages.Contains("Localization." + lang + ".json"))
  96. langPath = null;
  97. else
  98. {
  99. if (lang == "en")
  100. {
  101. AccessTools.Method(typeof(LocalizationService), "Init").Invoke(null, new object[0]);
  102. _origStrings = null; //Reset as the object changed
  103. LoadOriginalStrings();
  104. Logging.CommandLog("Strings reset to default. (" + _origStrings.Count + " strings in total)");
  105. return;
  106. }
  107. Logging.CommandLogError("Could not find json file!");
  108. return;
  109. }
  110. }
  111. string jsonText = langPath != null ? File.ReadAllText(langPath) : null;
  112. if (jsonText == null)
  113. {
  114. var stream = Assembly.GetExecutingAssembly()
  115. .GetManifestResourceStream("Localization." + lang + ".json");
  116. if (stream != null)
  117. using (var st = new StreamReader(stream))
  118. jsonText = st.ReadToEnd();
  119. else
  120. {
  121. Logging.CommandLogError("Failed to load embedded translation for " + lang);
  122. return;
  123. }
  124. }
  125. var strings = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonText);
  126. foreach (var kv in strings)
  127. {
  128. if (!_origStrings.Remove(kv.Key))
  129. Logging.CommandLogWarning(kv.Key + " wasn't in the original file.");
  130. _origStrings.Add(kv.Key, kv.Value);
  131. }
  132. Logging.CommandLog("Updated " + strings.Count + " strings (" + _origStrings.Count + " strings in total)");
  133. }
  134. private void LoadOriginalStrings()
  135. {
  136. if (_origStrings != null) return;
  137. _origStrings =
  138. (Dictionary<string, string>) AccessTools.Field(typeof(LocalizationService), "LocalizedStrings")
  139. .GetValue(null);
  140. }
  141. private void TryLoadSystemLanguageMenuEnterEvent(object sender, MenuEventArgs args)
  142. {
  143. TryLoadSystemLanguage();
  144. Client.EnterMenu -= TryLoadSystemLanguageMenuEnterEvent;
  145. }
  146. private void TryLoadSystemLanguage()
  147. {
  148. string lang = CultureInfo.CurrentUICulture.EnglishName.Split(' ')[0].ToLower();
  149. string first2 = lang.Substring(0, 2);
  150. // try some possibly valid language codes
  151. if (File.Exists(Path.Combine(_pluginFolder.FullName, lang + ".json")))
  152. {
  153. Logging.MetaLog($"Automatically detected system UI language {lang}, loading translations...");
  154. LoadTranslation(lang);
  155. }
  156. else if (File.Exists(Path.Combine(_pluginFolder.FullName, first2 + ".json")))
  157. {
  158. lang = first2;
  159. Logging.MetaLog($"Automatically detected system UI language {lang}, loading translations...");
  160. LoadTranslation(lang);
  161. }
  162. else if (File.Exists(Path.Combine(_pluginFolder.FullName, first2 + "-" + first2 + ".json")))
  163. {
  164. // a lot of standard languages codes are like fr-fr (French from France), but this won't work for English (nor fr-CA French from Canada)
  165. lang = first2 + "-" + first2;
  166. Logging.MetaLog($"Automatically detected system UI language {lang}, loading translations...");
  167. LoadTranslation(lang);
  168. }
  169. else
  170. {
  171. Logging.MetaLog($"Translations for system UI language {lang} are not available, skipping...");
  172. }
  173. }
  174. public override string Name { get; } = "LocalizationMod";
  175. public override string Version { get; } = "1.0.0";
  176. }
  177. }