diff --git a/ValheimLib/Language.cs b/ValheimLib/Language.cs
index 9aef212..0850e42 100644
--- a/ValheimLib/Language.cs
+++ b/ValheimLib/Language.cs
@@ -1,49 +1,161 @@
-using MonoMod.RuntimeDetour;
+using BepInEx;
+using MonoMod.RuntimeDetour;
using System;
using System.Collections.Generic;
+using System.IO;
using ValheimLib.Util.Reflection;
namespace ValheimLib
{
+ ///
+ /// Class for adding / replacing localization tokens
+ ///
public static class Language
{
+ ///
+ /// Your token must start with this character.
+ ///
public const char TokenFirstChar = '$';
- public static List AdditionalTokens = new List();
+ internal static Dictionary> AdditionalTokens =
+ new Dictionary>();
- public struct TokenValue
- {
- public string Token;
- public string Value;
- }
+ internal static Func>> DoQuoteLineSplit;
- public static void Init()
+ internal static void Init()
{
- var _ = new Hook(
+ _ = new Hook(
typeof(Localization).GetMethod(nameof(Localization.SetupLanguage), ReflectionHelper.AllBindingFlags),
typeof(Language).GetMethod(nameof(AddTokens), ReflectionHelper.AllBindingFlags));
+
+ var doQuoteLineSplitMethodInfo = typeof(Localization).GetMethod(nameof(Localization.DoQuoteLineSplit), ReflectionHelper.AllBindingFlags);
+ DoQuoteLineSplit = (Func>>)
+ Delegate.CreateDelegate(typeof(Func>>), null, doQuoteLineSplitMethodInfo);
+
+ AddLanguageFilesFromPluginFolder();
+ }
+
+ private static Dictionary GetLanguageDict(string language)
+ {
+ if (!AdditionalTokens.TryGetValue(language, out var languageDict))
+ {
+ languageDict = new Dictionary();
+ AdditionalTokens.Add(language, languageDict);
+ }
+
+ return languageDict;
+ }
+
+ private static void AddLanguageFilesFromPluginFolder()
+ {
+ var languagePaths = Directory.GetFiles(Paths.PluginPath, "*.language", SearchOption.AllDirectories);
+ foreach (var path in languagePaths)
+ {
+ AddPath(path);
+ }
}
- // Todo : for now the custom tokens are getting to any language
- public static void AddToken(string token, string value, bool forceReplace = false)
+ ///
+ /// Add a token and its value to the specified language (default to English)
+ ///
+ /// token / key
+ /// value that will be printed in the game
+ ///
+ /// replace the token if it already exists
+ public static void AddToken(string token, string value, string language = "English", bool forceReplace = false)
{
if (token[0] != TokenFirstChar)
{
- throw new Exception($"Token first char should be $ ! (token : {token})");
+ throw new Exception($"Token first char should be {TokenFirstChar} ! (token : {token})");
}
+ Dictionary languageDict;
+
if (!forceReplace)
{
- foreach (var pair in AdditionalTokens)
+ if (AdditionalTokens.TryGetValue(language, out languageDict))
{
- if (pair.Token == token)
+ foreach (var pair in languageDict)
{
- throw new Exception($"Token named {token} already exist !");
+ if (pair.Key == token)
+ {
+ throw new Exception($"Token named {token} already exist !");
+ }
}
}
}
- AdditionalTokens.Add(new TokenValue { Token = token.Substring(1), Value = value });
+ languageDict = GetLanguageDict(language);
+ languageDict.Add(token.Substring(1), value);
+ }
+
+ ///
+ /// Add a token and its value to the English language
+ ///
+ /// token / key
+ /// value that will be printed in the game
+ /// replace the token if it already exists
+ public static void AddToken(string token, string value, bool forceReplace = false) =>
+ AddToken(token, value, "French", forceReplace);
+
+ ///
+ /// Add a file via path
+ ///
+ /// absolute path to file
+ public static void AddPath(string path)
+ {
+ if (path == null)
+ {
+ throw new NullReferenceException($"param {nameof(path)} is null");
+ }
+
+ var fileContent = File.ReadAllText(path);
+ Add(fileContent);
+ Log.LogInfo($"Added language file {Path.GetFileName(path)}");
+ }
+
+ ///
+ /// Add a language file
+ ///
+ /// Entire file as string
+ public static void Add(string fileContent)
+ {
+ if (fileContent == null)
+ {
+ throw new NullReferenceException($"param {nameof(fileContent)} is null");
+ }
+
+ LoadLanguageFile(fileContent);
+ }
+
+ private static void LoadLanguageFile(string fileContent)
+ {
+ var stringReader = new StringReader(fileContent);
+ var languages = stringReader.ReadLine().Split(new []{ ',' });
+
+ foreach (List keyAndValues in DoQuoteLineSplit(stringReader))
+ {
+ if (keyAndValues.Count != 0)
+ {
+ var token = keyAndValues[0];
+ if (!token.StartsWith("//") && token.Length != 0)
+ {
+ for (var i = 0; i < languages.Length; i++)
+ {
+ var language = languages[i];
+
+ string tokenValue = keyAndValues[i];
+ if (string.IsNullOrEmpty(tokenValue) || tokenValue[0] == '\r')
+ {
+ tokenValue = keyAndValues[1];
+ }
+
+ var languageDict = GetLanguageDict(language);
+ languageDict.Add(token, tokenValue);
+ }
+ }
+ }
+ }
}
private static bool AddTokens(Func orig, Localization self, string language)
@@ -52,9 +164,12 @@ private static bool AddTokens(Func orig, Localizatio
if (res)
{
- foreach (var pair in AdditionalTokens)
+ if (AdditionalTokens.TryGetValue(language, out var tokens))
{
- self.AddWord(pair.Token, pair.Value);
+ foreach (var pair in tokens)
+ {
+ self.AddWord(pair.Key, pair.Value);
+ }
}
}