diff --git a/Core/TimberApi/LocalizationSystem/LocalizationFetcher.cs b/Core/TimberApi/LocalizationSystem/LocalizationFetcher.cs
index 6a54299a..7f6e94b2 100644
--- a/Core/TimberApi/LocalizationSystem/LocalizationFetcher.cs
+++ b/Core/TimberApi/LocalizationSystem/LocalizationFetcher.cs
@@ -6,6 +6,7 @@
using LINQtoCSV;
using TimberApi.DependencyContainerSystem;
using TimberApi.ModSystem;
+using Timberborn.Common;
using Timberborn.Localization;
using UnityEngine;
@@ -20,98 +21,88 @@ internal static class LocalizationFetcher
///
public static Dictionary GetLocalization(string localizationKey)
{
- var localizedRecords = GetLocalizationRecordsFromFiles(localizationKey, GetLocalizationFilePathsFromDependencies(localizationKey))
- .ToDictionary(record => record.Id, record => TextColors.ColorizeText(record.Text));
-
- foreach (LocalizationRecord defaultRecord in GetDefaultLocalization())
+ if (localizationKey == LocalizationCodes.Default)
{
- var id = defaultRecord.Id;
- if (!localizedRecords.TryGetValue(id, out string text) || string.IsNullOrEmpty(text))
- {
- localizedRecords[id] = TextColors.ColorizeText(defaultRecord.Text);
- }
+ return GetLocalizationRecordsFromFiles(localizationKey, GetLocalizationFilePathsFromDependencies(localizationKey))
+ .ToDictionary(record => record.Id, record => TextColors.ColorizeText(record.Text))!;
}
- return localizedRecords;
+ var userLocalizationRecords = GetLocalizationRecordsFromFiles(localizationKey, GetLocalizationFilePathsFromDependencies(localizationKey));
+ var defaultLocalizationRecords = GetLocalizationRecordsFromFiles(LocalizationCodes.Default, GetLocalizationFilePathsFromDependencies(LocalizationCodes.Default));
+
+ return defaultLocalizationRecords
+ .ToDictionary(
+ defaultLocalizationRecord => defaultLocalizationRecord.Id,
+ defaultLocalizationRecord => TextColors.ColorizeText(userLocalizationRecords.FirstOrDefault(userLocalizationRecord => userLocalizationRecord.Id == defaultLocalizationRecord.Id)?.Text ?? defaultLocalizationRecord.Text)
+ )!;
}
///
/// Parses text files into LocalizationRecords
///
- ///
+ ///
///
///
- private static IEnumerable GetLocalizationRecordsFromFiles(string localization, IEnumerable filePaths)
+ private static IEnumerable GetLocalizationRecordsFromFiles(string localizationKey, IEnumerable filePaths)
{
- List records = new();
- foreach (LocalizationFile localizationFile in filePaths)
- {
- records.AddRange(TryToReadRecords(localization, localizationFile));
- }
-
- return records;
+ return filePaths
+ .SelectMany(localizationFile => TryToReadRecords(localizationKey, localizationFile))
+ .GroupBy(record => record.Id)
+ .Select(recordsGroupedById => recordsGroupedById.Last())
+ .ToList();
}
///
/// Timberborn method Timberborn.Localization.LocalizationRepository.TryToReadRecords
///
- ///
+ ///
///
///
///
- private static IEnumerable TryToReadRecords(string localization, LocalizationFile localizationFile)
+ private static IEnumerable TryToReadRecords(string localizationKey, LocalizationFile localizationFile)
{
try
{
- var localizationRecords = new CsvContext().Read(localizationFile.FilePath);
-
- ValidateLocalizationRecords(localizationRecords, localizationFile.Mod);
-
- return new CsvContext().Read(localizationFile.FilePath);
+ return CleanLocalizationRecords(new CsvContext().Read(localizationFile.FilePath), localizationFile.Mod);
}
- catch (Exception ex)
+ catch (Exception exception)
{
- var message = "Unable to parse file for " + localization + ".";
- if (ex is AggregatedException aggregatedException)
+ var message = "Unable to parse file for " + localizationKey + ".";
+ if (exception is AggregatedException aggregatedException)
{
message = message + " First error: " + aggregatedException.m_InnerExceptionsList[0].Message;
}
- if (localization == LocalizationCodes.Default)
+ if (localizationKey == LocalizationCodes.Default)
{
- throw new InvalidDataException(message, ex);
+ throw new InvalidDataException(message, exception);
}
TimberApi.ConsoleWriter.Log(message, LogType.Error);
+
return new List();
}
}
- private static void ValidateLocalizationRecords(IEnumerable localizationRecords, IMod mod)
+ private static IEnumerable CleanLocalizationRecords(IEnumerable localizationRecords, IMod mod)
{
- var hasValidationErrors = false;
+ var records = localizationRecords.ToList();
+
+ var errors = records
+ .Where(record => record.Text is null)
+ .ToList();
- foreach (var record in localizationRecords)
+ if (errors.IsEmpty())
{
- if(record.Text is null)
- {
- hasValidationErrors = true;
- TimberApi.ConsoleWriter.LogAs(mod.Name, $"Localization Id does not have any text: {record.Id}", LogType.Error);
- }
+ return records.Where(record => record.Id is not null);
}
- if(hasValidationErrors)
+ foreach (var error in errors)
{
- throw new Exception($"Validating localization files for {mod.Name} failed.");
+ TimberApi.ConsoleWriter.LogAs(mod.Name, $"Localization Id does not have any text: {error.Id}", LogType.Error);
}
- }
- ///
- /// Returns the default localization
- ///
- private static IEnumerable GetDefaultLocalization()
- {
- return GetLocalizationRecordsFromFiles(LocalizationCodes.Default, GetLocalizationFilePathsFromDependencies(LocalizationCodes.Default));
+ throw new Exception($"Validating localization files for {mod.Name} failed.");
}
///
@@ -121,53 +112,28 @@ private static IEnumerable GetDefaultLocalization()
///
private static IEnumerable GetLocalizationFilePathsFromDependencies(string localizationKey)
{
- List localizationFilePaths = new();
- foreach (IMod mod in DependencyContainer.GetInstance().All())
- {
- var pluginLocalizationPath = Path.Combine(mod.DirectoryPath, mod.LanguagePath);
-
- (var hasLocalization, var localizationName) = LocalizationNameOrDefault(pluginLocalizationPath, localizationKey);
-
- if (!hasLocalization)
- {
- continue;
- }
-
- localizationFilePaths.Add(new LocalizationFile(mod, Path.Combine(pluginLocalizationPath, localizationName)));
- }
-
- return localizationFilePaths;
+ return (
+ from mod in DependencyContainer.GetInstance().All()
+ let pluginLocalizationPath = Path.Combine(mod.DirectoryPath, mod.LanguagePath)
+ let localizationFile = GetLocalizationFile(pluginLocalizationPath, localizationKey) ?? GetLocalizationFile(pluginLocalizationPath, LocalizationCodes.Default)
+ where localizationFile is not null
+ select new LocalizationFile(mod, Path.Combine(pluginLocalizationPath, localizationFile))
+ ).ToList();
}
///
- /// Check if localization file exists, return default if not
- /// Returns false if default and localization file doesn't exists
+ /// Get the localization file from the plugin localization path or return null
///
///
- ///
- private static (bool, string) LocalizationNameOrDefault(string pluginLocalizationPath, string localizationName)
+ ///
+ private static string? GetLocalizationFile(string pluginLocalizationPath, string localizationKey)
{
- if (string.IsNullOrEmpty(localizationName))
- {
- return (false, "");
- }
-
- if (!Directory.Exists(pluginLocalizationPath))
- {
- return (false, "");
- }
-
- if (File.Exists(Path.Combine(pluginLocalizationPath, localizationName + ".txt")))
- {
- return (true, localizationName + ".txt");
- }
-
- if (File.Exists(Path.Combine(pluginLocalizationPath, LocalizationCodes.Default + ".txt")))
+ if (string.IsNullOrEmpty(localizationKey) || !Directory.Exists(pluginLocalizationPath))
{
- return (true, LocalizationCodes.Default + ".txt");
+ return null;
}
- return (false, "");
+ return File.Exists(Path.Combine(pluginLocalizationPath, localizationKey + ".txt")) ? localizationKey + ".txt" : null;
}
}
-}
+}
\ No newline at end of file
diff --git a/Core/TimberApi/LocalizationSystem/LocalizationPatcher.cs b/Core/TimberApi/LocalizationSystem/LocalizationPatcher.cs
index 4a4ec2cc..6c4b403b 100644
--- a/Core/TimberApi/LocalizationSystem/LocalizationPatcher.cs
+++ b/Core/TimberApi/LocalizationSystem/LocalizationPatcher.cs
@@ -1,10 +1,7 @@
-using System;
using System.Collections.Generic;
using HarmonyLib;
using TimberApi.HarmonyPatcherSystem;
-using Timberborn.Common;
using Timberborn.Localization;
-using UnityEngine;
namespace TimberApi.LocalizationSystem
{
@@ -23,15 +20,12 @@ public override void Apply(Harmony harmony)
public static void GetLocalizationPatch(string localizationKey, ref IDictionary __result)
{
IDictionary localization = LocalizationFetcher.GetLocalization(localizationKey);
- try
- {
- __result.AddRange(localization);
- TimberApi.ConsoleWriter.Log($"Loaded {localization.Count} custom labels");
- }
- catch (Exception e)
+
+ TimberApi.ConsoleWriter.Log($"Loaded {localization.Count} custom labels");
+
+ foreach (var (key, value) in localization)
{
- TimberApi.ConsoleWriter.Log(e.ToString(), LogType.Error);
- throw;
+ __result[key] = value;
}
}
}
diff --git a/Core/TimberApi/LocalizationSystem/LocalizationRecord.cs b/Core/TimberApi/LocalizationSystem/LocalizationRecord.cs
index 4b1cc20a..e94490fb 100644
--- a/Core/TimberApi/LocalizationSystem/LocalizationRecord.cs
+++ b/Core/TimberApi/LocalizationSystem/LocalizationRecord.cs
@@ -8,13 +8,13 @@ namespace TimberApi.LocalizationSystem
internal class LocalizationRecord
{
[CsvColumn(Name = "ID")]
- public string Id { get; set; } = null!;
+ public string? Id { get; set; } = null;
[CsvColumn(Name = "Text")]
- public string Text { get; set; } = null!;
+ public string? Text { get; set; } = null;
[CsvColumn(Name = "Comment")]
- public string Comment { get; set; } = null!;
+ public string? Comment { get; set; } = null;
public bool IsWip { get; set; }
}