From 291bf3a3c83446c112cfb7118ec94d712967ec11 Mon Sep 17 00:00:00 2001 From: Velken <8467292+Velken@users.noreply.github.com> Date: Thu, 19 Mar 2026 17:32:39 -0300 Subject: [PATCH 1/2] add /Uploaded as path for .ftl --- .../Localization/LocalizationManager.cs | 19 +++++++++++++++++++ .../Upload/SharedNetworkResourceManager.cs | 14 ++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/Robust.Shared/Localization/LocalizationManager.cs b/Robust.Shared/Localization/LocalizationManager.cs index cc719c6202e..1c4e0fd10d2 100644 --- a/Robust.Shared/Localization/LocalizationManager.cs +++ b/Robust.Shared/Localization/LocalizationManager.cs @@ -27,6 +27,7 @@ namespace Robust.Shared.Localization internal abstract partial class LocalizationManager : ILocalizationManagerInternal { protected static readonly ResPath LocaleDirPath = new("/Locale"); + protected static readonly ResPath UploadedDirPath = new("/Uploaded"); [Dependency] private readonly IConfigurationManager _configuration = default!; [Dependency] private readonly IResourceManager _res = default!; @@ -403,6 +404,20 @@ public List GetFoundCultures() result.Add(CultureInfo.GetCultureInfo(cultureName, predefinedOnly: false)); } + var uploadedFiles = _res.ContentFindFiles(UploadedDirPath) + .Where(c => c.Filename.EndsWith(".ftl", StringComparison.InvariantCultureIgnoreCase)); + + foreach (var file in uploadedFiles) + { + var cultureName = Path.GetFileNameWithoutExtension(file.Filename); + if (CultureInfo.GetCultures(CultureTypes.AllCultures).Any(c => c.Name.Equals(cultureName, StringComparison.InvariantCultureIgnoreCase))) + { + var culture = CultureInfo.GetCultureInfo(cultureName, predefinedOnly: false); + if (!result.Contains(culture)) + result.Add(culture); + } + } + return result; } @@ -485,10 +500,14 @@ private void _initData(IResourceManager resourceManager, CultureInfo culture, Fl { // Load data from .ftl files. // Data is loaded from /Locale//* + // and from /Uploaded/**/* where filename is .ftl var root = LocaleDirPath / culture.Name; + var cultureFtl = culture.Name + ".ftl"; var files = resourceManager.ContentFindFiles(root) + .Concat(resourceManager.ContentFindFiles(UploadedDirPath) + .Where(c => c.Filename.Equals(cultureFtl, StringComparison.InvariantCultureIgnoreCase))) .Where(c => c.Filename.EndsWith(".ftl", StringComparison.InvariantCultureIgnoreCase)) .ToArray(); diff --git a/Robust.Shared/Upload/SharedNetworkResourceManager.cs b/Robust.Shared/Upload/SharedNetworkResourceManager.cs index 84fac8f166d..0749c3dd814 100644 --- a/Robust.Shared/Upload/SharedNetworkResourceManager.cs +++ b/Robust.Shared/Upload/SharedNetworkResourceManager.cs @@ -7,6 +7,7 @@ using Robust.Shared.Asynchronous; using Robust.Shared.ContentPack; using Robust.Shared.IoC; +using Robust.Shared.Localization; using Robust.Shared.Log; using Robust.Shared.Network; using Robust.Shared.Network.Transfer; @@ -38,6 +39,7 @@ public abstract class SharedNetworkResourceManager : IDisposable, IPostInjectIni [Dependency] protected readonly IResourceManager ResourceManager = default!; [Dependency] protected readonly ITransferManager TransferManager = default!; [Dependency] protected readonly ILogManager LogManager = default!; + [Dependency] protected readonly ILocalizationManager LocalizationManager = default!; [Dependency] private readonly ITaskManager _taskManager = default!; protected ISawmill Sawmill = default!; @@ -112,9 +114,13 @@ protected virtual void ValidateUpload(uint size) protected async Task> IngestFileStream(Stream stream) { var list = new List<(ResPath Relative, byte[] Data)>(); + var anyLoc = false; await foreach (var (relative, data) in ReadTransferStream(stream).ConfigureAwait(false)) { + if (relative.Extension == "ftl") + anyLoc = true; + Sawmill.Verbose($"Storing uploaded file: {relative} ({ByteHelpers.FormatBytes(data.Length)})"); _taskManager.RunOnMainThread(() => { @@ -123,6 +129,14 @@ protected virtual void ValidateUpload(uint size) list.Add((relative, data)); } + if (anyLoc) + { + _taskManager.RunOnMainThread(() => + { + LocalizationManager.ReloadLocalizations(); + }); + } + return list; } From 05f482723e9ce0af89d33509548a8ad549906776 Mon Sep 17 00:00:00 2001 From: Velken <8467292+Velken@users.noreply.github.com> Date: Tue, 24 Mar 2026 20:53:03 -0300 Subject: [PATCH 2/2] my gut tells me this looks wrong, but it works, so, idk --- Robust.Shared/Localization/LocalizationManager.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Robust.Shared/Localization/LocalizationManager.cs b/Robust.Shared/Localization/LocalizationManager.cs index 1c4e0fd10d2..a169d2dd384 100644 --- a/Robust.Shared/Localization/LocalizationManager.cs +++ b/Robust.Shared/Localization/LocalizationManager.cs @@ -500,14 +500,13 @@ private void _initData(IResourceManager resourceManager, CultureInfo culture, Fl { // Load data from .ftl files. // Data is loaded from /Locale//* - // and from /Uploaded/**/* where filename is .ftl + // and from /Uploaded/**/Locale//* var root = LocaleDirPath / culture.Name; - var cultureFtl = culture.Name + ".ftl"; var files = resourceManager.ContentFindFiles(root) .Concat(resourceManager.ContentFindFiles(UploadedDirPath) - .Where(c => c.Filename.Equals(cultureFtl, StringComparison.InvariantCultureIgnoreCase))) + .Where(c => c.CanonPath.Contains($"/Locale/{culture.Name}/", StringComparison.InvariantCultureIgnoreCase))) .Where(c => c.Filename.EndsWith(".ftl", StringComparison.InvariantCultureIgnoreCase)) .ToArray();