Rename Fluent-related code to be more precise.
This commit is contained in:
@@ -25,40 +25,40 @@ using OpenRA.Traits;
|
||||
namespace OpenRA
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public sealed class TranslationReferenceAttribute : Attribute
|
||||
public sealed class FluentReferenceAttribute : Attribute
|
||||
{
|
||||
public readonly bool Optional;
|
||||
public readonly string[] RequiredVariableNames;
|
||||
public readonly LintDictionaryReference DictionaryReference;
|
||||
|
||||
public TranslationReferenceAttribute() { }
|
||||
public FluentReferenceAttribute() { }
|
||||
|
||||
public TranslationReferenceAttribute(params string[] requiredVariableNames)
|
||||
public FluentReferenceAttribute(params string[] requiredVariableNames)
|
||||
{
|
||||
RequiredVariableNames = requiredVariableNames;
|
||||
}
|
||||
|
||||
public TranslationReferenceAttribute(LintDictionaryReference dictionaryReference = LintDictionaryReference.None)
|
||||
public FluentReferenceAttribute(LintDictionaryReference dictionaryReference = LintDictionaryReference.None)
|
||||
{
|
||||
DictionaryReference = dictionaryReference;
|
||||
}
|
||||
|
||||
public TranslationReferenceAttribute(bool optional)
|
||||
public FluentReferenceAttribute(bool optional)
|
||||
{
|
||||
Optional = optional;
|
||||
}
|
||||
}
|
||||
|
||||
public class Translation
|
||||
public class FluentBundle
|
||||
{
|
||||
readonly FluentBundle bundle;
|
||||
readonly Linguini.Bundle.FluentBundle bundle;
|
||||
|
||||
public Translation(string language, string[] translations, IReadOnlyFileSystem fileSystem)
|
||||
: this(language, translations, fileSystem, error => Log.Write("debug", error.Message)) { }
|
||||
public FluentBundle(string language, string[] paths, IReadOnlyFileSystem fileSystem)
|
||||
: this(language, paths, fileSystem, error => Log.Write("debug", error.Message)) { }
|
||||
|
||||
public Translation(string language, string[] translations, IReadOnlyFileSystem fileSystem, Action<ParseError> onError)
|
||||
public FluentBundle(string language, string[] paths, IReadOnlyFileSystem fileSystem, Action<ParseError> onError)
|
||||
{
|
||||
if (translations == null || translations.Length == 0)
|
||||
if (paths == null || paths.Length == 0)
|
||||
return;
|
||||
|
||||
bundle = LinguiniBuilder.Builder()
|
||||
@@ -68,10 +68,10 @@ namespace OpenRA
|
||||
.UseConcurrent()
|
||||
.UncheckedBuild();
|
||||
|
||||
ParseTranslations(language, translations, fileSystem, onError);
|
||||
Load(language, paths, fileSystem, onError);
|
||||
}
|
||||
|
||||
public Translation(string language, string text, Action<ParseError> onError)
|
||||
public FluentBundle(string language, string text, Action<ParseError> onError)
|
||||
{
|
||||
var parser = new LinguiniParser(text);
|
||||
var resource = parser.Parse();
|
||||
@@ -88,16 +88,16 @@ namespace OpenRA
|
||||
bundle.AddResourceOverriding(resource);
|
||||
}
|
||||
|
||||
void ParseTranslations(string language, string[] translations, IReadOnlyFileSystem fileSystem, Action<ParseError> onError)
|
||||
void Load(string language, string[] paths, IReadOnlyFileSystem fileSystem, Action<ParseError> onError)
|
||||
{
|
||||
// Always load english strings to provide a fallback for missing translations.
|
||||
// It is important to load the english files first so the chosen language's files can override them.
|
||||
var paths = translations.Where(t => t.EndsWith("en.ftl", StringComparison.Ordinal)).ToList();
|
||||
foreach (var t in translations)
|
||||
var resolvedPaths = paths.Where(t => t.EndsWith("en.ftl", StringComparison.Ordinal)).ToList();
|
||||
foreach (var t in paths)
|
||||
if (t.EndsWith($"{language}.ftl", StringComparison.Ordinal))
|
||||
paths.Add(t);
|
||||
resolvedPaths.Add(t);
|
||||
|
||||
foreach (var path in paths.Distinct())
|
||||
foreach (var path in resolvedPaths.Distinct())
|
||||
{
|
||||
var stream = fileSystem.Open(path);
|
||||
using (var reader = new StreamReader(stream))
|
||||
@@ -140,13 +140,13 @@ namespace OpenRA
|
||||
|
||||
var result = bundle.TryGetAttrMessage(key, fluentArguments, out var errors, out value);
|
||||
foreach (var error in errors)
|
||||
Log.Write("debug", $"Translation of {key}: {error}");
|
||||
Log.Write("debug", $"FluentBundle of {key}: {error}");
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Log.Write("debug", $"Failed translation: {key}");
|
||||
Log.Write("debug", $"FluentBundle of {key}: threw exception");
|
||||
|
||||
value = null;
|
||||
return false;
|
||||
@@ -13,7 +13,7 @@ using Linguini.Shared.Types.Bundle;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public static class TranslationExts
|
||||
public static class FluentExts
|
||||
{
|
||||
public static IFluentType ToFluentType(this object value)
|
||||
{
|
||||
@@ -14,20 +14,20 @@ using OpenRA.FileSystem;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
public static class TranslationProvider
|
||||
public static class FluentProvider
|
||||
{
|
||||
// Ensure thread-safety.
|
||||
static readonly object SyncObject = new();
|
||||
static Translation modTranslation;
|
||||
static Translation mapTranslation;
|
||||
static FluentBundle modFluentBundle;
|
||||
static FluentBundle mapFluentBundle;
|
||||
|
||||
public static void Initialize(ModData modData, IReadOnlyFileSystem fileSystem)
|
||||
{
|
||||
lock (SyncObject)
|
||||
{
|
||||
modTranslation = new Translation(Game.Settings.Player.Language, modData.Manifest.Translations, fileSystem);
|
||||
mapTranslation = fileSystem is Map map && map.TranslationDefinitions != null
|
||||
? new Translation(Game.Settings.Player.Language, FieldLoader.GetValue<string[]>("value", map.TranslationDefinitions.Value), fileSystem)
|
||||
modFluentBundle = new FluentBundle(Game.Settings.Player.Language, modData.Manifest.Translations, fileSystem);
|
||||
mapFluentBundle = fileSystem is Map map && map.TranslationDefinitions != null
|
||||
? new FluentBundle(Game.Settings.Player.Language, FieldLoader.GetValue<string[]>("value", map.TranslationDefinitions.Value), fileSystem)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -36,13 +36,13 @@ namespace OpenRA
|
||||
{
|
||||
lock (SyncObject)
|
||||
{
|
||||
// By prioritizing mod-level translations we prevent maps from overwriting translation keys. We do not want to
|
||||
// By prioritizing mod-level fluent bundles we prevent maps from overwriting string keys. We do not want to
|
||||
// allow maps to change the UI nor any other strings not exposed to the map.
|
||||
if (modTranslation.TryGetString(key, out var message, args))
|
||||
if (modFluentBundle.TryGetString(key, out var message, args))
|
||||
return message;
|
||||
|
||||
if (mapTranslation != null)
|
||||
return mapTranslation.GetString(key, args);
|
||||
if (mapFluentBundle != null)
|
||||
return mapFluentBundle.GetString(key, args);
|
||||
|
||||
return key;
|
||||
}
|
||||
@@ -52,12 +52,12 @@ namespace OpenRA
|
||||
{
|
||||
lock (SyncObject)
|
||||
{
|
||||
// By prioritizing mod-level translations we prevent maps from overwriting translation keys. We do not want to
|
||||
// By prioritizing mod-level bundle we prevent maps from overwriting string keys. We do not want to
|
||||
// allow maps to change the UI nor any other strings not exposed to the map.
|
||||
if (modTranslation.TryGetString(key, out message, args))
|
||||
if (modFluentBundle.TryGetString(key, out message, args))
|
||||
return true;
|
||||
|
||||
if (mapTranslation != null && mapTranslation.TryGetString(key, out message, args))
|
||||
if (mapFluentBundle != null && mapFluentBundle.TryGetString(key, out message, args))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -69,7 +69,7 @@ namespace OpenRA
|
||||
{
|
||||
lock (SyncObject)
|
||||
{
|
||||
return modTranslation.TryGetString(key, out message, args);
|
||||
return modFluentBundle.TryGetString(key, out message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA
|
||||
{
|
||||
public static class Game
|
||||
{
|
||||
[TranslationReference("filename")]
|
||||
[FluentReference("filename")]
|
||||
const string SavedScreenshot = "notification-saved-screenshot";
|
||||
|
||||
public const int TimestepJankThreshold = 250; // Don't catch up for delays larger than 250ms
|
||||
@@ -595,7 +595,7 @@ namespace OpenRA
|
||||
Log.Write("debug", "Taking screenshot " + path);
|
||||
|
||||
Renderer.SaveScreenshot(path);
|
||||
TextNotificationsManager.Debug(TranslationProvider.GetString(SavedScreenshot, Translation.Arguments("filename", filename)));
|
||||
TextNotificationsManager.Debug(FluentProvider.GetString(SavedScreenshot, FluentBundle.Arguments("filename", filename)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenRA
|
||||
{
|
||||
public class GameInformation
|
||||
{
|
||||
[TranslationReference("name", "number")]
|
||||
[FluentReference("name", "number")]
|
||||
const string EnumeratedBotName = "enumerated-bot-name";
|
||||
|
||||
public string Mod;
|
||||
@@ -152,9 +152,9 @@ namespace OpenRA
|
||||
if (player.IsBot)
|
||||
{
|
||||
var number = Players.Where(p => p.BotType == player.BotType).ToList().IndexOf(player) + 1;
|
||||
return TranslationProvider.GetString(EnumeratedBotName,
|
||||
Translation.Arguments(
|
||||
"name", TranslationProvider.GetString(player.Name),
|
||||
return FluentProvider.GetString(EnumeratedBotName,
|
||||
FluentBundle.Arguments(
|
||||
"name", FluentProvider.GetString(player.Name),
|
||||
"number", number));
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace OpenRA
|
||||
{
|
||||
public class GameSpeed
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[FieldLoader.Require]
|
||||
public readonly string Name;
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace OpenRA
|
||||
public MiniYaml SequenceDefinitions;
|
||||
public MiniYaml ModelSequenceDefinitions;
|
||||
|
||||
public Translation Translation { get; private set; }
|
||||
public FluentBundle FluentBundle { get; private set; }
|
||||
public ActorInfo WorldActorInfo { get; private set; }
|
||||
public ActorInfo PlayerActorInfo { get; private set; }
|
||||
|
||||
@@ -122,8 +122,8 @@ namespace OpenRA
|
||||
SequenceDefinitions = LoadRuleSection(yaml, "Sequences");
|
||||
ModelSequenceDefinitions = LoadRuleSection(yaml, "ModelSequences");
|
||||
|
||||
Translation = yaml.TryGetValue("Translations", out var node) && node != null
|
||||
? new Translation(Game.Settings.Player.Language, FieldLoader.GetValue<string[]>("value", node.Value), fileSystem)
|
||||
FluentBundle = yaml.TryGetValue("Translations", out var node) && node != null
|
||||
? new FluentBundle(Game.Settings.Player.Language, FieldLoader.GetValue<string[]>("value", node.Value), fileSystem)
|
||||
: null;
|
||||
|
||||
try
|
||||
@@ -224,16 +224,16 @@ namespace OpenRA
|
||||
public int DownloadPercentage { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Functionality mirrors <see cref="TranslationProvider.GetString"/>, except instead of using
|
||||
/// loaded <see cref="Map"/>'s translations as backup, we use this <see cref="MapPreview"/>'s.
|
||||
/// Functionality mirrors <see cref="FluentProvider.GetString"/>, except instead of using
|
||||
/// loaded <see cref="Map"/>'s fluent bundle as backup, we use this <see cref="MapPreview"/>'s.
|
||||
/// </summary>
|
||||
public string GetLocalisedString(string key, IDictionary<string, object> args = null)
|
||||
{
|
||||
// PERF: instead of loading mod level Translation per each MapPreview, reuse the already loaded one in TranslationProvider.
|
||||
if (TranslationProvider.TryGetModString(key, out var message, args))
|
||||
// PERF: instead of loading mod level strings per each MapPreview, reuse the already loaded one in FluentProvider.
|
||||
if (FluentProvider.TryGetModString(key, out var message, args))
|
||||
return message;
|
||||
|
||||
return innerData.Translation?.GetString(key, args) ?? key;
|
||||
return innerData.FluentBundle?.GetString(key, args) ?? key;
|
||||
}
|
||||
|
||||
Sprite minimap;
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace OpenRA
|
||||
// horribly when you use ModData in unexpected ways.
|
||||
ChromeMetrics.Initialize(this);
|
||||
ChromeProvider.Initialize(this);
|
||||
TranslationProvider.Initialize(this, fileSystem);
|
||||
FluentProvider.Initialize(this, fileSystem);
|
||||
|
||||
Game.Sound.Initialize(SoundLoaders, fileSystem);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace OpenRA.Network
|
||||
}
|
||||
}
|
||||
|
||||
public class LocalizedMessage
|
||||
public class FluentMessage
|
||||
{
|
||||
public const int ProtocolVersion = 1;
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace OpenRA.Network
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public LocalizedMessage(MiniYaml yaml)
|
||||
public FluentMessage(MiniYaml yaml)
|
||||
{
|
||||
// Let the FieldLoader do the dirty work of loading the public fields.
|
||||
FieldLoader.Load(this, yaml);
|
||||
@@ -105,7 +105,7 @@ namespace OpenRA.Network
|
||||
}
|
||||
|
||||
return new MiniYaml("", root)
|
||||
.ToLines("LocalizedMessage")
|
||||
.ToLines("FluentMessage")
|
||||
.JoinWith("\n");
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace OpenRA.Network
|
||||
{
|
||||
const OrderPacket ClientDisconnected = null;
|
||||
|
||||
[TranslationReference("frame")]
|
||||
[FluentReference("frame")]
|
||||
const string DesyncCompareLogs = "notification-desync-compare-logs";
|
||||
|
||||
readonly SyncReport syncReport;
|
||||
@@ -91,7 +91,7 @@ namespace OpenRA.Network
|
||||
World.OutOfSync();
|
||||
IsOutOfSync = true;
|
||||
|
||||
TextNotificationsManager.AddSystemLine(DesyncCompareLogs, Translation.Arguments("frame", frame));
|
||||
TextNotificationsManager.AddSystemLine(DesyncCompareLogs, FluentBundle.Arguments("frame", frame));
|
||||
}
|
||||
|
||||
public void StartGame()
|
||||
|
||||
@@ -20,22 +20,22 @@ namespace OpenRA.Network
|
||||
{
|
||||
public const int ChatMessageMaxLength = 2500;
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string Joined = "notification-joined";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string Left = "notification-lobby-disconnected";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string GameStarted = "notification-game-has-started";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string GameSaved = "notification-game-saved";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string GamePaused = "notification-game-paused";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string GameUnpaused = "notification-game-unpaused";
|
||||
|
||||
public static int? KickVoteTarget { get; internal set; }
|
||||
@@ -56,8 +56,8 @@ namespace OpenRA.Network
|
||||
TextNotificationsManager.AddSystemLine(order.TargetString);
|
||||
break;
|
||||
|
||||
// Client side translated server message
|
||||
case "LocalizedMessage":
|
||||
// Client side resolved server message
|
||||
case "FluentMessage":
|
||||
{
|
||||
if (string.IsNullOrEmpty(order.TargetString))
|
||||
break;
|
||||
@@ -65,7 +65,7 @@ namespace OpenRA.Network
|
||||
var yaml = MiniYaml.FromString(order.TargetString, order.OrderString);
|
||||
foreach (var node in yaml)
|
||||
{
|
||||
var localizedMessage = new LocalizedMessage(node.Value);
|
||||
var localizedMessage = new FluentMessage(node.Value);
|
||||
if (localizedMessage.Key == Joined)
|
||||
TextNotificationsManager.AddPlayerJoinedLine(localizedMessage.Key, localizedMessage.Arguments);
|
||||
else if (localizedMessage.Key == Left)
|
||||
@@ -231,7 +231,7 @@ namespace OpenRA.Network
|
||||
break;
|
||||
|
||||
if (orderManager.World.Paused != pause && world != null && world.LobbyInfo.NonBotClients.Count() > 1)
|
||||
TextNotificationsManager.AddSystemLine(pause ? GamePaused : GameUnpaused, Translation.Arguments("player", client.Name));
|
||||
TextNotificationsManager.AddSystemLine(pause ? GamePaused : GameUnpaused, FluentBundle.Arguments("player", client.Name));
|
||||
|
||||
orderManager.World.Paused = pause;
|
||||
orderManager.World.PredictedPaused = pause;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA
|
||||
|
||||
public class Player : IScriptBindable, IScriptNotifyBind, ILuaTableBinding, ILuaEqualityBinding, ILuaToStringBinding
|
||||
{
|
||||
[TranslationReference("name", "number")]
|
||||
[FluentReference("name", "number")]
|
||||
const string EnumeratedBotName = "enumerated-bot-name";
|
||||
|
||||
public readonly Actor PlayerActor;
|
||||
@@ -238,8 +238,8 @@ namespace OpenRA
|
||||
{
|
||||
var botInfo = botInfos.First(b => b.Type == BotType);
|
||||
var botsOfSameType = World.Players.Where(c => c.BotType == BotType).ToArray();
|
||||
return TranslationProvider.GetString(EnumeratedBotName,
|
||||
Translation.Arguments("name", TranslationProvider.GetString(botInfo.Name),
|
||||
return FluentProvider.GetString(EnumeratedBotName,
|
||||
FluentBundle.Arguments("name", FluentProvider.GetString(botInfo.Name),
|
||||
"number", botsOfSameType.IndexOf(this) + 1));
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace OpenRA.Server
|
||||
{
|
||||
sealed class PlayerMessageTracker
|
||||
{
|
||||
[TranslationReference("remaining")]
|
||||
[FluentReference("remaining")]
|
||||
const string ChatTemporaryDisabled = "notification-chat-temp-disabled";
|
||||
|
||||
readonly Dictionary<int, List<long>> messageTracker = new();
|
||||
@@ -56,7 +56,7 @@ namespace OpenRA.Server
|
||||
if (!isAdmin && time < settings.FloodLimitJoinCooldown)
|
||||
{
|
||||
var remaining = CalculateRemaining(settings.FloodLimitJoinCooldown);
|
||||
sendLocalizedMessageTo(conn, ChatTemporaryDisabled, Translation.Arguments("remaining", remaining));
|
||||
sendLocalizedMessageTo(conn, ChatTemporaryDisabled, FluentBundle.Arguments("remaining", remaining));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace OpenRA.Server
|
||||
if (tracker.Count >= settings.FloodLimitMessageCount)
|
||||
{
|
||||
var remaining = CalculateRemaining(tracker[0] + settings.FloodLimitInterval);
|
||||
sendLocalizedMessageTo(conn, ChatTemporaryDisabled, Translation.Arguments("remaining", remaining));
|
||||
sendLocalizedMessageTo(conn, ChatTemporaryDisabled, FluentBundle.Arguments("remaining", remaining));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,73 +47,73 @@ namespace OpenRA.Server
|
||||
|
||||
public sealed class Server
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string CustomRules = "notification-custom-rules";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string BotsDisabled = "notification-map-bots-disabled";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string TwoHumansRequired = "notification-two-humans-required";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string ErrorGameStarted = "notification-error-game-started";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string RequiresPassword = "notification-requires-password";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string IncorrectPassword = "notification-incorrect-password";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string IncompatibleMod = "notification-incompatible-mod";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string IncompatibleVersion = "notification-incompatible-version";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string IncompatibleProtocol = "notification-incompatible-protocol";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string Banned = "notification-you-were-banned";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string TempBanned = "notification-you-were-temp-banned";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string Full = "notification-game-full";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string Joined = "notification-joined";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string RequiresAuthentication = "notification-requires-authentication";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string NoPermission = "notification-no-permission-to-join";
|
||||
|
||||
[TranslationReference("command")]
|
||||
[FluentReference("command")]
|
||||
const string UnknownServerCommand = "notification-unknown-server-command";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string LobbyDisconnected = "notification-lobby-disconnected";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string PlayerDisconnected = "notification-player-disconnected";
|
||||
|
||||
[TranslationReference("player", "team")]
|
||||
[FluentReference("player", "team")]
|
||||
const string PlayerTeamDisconnected = "notification-team-player-disconnected";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string ObserverDisconnected = "notification-observer-disconnected";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string NewAdmin = "notification-new-admin";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string YouWereKicked = "notification-you-were-kicked";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string GameStarted = "notification-game-started";
|
||||
|
||||
public readonly MersenneTwister Random = new();
|
||||
@@ -580,7 +580,7 @@ namespace OpenRA.Server
|
||||
|
||||
Log.Write("server", $"{client.Name} ({newConn.EndPoint}) has joined the game.");
|
||||
|
||||
SendLocalizedMessage(Joined, Translation.Arguments("player", client.Name));
|
||||
SendLocalizedMessage(Joined, FluentBundle.Arguments("player", client.Name));
|
||||
|
||||
if (Type == ServerType.Dedicated)
|
||||
{
|
||||
@@ -954,17 +954,17 @@ namespace OpenRA.Server
|
||||
|
||||
public void SendLocalizedMessage(string key, Dictionary<string, object> arguments = null)
|
||||
{
|
||||
var text = LocalizedMessage.Serialize(key, arguments);
|
||||
DispatchServerOrdersToClients(Order.FromTargetString("LocalizedMessage", text, true));
|
||||
var text = FluentMessage.Serialize(key, arguments);
|
||||
DispatchServerOrdersToClients(Order.FromTargetString("FluentMessage", text, true));
|
||||
|
||||
if (Type == ServerType.Dedicated)
|
||||
WriteLineWithTimeStamp(TranslationProvider.GetString(key, arguments));
|
||||
WriteLineWithTimeStamp(FluentProvider.GetString(key, arguments));
|
||||
}
|
||||
|
||||
public void SendLocalizedMessageTo(Connection conn, string key, Dictionary<string, object> arguments = null)
|
||||
{
|
||||
var text = LocalizedMessage.Serialize(key, arguments);
|
||||
DispatchOrdersToClient(conn, 0, 0, Order.FromTargetString("LocalizedMessage", text, true).Serialize());
|
||||
var text = FluentMessage.Serialize(key, arguments);
|
||||
DispatchOrdersToClient(conn, 0, 0, Order.FromTargetString("FluentMessage", text, true).Serialize());
|
||||
}
|
||||
|
||||
void WriteLineWithTimeStamp(string line)
|
||||
@@ -998,7 +998,7 @@ namespace OpenRA.Server
|
||||
if (!InterpretCommand(o.TargetString, conn))
|
||||
{
|
||||
Log.Write("server", $"Unknown server command: {o.TargetString}");
|
||||
SendLocalizedMessageTo(conn, UnknownServerCommand, Translation.Arguments("command", o.TargetString));
|
||||
SendLocalizedMessageTo(conn, UnknownServerCommand, FluentBundle.Arguments("command", o.TargetString));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1180,14 +1180,14 @@ namespace OpenRA.Server
|
||||
if (State == ServerState.GameStarted)
|
||||
{
|
||||
if (dropClient.IsObserver)
|
||||
SendLocalizedMessage(ObserverDisconnected, Translation.Arguments("player", dropClient.Name));
|
||||
SendLocalizedMessage(ObserverDisconnected, FluentBundle.Arguments("player", dropClient.Name));
|
||||
else if (dropClient.Team > 0)
|
||||
SendLocalizedMessage(PlayerTeamDisconnected, Translation.Arguments("player", dropClient.Name, "team", dropClient.Team));
|
||||
SendLocalizedMessage(PlayerTeamDisconnected, FluentBundle.Arguments("player", dropClient.Name, "team", dropClient.Team));
|
||||
else
|
||||
SendLocalizedMessage(PlayerDisconnected, Translation.Arguments("player", dropClient.Name));
|
||||
SendLocalizedMessage(PlayerDisconnected, FluentBundle.Arguments("player", dropClient.Name));
|
||||
}
|
||||
else
|
||||
SendLocalizedMessage(LobbyDisconnected, Translation.Arguments("player", dropClient.Name));
|
||||
SendLocalizedMessage(LobbyDisconnected, FluentBundle.Arguments("player", dropClient.Name));
|
||||
|
||||
LobbyInfo.Clients.RemoveAll(c => c.Index == toDrop.PlayerIndex);
|
||||
|
||||
@@ -1204,7 +1204,7 @@ namespace OpenRA.Server
|
||||
if (nextAdmin != null)
|
||||
{
|
||||
nextAdmin.IsAdmin = true;
|
||||
SendLocalizedMessage(NewAdmin, Translation.Arguments("player", nextAdmin.Name));
|
||||
SendLocalizedMessage(NewAdmin, FluentBundle.Arguments("player", nextAdmin.Name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1302,7 +1302,7 @@ namespace OpenRA.Server
|
||||
{
|
||||
lock (LobbyInfo)
|
||||
{
|
||||
WriteLineWithTimeStamp(TranslationProvider.GetString(GameStarted));
|
||||
WriteLineWithTimeStamp(FluentProvider.GetString(GameStarted));
|
||||
|
||||
// Drop any players who are not ready
|
||||
foreach (var c in Conns.Where(c => !c.Validated || GetClient(c).IsInvalid).ToArray())
|
||||
|
||||
@@ -17,22 +17,22 @@ namespace OpenRA.Server
|
||||
{
|
||||
public sealed class VoteKickTracker
|
||||
{
|
||||
[TranslationReference("kickee")]
|
||||
[FluentReference("kickee")]
|
||||
const string InsufficientVotes = "notification-insufficient-votes-to-kick";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string AlreadyVoted = "notification-kick-already-voted";
|
||||
|
||||
[TranslationReference("kicker", "kickee")]
|
||||
[FluentReference("kicker", "kickee")]
|
||||
const string VoteKickStarted = "notification-vote-kick-started";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string UnableToStartAVote = "notification-unable-to-start-a-vote";
|
||||
|
||||
[TranslationReference("kickee", "percentage")]
|
||||
[FluentReference("kickee", "percentage")]
|
||||
const string VoteKickProgress = "notification-vote-kick-in-progress";
|
||||
|
||||
[TranslationReference("kickee")]
|
||||
[FluentReference("kickee")]
|
||||
const string VoteKickEnded = "notification-vote-kick-ended";
|
||||
|
||||
readonly Dictionary<int, bool> voteTracker = new();
|
||||
@@ -107,7 +107,7 @@ namespace OpenRA.Server
|
||||
if (!kickee.IsObserver && !server.HasClientWonOrLost(kickee))
|
||||
{
|
||||
// Vote kick cannot be the sole deciding factor for a game.
|
||||
server.SendLocalizedMessageTo(conn, InsufficientVotes, Translation.Arguments("kickee", kickee.Name));
|
||||
server.SendLocalizedMessageTo(conn, InsufficientVotes, FluentBundle.Arguments("kickee", kickee.Name));
|
||||
EndKickVote();
|
||||
return false;
|
||||
}
|
||||
@@ -135,7 +135,7 @@ namespace OpenRA.Server
|
||||
|
||||
Log.Write("server", $"Vote kick started on {kickeeID}.");
|
||||
voteKickTimer = Stopwatch.StartNew();
|
||||
server.SendLocalizedMessage(VoteKickStarted, Translation.Arguments("kicker", kicker.Name, "kickee", kickee.Name));
|
||||
server.SendLocalizedMessage(VoteKickStarted, FluentBundle.Arguments("kicker", kicker.Name, "kickee", kickee.Name));
|
||||
server.DispatchServerOrdersToClients(new Order("StartKickVote", null, false) { ExtraData = (uint)kickeeID }.Serialize());
|
||||
this.kickee = (kickee, kickeeConn);
|
||||
voteKickerStarter = (kicker, conn);
|
||||
@@ -168,7 +168,7 @@ namespace OpenRA.Server
|
||||
}
|
||||
|
||||
var votesNeeded = eligiblePlayers / 2 + 1;
|
||||
server.SendLocalizedMessage(VoteKickProgress, Translation.Arguments(
|
||||
server.SendLocalizedMessage(VoteKickProgress, FluentBundle.Arguments(
|
||||
"kickee", kickee.Name,
|
||||
"percentage", votesFor * 100 / eligiblePlayers));
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace OpenRA.Server
|
||||
return;
|
||||
|
||||
if (sendMessage)
|
||||
server.SendLocalizedMessage(VoteKickEnded, Translation.Arguments("kickee", kickee.Client.Name));
|
||||
server.SendLocalizedMessage(VoteKickEnded, FluentBundle.Arguments("kickee", kickee.Client.Name));
|
||||
|
||||
server.DispatchServerOrdersToClients(new Order("EndKickVote", null, false) { ExtraData = (uint)kickee.Client.Index }.Serialize());
|
||||
|
||||
|
||||
@@ -38,12 +38,12 @@ namespace OpenRA
|
||||
return;
|
||||
|
||||
if (player == null || player == player.World.LocalPlayer)
|
||||
AddTextNotification(TextNotificationPool.Transients, SystemClientId, SystemMessageLabel, TranslationProvider.GetString(text));
|
||||
AddTextNotification(TextNotificationPool.Transients, SystemClientId, SystemMessageLabel, FluentProvider.GetString(text));
|
||||
}
|
||||
|
||||
public static void AddFeedbackLine(string text, Dictionary<string, object> arguments = null)
|
||||
{
|
||||
AddTextNotification(TextNotificationPool.Feedback, SystemClientId, SystemMessageLabel, TranslationProvider.GetString(text, arguments));
|
||||
AddTextNotification(TextNotificationPool.Feedback, SystemClientId, SystemMessageLabel, FluentProvider.GetString(text, arguments));
|
||||
}
|
||||
|
||||
public static void AddMissionLine(string prefix, string text, Color? prefixColor = null)
|
||||
@@ -53,17 +53,17 @@ namespace OpenRA
|
||||
|
||||
public static void AddPlayerJoinedLine(string text, Dictionary<string, object> arguments = null)
|
||||
{
|
||||
AddTextNotification(TextNotificationPool.Join, SystemClientId, SystemMessageLabel, TranslationProvider.GetString(text, arguments));
|
||||
AddTextNotification(TextNotificationPool.Join, SystemClientId, SystemMessageLabel, FluentProvider.GetString(text, arguments));
|
||||
}
|
||||
|
||||
public static void AddPlayerLeftLine(string text, Dictionary<string, object> arguments = null)
|
||||
{
|
||||
AddTextNotification(TextNotificationPool.Leave, SystemClientId, SystemMessageLabel, TranslationProvider.GetString(text, arguments));
|
||||
AddTextNotification(TextNotificationPool.Leave, SystemClientId, SystemMessageLabel, FluentProvider.GetString(text, arguments));
|
||||
}
|
||||
|
||||
public static void AddSystemLine(string text, Dictionary<string, object> arguments = null)
|
||||
{
|
||||
AddSystemLine(SystemMessageLabel, TranslationProvider.GetString(text, arguments));
|
||||
AddSystemLine(SystemMessageLabel, FluentProvider.GetString(text, arguments));
|
||||
}
|
||||
|
||||
public static void AddSystemLine(string prefix, string text)
|
||||
|
||||
@@ -18,11 +18,11 @@ namespace OpenRA.Traits
|
||||
[Desc("Required for shroud and fog visibility checks. Add this to the player actor.")]
|
||||
public class ShroudInfo : TraitInfo, ILobbyOptions
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Descriptive label for the fog checkbox in the lobby.")]
|
||||
public readonly string FogCheckboxLabel = "checkbox-fog-of-war.label";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the fog checkbox in the lobby.")]
|
||||
public readonly string FogCheckboxDescription = "checkbox-fog-of-war.description";
|
||||
|
||||
@@ -38,11 +38,11 @@ namespace OpenRA.Traits
|
||||
[Desc("Display order for the fog checkbox in the lobby.")]
|
||||
public readonly int FogCheckboxDisplayOrder = 0;
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Descriptive label for the explored map checkbox in the lobby.")]
|
||||
public readonly string ExploredMapCheckboxLabel = "checkbox-explored-map.label";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the explored map checkbox in the lobby.")]
|
||||
public readonly string ExploredMapCheckboxDescription = "checkbox-explored-map.description";
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Traits
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
public class FactionInfo : TraitInfo<Faction>
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("This is the name exposed to the players.")]
|
||||
public readonly string Name = null;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenRA.Traits
|
||||
[Desc("The side that the faction belongs to. For example, England belongs to the 'Allies' side.")]
|
||||
public readonly string Side = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("This is shown in the lobby as a tooltip.")]
|
||||
public readonly string Description = null;
|
||||
|
||||
|
||||
@@ -51,13 +51,13 @@ namespace OpenRA.Mods.Cnc.Installer
|
||||
|
||||
Action<long> onProgress = null;
|
||||
if (stream.Length < InstallFromSourceLogic.ShowPercentageThreshold)
|
||||
updateMessage(TranslationProvider.GetString(
|
||||
updateMessage(FluentProvider.GetString(
|
||||
InstallFromSourceLogic.Extracing,
|
||||
Translation.Arguments("filename", displayFilename)));
|
||||
FluentBundle.Arguments("filename", displayFilename)));
|
||||
else
|
||||
onProgress = b => updateMessage(TranslationProvider.GetString(
|
||||
onProgress = b => updateMessage(FluentProvider.GetString(
|
||||
InstallFromSourceLogic.ExtractingProgress,
|
||||
Translation.Arguments("filename", displayFilename, "progress", 100 * b / stream.Length)));
|
||||
FluentBundle.Arguments("filename", displayFilename, "progress", 100 * b / stream.Length)));
|
||||
|
||||
using (var target = File.OpenWrite(targetPath))
|
||||
{
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[Desc("Sound the victim will hear when they get robbed.")]
|
||||
public readonly string InfiltratedNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification the victim will see when they get robbed.")]
|
||||
public readonly string InfiltratedTextNotification = null;
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[Desc("Sound the perpetrator will hear after successful infiltration.")]
|
||||
public readonly string InfiltrationNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification the perpetrator will see after successful infiltration.")]
|
||||
public readonly string InfiltrationTextNotification = null;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[Desc("Sound the victim will hear when they get sabotaged.")]
|
||||
public readonly string InfiltratedNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification the victim will see when they get sabotaged.")]
|
||||
public readonly string InfiltratedTextNotification = null;
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[Desc("Sound the perpetrator will hear after successful infiltration.")]
|
||||
public readonly string InfiltrationNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification the perpetrator will see after successful infiltration.")]
|
||||
public readonly string InfiltrationTextNotification = null;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[Desc("Sound the victim will hear when they get sabotaged.")]
|
||||
public readonly string InfiltratedNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification the victim will see when they get sabotaged.")]
|
||||
public readonly string InfiltratedTextNotification = null;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[Desc("Sound the perpetrator will hear after successful infiltration.")]
|
||||
public readonly string InfiltrationNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification the perpetrator will see after successful infiltration.")]
|
||||
public readonly string InfiltrationTextNotification = null;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[Desc("Sound the victim will hear when technology gets stolen.")]
|
||||
public readonly string InfiltratedNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification the victim will see when technology gets stolen.")]
|
||||
public readonly string InfiltratedTextNotification = null;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[Desc("Sound the perpetrator will hear after successful infiltration.")]
|
||||
public readonly string InfiltrationNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification the perpetrator will see after successful infiltration.")]
|
||||
public readonly string InfiltrationTextNotification = null;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[Desc("Experience to grant to the infiltrating player.")]
|
||||
public readonly int PlayerExperience = 0;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification the victim will see when they get sabotaged.")]
|
||||
public readonly string InfiltratedTextNotification = null;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[Desc("Sound the perpetrator will hear after successful infiltration.")]
|
||||
public readonly string InfiltrationNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification the perpetrator will see after successful infiltration.")]
|
||||
public readonly string InfiltrationTextNotification = null;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
[Desc("Notification to play when a target is infiltrated.")]
|
||||
public readonly string Notification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display when a target is infiltrated.")]
|
||||
public readonly string TextNotification = null;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
public readonly string Palette = TileSet.TerrainPaletteInternalName;
|
||||
|
||||
[FieldLoader.Require]
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Resource name used by tooltips.")]
|
||||
public readonly string Name = null;
|
||||
|
||||
@@ -371,7 +371,7 @@ namespace OpenRA.Mods.Cnc.Traits
|
||||
string IResourceRenderer.GetRenderedResourceTooltip(CPos cell)
|
||||
{
|
||||
if (renderIndices[cell] != null || borders[cell] != Adjacency.None)
|
||||
return TranslationProvider.GetString(info.Name);
|
||||
return FluentProvider.GetString(info.Name);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Commands
|
||||
|
||||
public class ChatCommands : INotifyChat
|
||||
{
|
||||
[TranslationReference("name")]
|
||||
[FluentReference("name")]
|
||||
const string InvalidCommand = "notification-invalid-command";
|
||||
|
||||
public Dictionary<string, IChatCommand> Commands { get; }
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Commands
|
||||
if (Commands.TryGetValue(name, out var command))
|
||||
command.InvokeCommand(name, message[(1 + name.Length)..].Trim());
|
||||
else
|
||||
TextNotificationsManager.Debug(TranslationProvider.GetString(InvalidCommand, Translation.Arguments("name", name)));
|
||||
TextNotificationsManager.Debug(FluentProvider.GetString(InvalidCommand, FluentBundle.Arguments("name", name)));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -23,19 +23,19 @@ namespace OpenRA.Mods.Common.Commands
|
||||
|
||||
public class DebugVisualizationCommands : IChatCommand, IWorldLoaded
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string CombatGeometryDescription = "description-combat-geometry";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string RenderGeometryDescription = "description-render-geometry";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string ScreenMapOverlayDescription = "description-screen-map-overlay";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string DepthBufferDescription = "description-depth-buffer";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string ActorTagsOverlayDescripition = "description-actor-tags-overlay";
|
||||
|
||||
readonly IDictionary<string, (string Description, Action<DebugVisualizations, DeveloperMode> Handler)> commandHandlers =
|
||||
|
||||
@@ -24,55 +24,55 @@ namespace OpenRA.Mods.Common.Commands
|
||||
|
||||
public class DevCommands : IChatCommand, IWorldLoaded
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string CheatsDisabled = "notification-cheats-disabled";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string InvalidCashAmount = "notification-invalid-cash-amount";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string ToggleVisiblityDescription = "description-toggle-visibility";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string GiveCashDescription = "description-give-cash";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string GiveCashAllDescription = "description-give-cash-all";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string InstantBuildingDescription = "description-instant-building";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string BuildAnywhereDescription = "description-build-anywhere";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string UnlimitedPowerDescription = "description-unlimited-power";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string EnableTechDescription = "description-enable-tech";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string FastChargeDescription = "description-fast-charge";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string DevCheatAllDescription = "description-dev-cheat-all";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string DevCrashDescription = "description-dev-crash";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string LevelUpActorDescription = "description-levelup-actor";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string PlayerExperienceDescription = "description-player-experience";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string PowerOutageDescription = "description-power-outage";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string KillSelectedActorsDescription = "description-kill-selected-actors";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string DisposeSelectedActorsDescription = "description-dispose-selected-actors";
|
||||
|
||||
readonly IDictionary<string, (string Description, Action<string, World> Handler)> commandHandlers = new Dictionary<string, (string, Action<string, World>)>
|
||||
@@ -121,7 +121,7 @@ namespace OpenRA.Mods.Common.Commands
|
||||
|
||||
if (!developerMode.Enabled)
|
||||
{
|
||||
TextNotificationsManager.Debug(TranslationProvider.GetString(CheatsDisabled));
|
||||
TextNotificationsManager.Debug(FluentProvider.GetString(CheatsDisabled));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace OpenRA.Mods.Common.Commands
|
||||
giveCashOrder.ExtraData = (uint)cash;
|
||||
else
|
||||
{
|
||||
TextNotificationsManager.Debug(TranslationProvider.GetString(InvalidCashAmount));
|
||||
TextNotificationsManager.Debug(FluentProvider.GetString(InvalidCashAmount));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,13 +22,13 @@ namespace OpenRA.Mods.Common.Commands
|
||||
|
||||
public class HelpCommand : IChatCommand, IWorldLoaded
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string AvailableCommands = "notification-available-commands";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string NoDescription = "description-no-description";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string HelpDescription = "description-help-description";
|
||||
|
||||
readonly Dictionary<string, string> helpDescriptions;
|
||||
@@ -52,12 +52,12 @@ namespace OpenRA.Mods.Common.Commands
|
||||
|
||||
public void InvokeCommand(string name, string arg)
|
||||
{
|
||||
TextNotificationsManager.Debug(TranslationProvider.GetString(AvailableCommands));
|
||||
TextNotificationsManager.Debug(FluentProvider.GetString(AvailableCommands));
|
||||
|
||||
foreach (var key in console.Commands.Keys.OrderBy(k => k))
|
||||
{
|
||||
if (!helpDescriptions.TryGetValue(key, out var description))
|
||||
description = TranslationProvider.GetString(NoDescription);
|
||||
description = FluentProvider.GetString(NoDescription);
|
||||
|
||||
TextNotificationsManager.Debug($"{key}: {description}");
|
||||
}
|
||||
@@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Commands
|
||||
|
||||
public void RegisterHelp(string name, string description)
|
||||
{
|
||||
helpDescriptions[name] = TranslationProvider.GetString(description);
|
||||
helpDescriptions[name] = FluentProvider.GetString(description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,10 @@ namespace OpenRA.Mods.Common.Commands
|
||||
|
||||
public class PlayerCommands : IChatCommand, IWorldLoaded
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string PauseDescription = "description-pause-description";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string SurrenderDescription = "description-surrender-description";
|
||||
|
||||
World world;
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
{
|
||||
public string Text { get; private set; }
|
||||
|
||||
[TranslationReference("name", "id")]
|
||||
[FluentReference("name", "id")]
|
||||
const string AddedActor = "notification-added-actor";
|
||||
|
||||
readonly EditorActorLayer editorLayer;
|
||||
@@ -167,8 +167,8 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
public void Do()
|
||||
{
|
||||
editorActorPreview = editorLayer.Add(actor);
|
||||
Text = TranslationProvider.GetString(AddedActor,
|
||||
Translation.Arguments("name", editorActorPreview.Info.Name, "id", editorActorPreview.ID));
|
||||
Text = FluentProvider.GetString(AddedActor,
|
||||
FluentBundle.Arguments("name", editorActorPreview.Info.Name, "id", editorActorPreview.ID));
|
||||
}
|
||||
|
||||
public void Undo()
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
sealed class CopyPasteEditorAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("amount")]
|
||||
[FluentReference("amount")]
|
||||
const string CopiedTiles = "notification-copied-tiles";
|
||||
|
||||
public string Text { get; }
|
||||
@@ -146,7 +146,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
undoClipboard = CopySelectionContents();
|
||||
|
||||
Text = TranslationProvider.GetString(CopiedTiles, Translation.Arguments("amount", clipboard.Tiles.Count));
|
||||
Text = FluentProvider.GetString(CopiedTiles, FluentBundle.Arguments("amount", clipboard.Tiles.Count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -279,13 +279,13 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
sealed class ChangeSelectionAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("x", "y", "width", "height")]
|
||||
[FluentReference("x", "y", "width", "height")]
|
||||
const string SelectedArea = "notification-selected-area";
|
||||
|
||||
[TranslationReference("id")]
|
||||
[FluentReference("id")]
|
||||
const string SelectedActor = "notification-selected-actor";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string ClearedSelection = "notification-cleared-selection";
|
||||
|
||||
public string Text { get; }
|
||||
@@ -308,15 +308,15 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
};
|
||||
|
||||
if (selection.Area != null)
|
||||
Text = TranslationProvider.GetString(SelectedArea, Translation.Arguments(
|
||||
Text = FluentProvider.GetString(SelectedArea, FluentBundle.Arguments(
|
||||
"x", selection.Area.TopLeft.X,
|
||||
"y", selection.Area.TopLeft.Y,
|
||||
"width", selection.Area.BottomRight.X - selection.Area.TopLeft.X,
|
||||
"height", selection.Area.BottomRight.Y - selection.Area.TopLeft.Y));
|
||||
else if (selection.Actor != null)
|
||||
Text = TranslationProvider.GetString(SelectedActor, Translation.Arguments("id", selection.Actor.ID));
|
||||
Text = FluentProvider.GetString(SelectedActor, FluentBundle.Arguments("id", selection.Actor.ID));
|
||||
else
|
||||
Text = TranslationProvider.GetString(ClearedSelection);
|
||||
Text = FluentProvider.GetString(ClearedSelection);
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
@@ -337,7 +337,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
sealed class RemoveSelectedActorAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("name", "id")]
|
||||
[FluentReference("name", "id")]
|
||||
const string RemovedActor = "notification-removed-actor";
|
||||
|
||||
public string Text { get; }
|
||||
@@ -360,8 +360,8 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
Actor = defaultBrush.Selection.Actor
|
||||
};
|
||||
|
||||
Text = TranslationProvider.GetString(RemovedActor,
|
||||
Translation.Arguments("name", actor.Info.Name, "id", actor.ID));
|
||||
Text = FluentProvider.GetString(RemovedActor,
|
||||
FluentBundle.Arguments("name", actor.Info.Name, "id", actor.ID));
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
@@ -384,7 +384,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
sealed class RemoveActorAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("name", "id")]
|
||||
[FluentReference("name", "id")]
|
||||
const string RemovedActor = "notification-removed-actor";
|
||||
|
||||
public string Text { get; }
|
||||
@@ -397,8 +397,8 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
this.editorActorLayer = editorActorLayer;
|
||||
this.actor = actor;
|
||||
|
||||
Text = TranslationProvider.GetString(RemovedActor,
|
||||
Translation.Arguments("name", actor.Info.Name, "id", actor.ID));
|
||||
Text = FluentProvider.GetString(RemovedActor,
|
||||
FluentBundle.Arguments("name", actor.Info.Name, "id", actor.ID));
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
@@ -419,7 +419,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
sealed class MoveActorAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("id", "x1", "y1", "x2", "y2")]
|
||||
[FluentReference("id", "x1", "y1", "x2", "y2")]
|
||||
const string MovedActor = "notification-moved-actor";
|
||||
|
||||
public string Text { get; private set; }
|
||||
@@ -466,13 +466,13 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
to = worldRenderer.Viewport.ViewToWorld(pixelTo + pixelOffset) + cellOffset;
|
||||
layer.MoveActor(actor, to);
|
||||
|
||||
Text = TranslationProvider.GetString(MovedActor, Translation.Arguments("id", actor.ID, "x1", from.X, "y1", from.Y, "x2", to.X, "y2", to.Y));
|
||||
Text = FluentProvider.GetString(MovedActor, FluentBundle.Arguments("id", actor.ID, "x1", from.X, "y1", from.Y, "x2", to.X, "y2", to.Y));
|
||||
}
|
||||
}
|
||||
|
||||
sealed class RemoveResourceAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("type")]
|
||||
[FluentReference("type")]
|
||||
const string RemovedResource = "notification-removed-resource";
|
||||
|
||||
public string Text { get; }
|
||||
@@ -487,7 +487,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
this.resourceLayer = resourceLayer;
|
||||
this.cell = cell;
|
||||
|
||||
Text = TranslationProvider.GetString(RemovedResource, Translation.Arguments("type", resourceType));
|
||||
Text = FluentProvider.GetString(RemovedResource, FluentBundle.Arguments("type", resourceType));
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
|
||||
@@ -98,10 +98,10 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
class PaintMarkerTileEditorAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("amount", "type")]
|
||||
[FluentReference("amount", "type")]
|
||||
const string AddedMarkerTiles = "notification-added-marker-tiles";
|
||||
|
||||
[TranslationReference("amount")]
|
||||
[FluentReference("amount")]
|
||||
const string RemovedMarkerTiles = "notification-removed-marker-tiles";
|
||||
|
||||
public string Text { get; private set; }
|
||||
@@ -150,15 +150,15 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
}
|
||||
|
||||
if (type != null)
|
||||
Text = TranslationProvider.GetString(AddedMarkerTiles, Translation.Arguments("amount", paintTiles.Count, "type", type));
|
||||
Text = FluentProvider.GetString(AddedMarkerTiles, FluentBundle.Arguments("amount", paintTiles.Count, "type", type));
|
||||
else
|
||||
Text = TranslationProvider.GetString(RemovedMarkerTiles, Translation.Arguments("amount", paintTiles.Count));
|
||||
Text = FluentProvider.GetString(RemovedMarkerTiles, FluentBundle.Arguments("amount", paintTiles.Count));
|
||||
}
|
||||
}
|
||||
|
||||
class ClearSelectedMarkerTilesEditorAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("amount", "type")]
|
||||
[FluentReference("amount", "type")]
|
||||
const string ClearedSelectedMarkerTiles = "notification-cleared-selected-marker-tiles";
|
||||
|
||||
public string Text { get; }
|
||||
@@ -176,7 +176,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
tiles = new HashSet<CPos>(markerLayerOverlay.Tiles[tile]);
|
||||
|
||||
Text = TranslationProvider.GetString(ClearedSelectedMarkerTiles, Translation.Arguments("amount", tiles.Count, "type", tile));
|
||||
Text = FluentProvider.GetString(ClearedSelectedMarkerTiles, FluentBundle.Arguments("amount", tiles.Count, "type", tile));
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
@@ -197,7 +197,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
class ClearAllMarkerTilesEditorAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("amount")]
|
||||
[FluentReference("amount")]
|
||||
const string ClearedAllMarkerTiles = "notification-cleared-all-marker-tiles";
|
||||
|
||||
public string Text { get; }
|
||||
@@ -213,7 +213,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
var allTilesCount = tiles.Values.Select(x => x.Count).Sum();
|
||||
|
||||
Text = TranslationProvider.GetString(ClearedAllMarkerTiles, Translation.Arguments("amount", allTilesCount));
|
||||
Text = FluentProvider.GetString(ClearedAllMarkerTiles, FluentBundle.Arguments("amount", allTilesCount));
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
sealed class AddResourcesEditorAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("amount", "type")]
|
||||
[FluentReference("amount", "type")]
|
||||
const string AddedResource = "notification-added-resource";
|
||||
|
||||
public string Text { get; private set; }
|
||||
@@ -168,7 +168,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
resourceLayer.ClearResources(resourceCell.Cell);
|
||||
resourceLayer.AddResource(resourceCell.NewResourceType, resourceCell.Cell, resourceLayer.GetMaxDensity(resourceCell.NewResourceType));
|
||||
cellResources.Add(resourceCell);
|
||||
Text = TranslationProvider.GetString(AddedResource, Translation.Arguments("amount", cellResources.Count, "type", resourceType));
|
||||
Text = FluentProvider.GetString(AddedResource, FluentBundle.Arguments("amount", cellResources.Count, "type", resourceType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
sealed class PaintTileEditorAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("id")]
|
||||
[FluentReference("id")]
|
||||
const string AddedTile = "notification-added-tile";
|
||||
|
||||
public string Text { get; }
|
||||
@@ -192,7 +192,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
var terrainInfo = (ITemplatedTerrainInfo)map.Rules.TerrainInfo;
|
||||
terrainTemplate = terrainInfo.Templates[template];
|
||||
Text = TranslationProvider.GetString(AddedTile, Translation.Arguments("id", terrainTemplate.Id));
|
||||
Text = FluentProvider.GetString(AddedTile, FluentBundle.Arguments("id", terrainTemplate.Id));
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
@@ -244,7 +244,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
sealed class FloodFillEditorAction : IEditorAction
|
||||
{
|
||||
[TranslationReference("id")]
|
||||
[FluentReference("id")]
|
||||
const string FilledTile = "notification-filled-tile";
|
||||
|
||||
public string Text { get; }
|
||||
@@ -264,7 +264,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
var terrainInfo = (ITemplatedTerrainInfo)map.Rules.TerrainInfo;
|
||||
terrainTemplate = terrainInfo.Templates[template];
|
||||
Text = TranslationProvider.GetString(FilledTile, Translation.Arguments("id", terrainTemplate.Id));
|
||||
Text = FluentProvider.GetString(FilledTile, FluentBundle.Arguments("id", terrainTemplate.Id));
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
|
||||
@@ -44,13 +44,13 @@ namespace OpenRA.Mods.Common.Installer
|
||||
|
||||
Action<long> onProgress = null;
|
||||
if (length < InstallFromSourceLogic.ShowPercentageThreshold)
|
||||
updateMessage(TranslationProvider.GetString(
|
||||
updateMessage(FluentProvider.GetString(
|
||||
InstallFromSourceLogic.CopyingFilename,
|
||||
Translation.Arguments("filename", displayFilename)));
|
||||
FluentBundle.Arguments("filename", displayFilename)));
|
||||
else
|
||||
onProgress = b => updateMessage(TranslationProvider.GetString(
|
||||
onProgress = b => updateMessage(FluentProvider.GetString(
|
||||
InstallFromSourceLogic.CopyingFilenameProgress,
|
||||
Translation.Arguments("filename", displayFilename, "progress", 100 * b / length)));
|
||||
FluentBundle.Arguments("filename", displayFilename, "progress", 100 * b / length)));
|
||||
|
||||
InstallerUtils.CopyStream(source, target, length, onProgress);
|
||||
}
|
||||
|
||||
@@ -68,13 +68,13 @@ namespace OpenRA.Mods.Common.Installer
|
||||
|
||||
Action<long> onProgress = null;
|
||||
if (length < InstallFromSourceLogic.ShowPercentageThreshold)
|
||||
updateMessage(TranslationProvider.GetString(
|
||||
updateMessage(FluentProvider.GetString(
|
||||
InstallFromSourceLogic.Extracing,
|
||||
Translation.Arguments("filename", displayFilename)));
|
||||
FluentBundle.Arguments("filename", displayFilename)));
|
||||
else
|
||||
onProgress = b => updateMessage(TranslationProvider.GetString(
|
||||
onProgress = b => updateMessage(FluentProvider.GetString(
|
||||
InstallFromSourceLogic.ExtractingProgress,
|
||||
Translation.Arguments("filename", displayFilename, "progress", 100 * b / length)));
|
||||
FluentBundle.Arguments("filename", displayFilename, "progress", 100 * b / length)));
|
||||
|
||||
using (var target = File.OpenWrite(targetPath))
|
||||
{
|
||||
|
||||
@@ -64,9 +64,9 @@ namespace OpenRA.Mods.Common.Installer
|
||||
{
|
||||
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
|
||||
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
|
||||
void OnProgress(int percent) => updateMessage(TranslationProvider.GetString(
|
||||
void OnProgress(int percent) => updateMessage(FluentProvider.GetString(
|
||||
InstallFromSourceLogic.ExtractingProgress,
|
||||
Translation.Arguments("filename", displayFilename, "progress", percent)));
|
||||
FluentBundle.Arguments("filename", displayFilename, "progress", percent)));
|
||||
reader.ExtractFile(node.Value.Value, target, OnProgress);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,9 +46,9 @@ namespace OpenRA.Mods.Common.Installer
|
||||
{
|
||||
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
|
||||
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
|
||||
void OnProgress(int percent) => updateMessage(TranslationProvider.GetString(
|
||||
void OnProgress(int percent) => updateMessage(FluentProvider.GetString(
|
||||
InstallFromSourceLogic.ExtractingProgress,
|
||||
Translation.Arguments("filename", displayFilename, "progress", percent)));
|
||||
FluentBundle.Arguments("filename", displayFilename, "progress", percent)));
|
||||
reader.ExtractFile(node.Value.Value, target, OnProgress);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,11 +61,11 @@ namespace OpenRA.Mods.Common.Installer
|
||||
|
||||
Action<long> onProgress = null;
|
||||
if (length < InstallFromSourceLogic.ShowPercentageThreshold)
|
||||
updateMessage(TranslationProvider.GetString(InstallFromSourceLogic.Extracing, Translation.Arguments("filename", displayFilename)));
|
||||
updateMessage(FluentProvider.GetString(InstallFromSourceLogic.Extracing, FluentBundle.Arguments("filename", displayFilename)));
|
||||
else
|
||||
onProgress = b => updateMessage(TranslationProvider.GetString(
|
||||
onProgress = b => updateMessage(FluentProvider.GetString(
|
||||
InstallFromSourceLogic.ExtractingProgress,
|
||||
Translation.Arguments("filename", displayFilename, "progress", 100 * b / length)));
|
||||
FluentBundle.Arguments("filename", displayFilename, "progress", 100 * b / length)));
|
||||
|
||||
using (var target = File.OpenWrite(targetPath))
|
||||
{
|
||||
|
||||
@@ -49,9 +49,9 @@ namespace OpenRA.Mods.Common.Installer
|
||||
using (var targetStream = File.OpenWrite(targetPath))
|
||||
sourceStream.CopyTo(targetStream);
|
||||
|
||||
updateMessage(TranslationProvider.GetString(
|
||||
updateMessage(FluentProvider.GetString(
|
||||
InstallFromSourceLogic.ExtractingProgress,
|
||||
Translation.Arguments("filename", displayFilename, "progress", 100)));
|
||||
FluentBundle.Arguments("filename", displayFilename, "progress", 100)));
|
||||
|
||||
extracted.Add(targetPath);
|
||||
}
|
||||
|
||||
@@ -27,23 +27,23 @@ using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.Lint
|
||||
{
|
||||
sealed class CheckTranslationReference : ILintPass, ILintMapPass
|
||||
sealed class CheckFluentReferences : ILintPass, ILintMapPass
|
||||
{
|
||||
static readonly Regex TranslationFilenameRegex = new(@"(?<language>[^\/\\]+)\.ftl$");
|
||||
static readonly Regex FilenameRegex = new(@"(?<language>[^\/\\]+)\.ftl$");
|
||||
|
||||
void ILintMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Map map)
|
||||
{
|
||||
if (map.TranslationDefinitions == null)
|
||||
return;
|
||||
|
||||
var usedKeys = GetUsedTranslationKeysInMap(map, emitWarning);
|
||||
var usedKeys = GetUsedFluentKeysInMap(map, emitWarning);
|
||||
|
||||
foreach (var context in usedKeys.EmptyKeyContexts)
|
||||
emitWarning($"Empty key in map translation files required by {context}");
|
||||
emitWarning($"Empty key in map ftl files required by {context}");
|
||||
|
||||
var mapTranslations = FieldLoader.GetValue<string[]>("value", map.TranslationDefinitions.Value);
|
||||
|
||||
foreach (var language in GetTranslationLanguages(modData))
|
||||
foreach (var language in GetModLanguages(modData))
|
||||
{
|
||||
// Check keys and variables are not missing across all language files.
|
||||
// But for maps we don't warn on unused keys. They might be unused on *this* map,
|
||||
@@ -52,20 +52,20 @@ namespace OpenRA.Mods.Common.Lint
|
||||
modData.Manifest.Translations.Concat(mapTranslations), map.Open, usedKeys,
|
||||
language, _ => false, emitError, emitWarning);
|
||||
|
||||
var modTranslation = new Translation(language, modData.Manifest.Translations, modData.DefaultFileSystem, _ => { });
|
||||
var mapTranslation = new Translation(language, mapTranslations, map, error => emitError(error.Message));
|
||||
var modFluentBundle = new FluentBundle(language, modData.Manifest.Translations, modData.DefaultFileSystem, _ => { });
|
||||
var mapFluentBundle = new FluentBundle(language, mapTranslations, map, error => emitError(error.Message));
|
||||
|
||||
foreach (var group in usedKeys.KeysWithContext)
|
||||
{
|
||||
if (modTranslation.HasMessage(group.Key))
|
||||
if (modFluentBundle.HasMessage(group.Key))
|
||||
{
|
||||
if (mapTranslation.HasMessage(group.Key))
|
||||
emitWarning($"Key `{group.Key}` in `{language}` language in map translation files already exists in mod translations and will not be used.");
|
||||
if (mapFluentBundle.HasMessage(group.Key))
|
||||
emitWarning($"Key `{group.Key}` in `{language}` language in map ftl files already exists in mod translations and will not be used.");
|
||||
}
|
||||
else if (!mapTranslation.HasMessage(group.Key))
|
||||
else if (!mapFluentBundle.HasMessage(group.Key))
|
||||
{
|
||||
foreach (var context in group)
|
||||
emitWarning($"Missing key `{group.Key}` in `{language}` language in map translation files required by {context}");
|
||||
emitWarning($"Missing key `{group.Key}` in `{language}` language in map ftl files required by {context}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,15 +73,14 @@ namespace OpenRA.Mods.Common.Lint
|
||||
|
||||
void ILintPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData)
|
||||
{
|
||||
var (usedKeys, testedFields) = GetUsedTranslationKeysInMod(modData);
|
||||
var (usedKeys, testedFields) = GetUsedFluentKeysInMod(modData);
|
||||
|
||||
foreach (var context in usedKeys.EmptyKeyContexts)
|
||||
emitWarning($"Empty key in mod translation files required by {context}");
|
||||
|
||||
foreach (var language in GetTranslationLanguages(modData))
|
||||
foreach (var language in GetModLanguages(modData))
|
||||
{
|
||||
Console.WriteLine($"Testing translation: {language}");
|
||||
var translation = new Translation(language, modData.Manifest.Translations, modData.DefaultFileSystem, error => emitError(error.Message));
|
||||
Console.WriteLine($"Testing language: {language}");
|
||||
CheckModWidgets(modData, usedKeys, testedFields);
|
||||
|
||||
// With the fully populated keys, check keys and variables are not missing and not unused across all language files.
|
||||
@@ -99,32 +98,32 @@ namespace OpenRA.Mods.Common.Lint
|
||||
continue;
|
||||
|
||||
foreach (var context in group)
|
||||
emitWarning($"Missing key `{group.Key}` in `{language}` language in mod translation files required by {context}");
|
||||
emitWarning($"Missing key `{group.Key}` in `{language}` language in mod ftl files required by {context}");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we couldn't test any fields.
|
||||
const BindingFlags Binding = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
|
||||
var allTranslatableFields = modData.ObjectCreator.GetTypes().SelectMany(t =>
|
||||
t.GetFields(Binding).Where(m => Utility.HasAttribute<TranslationReferenceAttribute>(m))).ToArray();
|
||||
var untestedFields = allTranslatableFields.Except(testedFields);
|
||||
var allFluentFields = modData.ObjectCreator.GetTypes().SelectMany(t =>
|
||||
t.GetFields(Binding).Where(m => Utility.HasAttribute<FluentReferenceAttribute>(m))).ToArray();
|
||||
var untestedFields = allFluentFields.Except(testedFields);
|
||||
foreach (var field in untestedFields)
|
||||
emitError(
|
||||
$"Lint pass ({nameof(CheckTranslationReference)}) lacks the know-how to test translatable field " +
|
||||
$"Lint pass ({nameof(CheckFluentReferences)}) lacks the know-how to test translatable field " +
|
||||
$"`{field.ReflectedType.Name}.{field.Name}` - previous warnings may be incorrect");
|
||||
}
|
||||
|
||||
static IEnumerable<string> GetTranslationLanguages(ModData modData)
|
||||
static IEnumerable<string> GetModLanguages(ModData modData)
|
||||
{
|
||||
return modData.Manifest.Translations
|
||||
.Select(filename => TranslationFilenameRegex.Match(filename).Groups["language"].Value)
|
||||
.Select(filename => FilenameRegex.Match(filename).Groups["language"].Value)
|
||||
.Distinct()
|
||||
.OrderBy(l => l);
|
||||
}
|
||||
|
||||
static TranslationKeys GetUsedTranslationKeysInRuleset(Ruleset rules)
|
||||
static Keys GetUsedFluentKeysInRuleset(Ruleset rules)
|
||||
{
|
||||
var usedKeys = new TranslationKeys();
|
||||
var usedKeys = new Keys();
|
||||
foreach (var actorInfo in rules.Actors)
|
||||
{
|
||||
foreach (var traitInfo in actorInfo.Value.TraitInfos<TraitInfo>())
|
||||
@@ -132,12 +131,12 @@ namespace OpenRA.Mods.Common.Lint
|
||||
var traitType = traitInfo.GetType();
|
||||
foreach (var field in Utility.GetFields(traitType))
|
||||
{
|
||||
var translationReference = Utility.GetCustomAttributes<TranslationReferenceAttribute>(field, true).SingleOrDefault();
|
||||
if (translationReference == null)
|
||||
var fluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(field, true).SingleOrDefault();
|
||||
if (fluentReference == null)
|
||||
continue;
|
||||
|
||||
foreach (var key in LintExts.GetFieldValues(traitInfo, field, translationReference.DictionaryReference))
|
||||
usedKeys.Add(key, translationReference, $"Actor `{actorInfo.Key}` trait `{traitType.Name[..^4]}.{field.Name}`");
|
||||
foreach (var key in LintExts.GetFieldValues(traitInfo, field, fluentReference.DictionaryReference))
|
||||
usedKeys.Add(key, fluentReference, $"Actor `{actorInfo.Key}` trait `{traitType.Name[..^4]}.{field.Name}`");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,12 +148,12 @@ namespace OpenRA.Mods.Common.Lint
|
||||
var warheadType = warhead.GetType();
|
||||
foreach (var field in Utility.GetFields(warheadType))
|
||||
{
|
||||
var translationReference = Utility.GetCustomAttributes<TranslationReferenceAttribute>(field, true).SingleOrDefault();
|
||||
if (translationReference == null)
|
||||
var fluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(field, true).SingleOrDefault();
|
||||
if (fluentReference == null)
|
||||
continue;
|
||||
|
||||
foreach (var key in LintExts.GetFieldValues(warhead, field, translationReference.DictionaryReference))
|
||||
usedKeys.Add(key, translationReference, $"Weapon `{weapon.Key}` warhead `{warheadType.Name[..^7]}.{field.Name}`");
|
||||
foreach (var key in LintExts.GetFieldValues(warhead, field, fluentReference.DictionaryReference))
|
||||
usedKeys.Add(key, fluentReference, $"Weapon `{weapon.Key}` warhead `{warheadType.Name[..^7]}.{field.Name}`");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,40 +161,40 @@ namespace OpenRA.Mods.Common.Lint
|
||||
return usedKeys;
|
||||
}
|
||||
|
||||
static TranslationKeys GetUsedTranslationKeysInMap(Map map, Action<string> emitWarning)
|
||||
static Keys GetUsedFluentKeysInMap(Map map, Action<string> emitWarning)
|
||||
{
|
||||
var usedKeys = GetUsedTranslationKeysInRuleset(map.Rules);
|
||||
var usedKeys = GetUsedFluentKeysInRuleset(map.Rules);
|
||||
|
||||
var luaScriptInfo = map.Rules.Actors[SystemActors.World].TraitInfoOrDefault<LuaScriptInfo>();
|
||||
if (luaScriptInfo != null)
|
||||
{
|
||||
// Matches expressions such as:
|
||||
// UserInterface.Translate("translation-key")
|
||||
// UserInterface.Translate("translation-key\"with-escape")
|
||||
// UserInterface.Translate("translation-key", { ["attribute"] = foo })
|
||||
// UserInterface.Translate("translation-key", { ["attribute\"-with-escape"] = foo })
|
||||
// UserInterface.Translate("translation-key", { ["attribute1"] = foo, ["attribute2"] = bar })
|
||||
// UserInterface.Translate("translation-key", tableVariable)
|
||||
// UserInterface.Translate("fluent-key")
|
||||
// UserInterface.Translate("fluent-key\"with-escape")
|
||||
// UserInterface.Translate("fluent-key", { ["attribute"] = foo })
|
||||
// UserInterface.Translate("fluent-key", { ["attribute\"-with-escape"] = foo })
|
||||
// UserInterface.Translate("fluent-key", { ["attribute1"] = foo, ["attribute2"] = bar })
|
||||
// UserInterface.Translate("fluent-key", tableVariable)
|
||||
// Extracts groups for the 'key' and each 'attr'.
|
||||
// If the table isn't inline like in the last example, extracts it as 'variable'.
|
||||
const string UserInterfaceTranslatePattern =
|
||||
@"UserInterface\s*\.\s*Translate\s*\(" + // UserInterface.Translate(
|
||||
@"\s*""(?<key>(?:[^""\\]|\\.)+?)""\s*" + // "translation-key"
|
||||
@"\s*""(?<key>(?:[^""\\]|\\.)+?)""\s*" + // "fluent-key"
|
||||
@"(,\s*({\s*\[\s*""(?<attr>(?:[^""\\]|\\.)*?)""\s*\]\s*=\s*.*?" + // { ["attribute1"] = foo
|
||||
@"(\s*,\s*\[\s*""(?<attr>(?:[^""\\]|\\.)*?)""\s*\]\s*=\s*.*?)*\s*}\s*)" + // , ["attribute2"] = bar }
|
||||
"|\\s*,\\s*(?<variable>.*?))?" + // tableVariable
|
||||
@"\)"; // )
|
||||
var translateRegex = new Regex(UserInterfaceTranslatePattern);
|
||||
|
||||
// The script in mods/common/scripts/utils.lua defines some helpers which accept a translation key
|
||||
// The script in mods/common/scripts/utils.lua defines some helpers which accept a fluent key
|
||||
// Matches expressions such as:
|
||||
// AddPrimaryObjective(Player, "translation-key")
|
||||
// AddSecondaryObjective(Player, "translation-key")
|
||||
// AddPrimaryObjective(Player, "translation-key\"with-escape")
|
||||
// AddPrimaryObjective(Player, "fluent-key")
|
||||
// AddSecondaryObjective(Player, "fluent-key")
|
||||
// AddPrimaryObjective(Player, "fluent-key\"with-escape")
|
||||
// Extracts groups for the 'key'.
|
||||
const string AddObjectivePattern =
|
||||
@"(AddPrimaryObjective|AddSecondaryObjective)\s*\(" + // AddPrimaryObjective(
|
||||
@".*?\s*,\s*""(?<key>(?:[^""\\]|\\.)+?)""\s*" + // Player, "translation-key"
|
||||
@".*?\s*,\s*""(?<key>(?:[^""\\]|\\.)+?)""\s*" + // Player, "fluent-key"
|
||||
@"\)"; // )
|
||||
var objectiveRegex = new Regex(AddObjectivePattern);
|
||||
|
||||
@@ -210,7 +209,8 @@ namespace OpenRA.Mods.Common.Lint
|
||||
IEnumerable<Match> matches = translateRegex.Matches(scriptText);
|
||||
if (luaScriptInfo.Scripts.Contains("utils.lua"))
|
||||
matches = matches.Concat(objectiveRegex.Matches(scriptText));
|
||||
var scriptTranslations = matches.Select(m =>
|
||||
|
||||
var references = matches.Select(m =>
|
||||
{
|
||||
var key = m.Groups["key"].Value.Replace(@"\""", @"""");
|
||||
var attrs = m.Groups["attr"].Captures.Select(c => c.Value.Replace(@"\""", @"""")).ToArray();
|
||||
@@ -218,10 +218,11 @@ namespace OpenRA.Mods.Common.Lint
|
||||
var line = scriptText.Take(m.Index).Count(x => x == '\n') + 1;
|
||||
return (Key: key, Attrs: attrs, Variable: variable, Line: line);
|
||||
}).ToArray();
|
||||
foreach (var (key, attrs, variable, line) in scriptTranslations)
|
||||
|
||||
foreach (var (key, attrs, variable, line) in references)
|
||||
{
|
||||
var context = $"Script {script}:{line}";
|
||||
usedKeys.Add(key, new TranslationReferenceAttribute(attrs), context);
|
||||
usedKeys.Add(key, new FluentReferenceAttribute(attrs), context);
|
||||
|
||||
if (variable != "")
|
||||
{
|
||||
@@ -239,22 +240,22 @@ namespace OpenRA.Mods.Common.Lint
|
||||
return usedKeys;
|
||||
}
|
||||
|
||||
static (TranslationKeys UsedKeys, List<FieldInfo> TestedFields) GetUsedTranslationKeysInMod(ModData modData)
|
||||
static (Keys UsedKeys, List<FieldInfo> TestedFields) GetUsedFluentKeysInMod(ModData modData)
|
||||
{
|
||||
var usedKeys = GetUsedTranslationKeysInRuleset(modData.DefaultRules);
|
||||
var usedKeys = GetUsedFluentKeysInRuleset(modData.DefaultRules);
|
||||
var testedFields = new List<FieldInfo>();
|
||||
testedFields.AddRange(
|
||||
modData.ObjectCreator.GetTypes()
|
||||
.Where(t => t.IsSubclassOf(typeof(TraitInfo)) || t.IsSubclassOf(typeof(Warhead)))
|
||||
.SelectMany(t => t.GetFields().Where(f => f.HasAttribute<TranslationReferenceAttribute>())));
|
||||
.SelectMany(t => t.GetFields().Where(f => f.HasAttribute<FluentReferenceAttribute>())));
|
||||
|
||||
// HACK: Need to hardcode the custom loader for GameSpeeds.
|
||||
var gameSpeeds = modData.Manifest.Get<GameSpeeds>();
|
||||
var gameSpeedNameField = typeof(GameSpeed).GetField(nameof(GameSpeed.Name));
|
||||
var gameSpeedTranslationReference = Utility.GetCustomAttributes<TranslationReferenceAttribute>(gameSpeedNameField, true)[0];
|
||||
var gameSpeedFluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(gameSpeedNameField, true)[0];
|
||||
testedFields.Add(gameSpeedNameField);
|
||||
foreach (var speed in gameSpeeds.Speeds.Values)
|
||||
usedKeys.Add(speed.Name, gameSpeedTranslationReference, $"`{nameof(GameSpeed)}.{nameof(GameSpeed.Name)}`");
|
||||
usedKeys.Add(speed.Name, gameSpeedFluentReference, $"`{nameof(GameSpeed)}.{nameof(GameSpeed.Name)}`");
|
||||
|
||||
// TODO: linter does not work with LoadUsing
|
||||
foreach (var actorInfo in modData.DefaultRules.Actors)
|
||||
@@ -262,12 +263,12 @@ namespace OpenRA.Mods.Common.Lint
|
||||
foreach (var info in actorInfo.Value.TraitInfos<ResourceRendererInfo>())
|
||||
{
|
||||
var resourceTypeNameField = typeof(ResourceRendererInfo.ResourceTypeInfo).GetField(nameof(ResourceRendererInfo.ResourceTypeInfo.Name));
|
||||
var resourceTypeTranslationReference = Utility.GetCustomAttributes<TranslationReferenceAttribute>(resourceTypeNameField, true)[0];
|
||||
var resourceTypeFluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(resourceTypeNameField, true)[0];
|
||||
testedFields.Add(resourceTypeNameField);
|
||||
foreach (var resourceTypes in info.ResourceTypes)
|
||||
usedKeys.Add(
|
||||
resourceTypes.Value.Name,
|
||||
resourceTypeTranslationReference,
|
||||
resourceTypeFluentReference,
|
||||
$"`{nameof(ResourceRendererInfo.ResourceTypeInfo)}.{nameof(ResourceRendererInfo.ResourceTypeInfo.Name)}`");
|
||||
}
|
||||
}
|
||||
@@ -281,47 +282,48 @@ namespace OpenRA.Mods.Common.Lint
|
||||
if (!field.IsLiteral)
|
||||
continue;
|
||||
|
||||
var translationReference = Utility.GetCustomAttributes<TranslationReferenceAttribute>(field, true).SingleOrDefault();
|
||||
if (translationReference == null)
|
||||
var fluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(field, true).SingleOrDefault();
|
||||
if (fluentReference == null)
|
||||
continue;
|
||||
|
||||
testedFields.Add(field);
|
||||
var keys = LintExts.GetFieldValues(null, field, translationReference.DictionaryReference);
|
||||
var keys = LintExts.GetFieldValues(null, field, fluentReference.DictionaryReference);
|
||||
foreach (var key in keys)
|
||||
usedKeys.Add(key, translationReference, $"`{field.ReflectedType.Name}.{field.Name}`");
|
||||
usedKeys.Add(key, fluentReference, $"`{field.ReflectedType.Name}.{field.Name}`");
|
||||
}
|
||||
}
|
||||
|
||||
return (usedKeys, testedFields);
|
||||
}
|
||||
|
||||
static void CheckModWidgets(ModData modData, TranslationKeys usedKeys, List<FieldInfo> testedFields)
|
||||
static void CheckModWidgets(ModData modData, Keys usedKeys, List<FieldInfo> testedFields)
|
||||
{
|
||||
var chromeLayoutNodes = BuildChromeTree(modData);
|
||||
|
||||
var widgetTypes = modData.ObjectCreator.GetTypes()
|
||||
.Where(t => t.Name.EndsWith("Widget", StringComparison.InvariantCulture) && t.IsSubclassOf(typeof(Widget)))
|
||||
.ToList();
|
||||
var translationReferencesByWidgetField = widgetTypes.SelectMany(t =>
|
||||
|
||||
var fluentReferencesByWidgetField = widgetTypes.SelectMany(t =>
|
||||
{
|
||||
var widgetName = t.Name[..^6];
|
||||
return Utility.GetFields(t)
|
||||
.Select(f =>
|
||||
{
|
||||
var attribute = Utility.GetCustomAttributes<TranslationReferenceAttribute>(f, true).SingleOrDefault();
|
||||
return (WidgetName: widgetName, FieldName: f.Name, TranslationReference: attribute);
|
||||
var attribute = Utility.GetCustomAttributes<FluentReferenceAttribute>(f, true).SingleOrDefault();
|
||||
return (WidgetName: widgetName, FieldName: f.Name, FluentReference: attribute);
|
||||
})
|
||||
.Where(x => x.TranslationReference != null);
|
||||
.Where(x => x.FluentReference != null);
|
||||
})
|
||||
.ToDictionary(
|
||||
x => (x.WidgetName, x.FieldName),
|
||||
x => x.TranslationReference);
|
||||
x => x.FluentReference);
|
||||
|
||||
testedFields.AddRange(widgetTypes.SelectMany(
|
||||
t => Utility.GetFields(t).Where(Utility.HasAttribute<TranslationReferenceAttribute>)));
|
||||
t => Utility.GetFields(t).Where(Utility.HasAttribute<FluentReferenceAttribute>)));
|
||||
|
||||
foreach (var node in chromeLayoutNodes)
|
||||
CheckChrome(node, translationReferencesByWidgetField, usedKeys);
|
||||
CheckChrome(node, fluentReferencesByWidgetField, usedKeys);
|
||||
}
|
||||
|
||||
static MiniYamlNode[] BuildChromeTree(ModData modData)
|
||||
@@ -336,38 +338,38 @@ namespace OpenRA.Mods.Common.Lint
|
||||
|
||||
static void CheckChrome(
|
||||
MiniYamlNode rootNode,
|
||||
Dictionary<(string WidgetName, string FieldName), TranslationReferenceAttribute> translationReferencesByWidgetField,
|
||||
TranslationKeys usedKeys)
|
||||
Dictionary<(string WidgetName, string FieldName), FluentReferenceAttribute> fluentReferencesByWidgetField,
|
||||
Keys usedKeys)
|
||||
{
|
||||
var nodeType = rootNode.Key.Split('@')[0];
|
||||
foreach (var childNode in rootNode.Value.Nodes)
|
||||
{
|
||||
var childType = childNode.Key.Split('@')[0];
|
||||
if (!translationReferencesByWidgetField.TryGetValue((nodeType, childType), out var translationReference))
|
||||
if (!fluentReferencesByWidgetField.TryGetValue((nodeType, childType), out var reference))
|
||||
continue;
|
||||
|
||||
var key = childNode.Value.Value;
|
||||
usedKeys.Add(key, translationReference, $"Widget `{rootNode.Key}` field `{childType}` in {rootNode.Location}");
|
||||
usedKeys.Add(key, reference, $"Widget `{rootNode.Key}` field `{childType}` in {rootNode.Location}");
|
||||
}
|
||||
|
||||
foreach (var childNode in rootNode.Value.Nodes)
|
||||
if (childNode.Key == "Children")
|
||||
foreach (var n in childNode.Value.Nodes)
|
||||
CheckChrome(n, translationReferencesByWidgetField, usedKeys);
|
||||
CheckChrome(n, fluentReferencesByWidgetField, usedKeys);
|
||||
}
|
||||
|
||||
static HashSet<string> CheckKeys(
|
||||
IEnumerable<string> translationFiles, Func<string, Stream> openFile, TranslationKeys usedKeys,
|
||||
IEnumerable<string> paths, Func<string, Stream> openFile, Keys usedKeys,
|
||||
string language, Func<string, bool> checkUnusedKeysForFile,
|
||||
Action<string> emitError, Action<string> emitWarning)
|
||||
{
|
||||
var keyWithAttrs = new HashSet<string>();
|
||||
foreach (var file in translationFiles)
|
||||
foreach (var path in paths)
|
||||
{
|
||||
if (!file.EndsWith($"{language}.ftl", StringComparison.Ordinal))
|
||||
if (!path.EndsWith($"{language}.ftl", StringComparison.Ordinal))
|
||||
continue;
|
||||
|
||||
var stream = openFile(file);
|
||||
var stream = openFile(path);
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
var parser = new LinguiniParser(reader);
|
||||
@@ -388,9 +390,9 @@ namespace OpenRA.Mods.Common.Lint
|
||||
foreach (var (node, attributeName) in nodeAndAttributeNames)
|
||||
{
|
||||
keyWithAttrs.Add(attributeName == null ? key : $"{key}.{attributeName}");
|
||||
if (checkUnusedKeysForFile(file))
|
||||
CheckUnusedKey(key, attributeName, file, usedKeys, emitWarning);
|
||||
CheckVariables(node, key, attributeName, file, usedKeys, emitError, emitWarning);
|
||||
if (checkUnusedKeysForFile(path))
|
||||
CheckUnusedKey(key, attributeName, path, usedKeys, emitWarning);
|
||||
CheckVariables(node, key, attributeName, path, usedKeys, emitError, emitWarning);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,7 +400,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
|
||||
return keyWithAttrs;
|
||||
|
||||
static void CheckUnusedKey(string key, string attribute, string file, TranslationKeys usedKeys, Action<string> emitWarning)
|
||||
static void CheckUnusedKey(string key, string attribute, string file, Keys usedKeys, Action<string> emitWarning)
|
||||
{
|
||||
var isAttribute = !string.IsNullOrEmpty(attribute);
|
||||
var keyWithAtrr = isAttribute ? $"{key}.{attribute}" : key;
|
||||
@@ -410,7 +412,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
}
|
||||
|
||||
static void CheckVariables(
|
||||
Pattern node, string key, string attribute, string file, TranslationKeys usedKeys,
|
||||
Pattern node, string key, string attribute, string file, Keys usedKeys,
|
||||
Action<string> emitError, Action<string> emitWarning)
|
||||
{
|
||||
var isAttribute = !string.IsNullOrEmpty(attribute);
|
||||
@@ -456,26 +458,26 @@ namespace OpenRA.Mods.Common.Lint
|
||||
}
|
||||
}
|
||||
|
||||
class TranslationKeys
|
||||
class Keys
|
||||
{
|
||||
readonly HashSet<string> keys = new();
|
||||
readonly List<(string Key, string Context)> keysWithContext = new();
|
||||
readonly Dictionary<string, HashSet<string>> requiredVariablesByKey = new();
|
||||
readonly List<string> contextForEmptyKeys = new();
|
||||
|
||||
public void Add(string key, TranslationReferenceAttribute translationReference, string context)
|
||||
public void Add(string key, FluentReferenceAttribute fluentReference, string context)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
if (!translationReference.Optional)
|
||||
if (!fluentReference.Optional)
|
||||
contextForEmptyKeys.Add(context);
|
||||
return;
|
||||
}
|
||||
|
||||
if (translationReference.RequiredVariableNames != null && translationReference.RequiredVariableNames.Length > 0)
|
||||
if (fluentReference.RequiredVariableNames != null && fluentReference.RequiredVariableNames.Length > 0)
|
||||
{
|
||||
var rv = requiredVariablesByKey.GetOrAdd(key, _ => new HashSet<string>());
|
||||
rv.UnionWith(translationReference.RequiredVariableNames);
|
||||
rv.UnionWith(fluentReference.RequiredVariableNames);
|
||||
}
|
||||
|
||||
keys.Add(key);
|
||||
@@ -18,7 +18,7 @@ using OpenRA.FileSystem;
|
||||
|
||||
namespace OpenRA.Mods.Common.Lint
|
||||
{
|
||||
sealed class CheckTranslationSyntax : ILintPass, ILintMapPass
|
||||
sealed class CheckFluentSyntax : ILintPass, ILintMapPass
|
||||
{
|
||||
void ILintMapPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Map map)
|
||||
{
|
||||
@@ -33,11 +33,11 @@ namespace OpenRA.Mods.Common.Lint
|
||||
Run(emitError, emitWarning, modData.DefaultFileSystem, modData.Manifest.Translations);
|
||||
}
|
||||
|
||||
static void Run(Action<string> emitError, Action<string> emitWarning, IReadOnlyFileSystem fileSystem, string[] translations)
|
||||
static void Run(Action<string> emitError, Action<string> emitWarning, IReadOnlyFileSystem fileSystem, string[] paths)
|
||||
{
|
||||
foreach (var file in translations)
|
||||
foreach (var path in paths)
|
||||
{
|
||||
var stream = fileSystem.Open(file);
|
||||
var stream = fileSystem.Open(path);
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
var ids = new List<string>();
|
||||
@@ -46,12 +46,12 @@ namespace OpenRA.Mods.Common.Lint
|
||||
foreach (var entry in resource.Entries)
|
||||
{
|
||||
if (entry is Junk junk)
|
||||
emitError($"{junk.GetId()}: {junk.AsStr()} in {file} {junk.Content}.");
|
||||
emitError($"{junk.GetId()}: {junk.AsStr()} in {path} {junk.Content}.");
|
||||
|
||||
if (entry is AstMessage message)
|
||||
{
|
||||
if (ids.Contains(message.Id.Name.ToString()))
|
||||
emitWarning($"Duplicate ID `{message.Id.Name}` in {file}.");
|
||||
emitWarning($"Duplicate ID `{message.Id.Name}` in {path}.");
|
||||
|
||||
ids.Add(message.Id.Name.ToString());
|
||||
}
|
||||
@@ -34,9 +34,9 @@ namespace OpenRA.Mods.Common.Scripting.Global
|
||||
luaLabel.GetColor = () => c;
|
||||
}
|
||||
|
||||
[Desc("Translates text into the users language. The translation key must be added to the language files (*.ftl). " +
|
||||
[Desc("Formats a language string for a given string key defined in the language files (*.ftl). " +
|
||||
"Args can be passed to be substituted into the resulting message.")]
|
||||
public string Translate(string translationKey, [ScriptEmmyTypeOverride("{ string: any }")] LuaTable args = null)
|
||||
public string Translate(string key, [ScriptEmmyTypeOverride("{ string: any }")] LuaTable args = null)
|
||||
{
|
||||
if (args != null)
|
||||
{
|
||||
@@ -48,17 +48,17 @@ namespace OpenRA.Mods.Common.Scripting.Global
|
||||
{
|
||||
if (!kv.Key.TryGetClrValue<string>(out var variable) || !kv.Value.TryGetClrValue<object>(out var value))
|
||||
throw new LuaException(
|
||||
"Translation arguments requires a table of [\"string\"]=value pairs. " +
|
||||
"String arguments requires a table of [\"string\"]=value pairs. " +
|
||||
$"Received {kv.Key.WrappedClrType().Name},{kv.Value.WrappedClrType().Name}");
|
||||
|
||||
argumentDictionary.Add(variable, value);
|
||||
}
|
||||
}
|
||||
|
||||
return TranslationProvider.GetString(translationKey, argumentDictionary);
|
||||
return FluentProvider.GetString(key, argumentDictionary);
|
||||
}
|
||||
|
||||
return TranslationProvider.GetString(translationKey);
|
||||
return FluentProvider.GetString(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ namespace OpenRA.Mods.Common.Scripting
|
||||
if (tooltip == null)
|
||||
return null;
|
||||
|
||||
return TranslationProvider.GetString(tooltip.Info.Name);
|
||||
return FluentProvider.GetString(tooltip.Info.Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,142 +27,142 @@ namespace OpenRA.Mods.Common.Server
|
||||
{
|
||||
public class LobbyCommands : ServerTrait, IInterpretCommand, INotifyServerStart, INotifyServerEmpty, IClientJoined, OpenRA.Server.ITick
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string CustomRules = "notification-custom-rules";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string OnlyHostStartGame = "notification-admin-start-game";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string NoStartUntilRequiredSlotsFull = "notification-no-start-until-required-slots-full";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string NoStartWithoutPlayers = "notification-no-start-without-players";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string TwoHumansRequired = "notification-two-humans-required";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string InsufficientEnabledSpawnPoints = "notification-insufficient-enabled-spawn-points";
|
||||
|
||||
[TranslationReference("command")]
|
||||
[FluentReference("command")]
|
||||
const string MalformedCommand = "notification-malformed-command";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string KickNone = "notification-kick-none";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string NoKickSelf = "notification-kick-self";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string NoKickGameStarted = "notification-no-kick-game-started";
|
||||
|
||||
[TranslationReference("admin", "player")]
|
||||
[FluentReference("admin", "player")]
|
||||
const string AdminKicked = "notification-admin-kicked";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string Kicked = "notification-kicked";
|
||||
|
||||
[TranslationReference("admin", "player")]
|
||||
[FluentReference("admin", "player")]
|
||||
const string TempBan = "notification-temp-ban";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string NoTransferAdmin = "notification-admin-transfer-admin";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string EmptySlot = "notification-empty-slot";
|
||||
|
||||
[TranslationReference("admin", "player")]
|
||||
[FluentReference("admin", "player")]
|
||||
const string MoveSpectators = "notification-move-spectators";
|
||||
|
||||
[TranslationReference("player", "name")]
|
||||
[FluentReference("player", "name")]
|
||||
const string Nick = "notification-nick-changed";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string StateUnchangedReady = "notification-state-unchanged-ready";
|
||||
|
||||
[TranslationReference("command")]
|
||||
[FluentReference("command")]
|
||||
const string StateUnchangedGameStarted = "notification-state-unchanged-game-started";
|
||||
|
||||
[TranslationReference("faction")]
|
||||
[FluentReference("faction")]
|
||||
const string InvalidFactionSelected = "notification-invalid-faction-selected";
|
||||
|
||||
[TranslationReference("factions")]
|
||||
[FluentReference("factions")]
|
||||
const string SupportedFactions = "notification-supported-factions";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string RequiresHost = "notification-requires-host";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string InvalidBotSlot = "notification-invalid-bot-slot";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string InvalidBotType = "notification-invalid-bot-type";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string HostChangeMap = "notification-admin-change-map";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string UnknownMap = "notification-unknown-map";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string SearchingMap = "notification-searching-map";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string NotAdmin = "notification-admin-change-configuration";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string InvalidConfigurationCommand = "notification-invalid-configuration-command";
|
||||
|
||||
[TranslationReference("option")]
|
||||
[FluentReference("option")]
|
||||
const string OptionLocked = "notification-option-locked";
|
||||
|
||||
[TranslationReference("player", "map")]
|
||||
[FluentReference("player", "map")]
|
||||
const string ChangedMap = "notification-changed-map";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string MapBotsDisabled = "notification-map-bots-disabled";
|
||||
|
||||
[TranslationReference("player", "name", "value")]
|
||||
[FluentReference("player", "name", "value")]
|
||||
const string ValueChanged = "notification-option-changed";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string NoMoveSpectators = "notification-admin-move-spectators";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string AdminOption = "notification-admin-option";
|
||||
|
||||
[TranslationReference("raw")]
|
||||
[FluentReference("raw")]
|
||||
const string NumberTeams = "notification-error-number-teams";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string AdminClearSpawn = "notification-admin-clear-spawn";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string SpawnOccupied = "notification-spawn-occupied";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string SpawnLocked = "notification-spawn-locked";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string AdminLobbyInfo = "notification-admin-lobby-info";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string InvalidLobbyInfo = "notification-invalid-lobby-info";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string AdminKick = "notification-admin-kick";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string SlotClosed = "notification-slot-closed";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string NewAdmin = "notification-new-admin";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string YouWereKicked = "notification-you-were-kicked";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string VoteKickDisabled = "notification-vote-kick-disabled";
|
||||
|
||||
readonly IDictionary<string, Func<S, Connection, Session.Client, string, bool>> commandHandlers =
|
||||
@@ -224,7 +224,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
|
||||
if (server.State == ServerState.GameStarted)
|
||||
{
|
||||
server.SendLocalizedMessageTo(conn, StateUnchangedGameStarted, Translation.Arguments("command", command));
|
||||
server.SendLocalizedMessageTo(conn, StateUnchangedGameStarted, FluentBundle.Arguments("command", command));
|
||||
return false;
|
||||
}
|
||||
else if (client.State == Session.ClientState.Ready && !(command.StartsWith("state", StringComparison.Ordinal) || command == "startgame"))
|
||||
@@ -303,7 +303,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
{
|
||||
if (!Enum<Session.ClientState>.TryParse(s, false, out var state))
|
||||
{
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "state"));
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "state"));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -399,7 +399,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
return true;
|
||||
}
|
||||
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "allow_spectate"));
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "allow_spectate"));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -488,7 +488,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
var parts = s.Split(' ');
|
||||
if (parts.Length < 3)
|
||||
{
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "slot_bot"));
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "slot_bot"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -652,7 +652,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
|
||||
server.SyncLobbyInfo();
|
||||
|
||||
server.SendLocalizedMessage(ChangedMap, Translation.Arguments("player", client.Name, "map", server.Map.Title));
|
||||
server.SendLocalizedMessage(ChangedMap, FluentBundle.Arguments("player", client.Name, "map", server.Map.Title));
|
||||
|
||||
if ((server.LobbyInfo.GlobalSettings.MapStatus & Session.MapStatus.UnsafeCustomRules) != 0)
|
||||
server.SendLocalizedMessage(CustomRules);
|
||||
@@ -722,7 +722,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
|
||||
if (option.IsLocked)
|
||||
{
|
||||
server.SendLocalizedMessageTo(conn, OptionLocked, Translation.Arguments("option", option.Name));
|
||||
server.SendLocalizedMessageTo(conn, OptionLocked, FluentBundle.Arguments("option", option.Name));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -739,7 +739,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
oo.Value = oo.PreferredValue = split[1];
|
||||
|
||||
server.SyncLobbyGlobalSettings();
|
||||
server.SendLocalizedMessage(ValueChanged, Translation.Arguments("player", client.Name, "name", option.Name, "value", option.Label(split[1])));
|
||||
server.SendLocalizedMessage(ValueChanged, FluentBundle.Arguments("player", client.Name, "name", option.Name, "value", option.Label(split[1])));
|
||||
|
||||
foreach (var c in server.LobbyInfo.Clients)
|
||||
c.State = Session.ClientState.NotReady;
|
||||
@@ -768,7 +768,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
foreach (var o in allOptions)
|
||||
{
|
||||
if (o.DefaultValue != server.LobbyInfo.GlobalSettings.LobbyOptions[o.Id].Value)
|
||||
server.SendLocalizedMessage(ValueChanged, Translation.Arguments(
|
||||
server.SendLocalizedMessage(ValueChanged, FluentBundle.Arguments(
|
||||
"player", client.Name,
|
||||
"name", o.Name,
|
||||
"value", o.Label(o.DefaultValue)));
|
||||
@@ -805,7 +805,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
|
||||
if (!Exts.TryParseInt32Invariant(raw, out var teamCount))
|
||||
{
|
||||
server.SendLocalizedMessageTo(conn, NumberTeams, Translation.Arguments("raw", raw));
|
||||
server.SendLocalizedMessageTo(conn, NumberTeams, FluentBundle.Arguments("raw", raw));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -850,7 +850,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
var split = s.Split(' ');
|
||||
if (split.Length < 2)
|
||||
{
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "kick"));
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "kick"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -877,14 +877,14 @@ namespace OpenRA.Mods.Common.Server
|
||||
}
|
||||
|
||||
Log.Write("server", $"Kicking client {kickClientID}.");
|
||||
server.SendLocalizedMessage(AdminKicked, Translation.Arguments("admin", client.Name, "player", kickClient.Name));
|
||||
server.SendLocalizedMessage(AdminKicked, FluentBundle.Arguments("admin", client.Name, "player", kickClient.Name));
|
||||
server.SendOrderTo(kickConn, "ServerError", YouWereKicked);
|
||||
server.DropClient(kickConn);
|
||||
|
||||
if (bool.TryParse(split[1], out var tempBan) && tempBan)
|
||||
{
|
||||
Log.Write("server", $"Temporarily banning client {kickClientID} ({kickClient.IPAddress}).");
|
||||
server.SendLocalizedMessage(TempBan, Translation.Arguments("admin", client.Name, "player", kickClient.Name));
|
||||
server.SendLocalizedMessage(TempBan, FluentBundle.Arguments("admin", client.Name, "player", kickClient.Name));
|
||||
server.TempBans.Add(kickClient.IPAddress);
|
||||
}
|
||||
|
||||
@@ -902,7 +902,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
var split = s.Split(' ');
|
||||
if (split.Length != 2)
|
||||
{
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "vote_kick"));
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "vote_kick"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -930,14 +930,14 @@ namespace OpenRA.Mods.Common.Server
|
||||
|
||||
if (!bool.TryParse(split[1], out var vote))
|
||||
{
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, Translation.Arguments("command", "vote_kick"));
|
||||
server.SendLocalizedMessageTo(conn, MalformedCommand, FluentBundle.Arguments("command", "vote_kick"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (server.VoteKickTracker.VoteKick(conn, client, kickConn, kickClient, kickClientID, vote))
|
||||
{
|
||||
Log.Write("server", $"Kicking client {kickClientID}.");
|
||||
server.SendLocalizedMessage(Kicked, Translation.Arguments("player", kickClient.Name));
|
||||
server.SendLocalizedMessage(Kicked, FluentBundle.Arguments("player", kickClient.Name));
|
||||
server.SendOrderTo(kickConn, "ServerError", YouWereKicked);
|
||||
server.DropClient(kickConn);
|
||||
|
||||
@@ -980,7 +980,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
foreach (var b in bots)
|
||||
b.BotControllerClientIndex = newAdminId;
|
||||
|
||||
server.SendLocalizedMessage(NewAdmin, Translation.Arguments("player", newAdminClient.Name));
|
||||
server.SendLocalizedMessage(NewAdmin, FluentBundle.Arguments("player", newAdminClient.Name));
|
||||
Log.Write("server", $"{newAdminClient.Name} is now the admin.");
|
||||
server.SyncLobbyClients();
|
||||
|
||||
@@ -1014,7 +1014,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
targetClient.Handicap = 0;
|
||||
targetClient.Color = Color.White;
|
||||
targetClient.State = Session.ClientState.NotReady;
|
||||
server.SendLocalizedMessage(MoveSpectators, Translation.Arguments("admin", client.Name, "player", targetClient.Name));
|
||||
server.SendLocalizedMessage(MoveSpectators, FluentBundle.Arguments("admin", client.Name, "player", targetClient.Name));
|
||||
Log.Write("server", $"{client.Name} moved {targetClient.Name} to spectators.");
|
||||
server.SyncLobbyClients();
|
||||
CheckAutoStart(server);
|
||||
@@ -1032,7 +1032,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
return true;
|
||||
|
||||
Log.Write("server", $"Player@{conn.EndPoint} is now known as {sanitizedName}.");
|
||||
server.SendLocalizedMessage(Nick, Translation.Arguments("player", client.Name, "name", sanitizedName));
|
||||
server.SendLocalizedMessage(Nick, FluentBundle.Arguments("player", client.Name, "name", sanitizedName));
|
||||
client.Name = sanitizedName;
|
||||
server.SyncLobbyClients();
|
||||
|
||||
@@ -1062,8 +1062,8 @@ namespace OpenRA.Mods.Common.Server
|
||||
var faction = parts[1];
|
||||
if (!factions.Contains(faction))
|
||||
{
|
||||
server.SendLocalizedMessageTo(conn, InvalidFactionSelected, Translation.Arguments("faction", faction));
|
||||
server.SendLocalizedMessageTo(conn, SupportedFactions, Translation.Arguments("factions", factions.JoinWith(", ")));
|
||||
server.SendLocalizedMessageTo(conn, InvalidFactionSelected, FluentBundle.Arguments("faction", faction));
|
||||
server.SendLocalizedMessageTo(conn, SupportedFactions, FluentBundle.Arguments("factions", factions.JoinWith(", ")));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,22 +30,22 @@ namespace OpenRA.Mods.Common.Server
|
||||
// 1 second (in milliseconds) minimum delay between pings
|
||||
const int RateLimitInterval = 1000;
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string NoPortForward = "notification-no-port-forward";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string BlacklistedTitle = "notification-blacklisted-server-name";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string InvalidErrorCode = "notification-invalid-error-code";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string Connected = "notification-master-server-connected";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string Error = "notification-master-server-error";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string GameOffline = "notification-game-offline";
|
||||
|
||||
static readonly Beacon LanGameBeacon;
|
||||
|
||||
@@ -18,16 +18,16 @@ namespace OpenRA.Mods.Common.Server
|
||||
{
|
||||
public class PlayerPinger : ServerTrait, ITick
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string PlayerDropped = "notification-player-dropped";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string ConnectionProblems = "notification-connection-problems";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string Timeout = "notification-timeout-dropped";
|
||||
|
||||
[TranslationReference("player", "timeout")]
|
||||
[FluentReference("player", "timeout")]
|
||||
const string TimeoutIn = "notification-timeout-dropped-in";
|
||||
|
||||
const int PingInterval = 5000; // Ping every 5 seconds
|
||||
@@ -69,13 +69,13 @@ namespace OpenRA.Mods.Common.Server
|
||||
{
|
||||
if (!c.TimeoutMessageShown && c.TimeSinceLastResponse > PingInterval * 2)
|
||||
{
|
||||
server.SendLocalizedMessage(ConnectionProblems, Translation.Arguments("player", client.Name));
|
||||
server.SendLocalizedMessage(ConnectionProblems, FluentBundle.Arguments("player", client.Name));
|
||||
c.TimeoutMessageShown = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
server.SendLocalizedMessage(Timeout, Translation.Arguments("player", client.Name));
|
||||
server.SendLocalizedMessage(Timeout, FluentBundle.Arguments("player", client.Name));
|
||||
server.DropClient(c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public readonly int BuildPaletteOrder = 9999;
|
||||
|
||||
[Desc("Text shown in the production tooltip.")]
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string Description;
|
||||
|
||||
public static string GetInitialFaction(ActorInfo ai, string defaultFaction)
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play when selecting a primary building.")]
|
||||
public readonly string SelectionNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display when selecting a primary building.")]
|
||||
public readonly string SelectionTextNotification = null;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play when a unit is delivered.")]
|
||||
public readonly string ReadyAudio = "Reinforce";
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display when a unit is delivered.")]
|
||||
public readonly string ReadyTextNotification = null;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play when setting a new rallypoint.")]
|
||||
public readonly string Notification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display when setting a new rallypoint.")]
|
||||
public readonly string TextNotification = null;
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Voice line to play when repairs are started.")]
|
||||
public readonly string RepairingNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Transient text message to display when repairs are started.")]
|
||||
public readonly string RepairingTextNotification = null;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string EnabledSpeech = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string EnabledTextNotification = null;
|
||||
|
||||
[NotificationReference("Sounds")]
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string DisabledSpeech = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string DisabledTextNotification = null;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new ToggleConditionOnOrder(this); }
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play when the crate is collected.")]
|
||||
public readonly string Notification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display when the crate is collected.")]
|
||||
public readonly string TextNotification = null;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class EncyclopediaInfo : TraitInfo
|
||||
{
|
||||
[Desc("Explains the purpose in the in-game encyclopedia.")]
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
public readonly string Description;
|
||||
|
||||
[Desc("Number for ordering the list.")]
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[NotificationReference("Sounds")]
|
||||
public readonly string LevelUpNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string LevelUpTextNotification = null;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new GainsExperience(init, this); }
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification type to play.")]
|
||||
public readonly string Notification = "BaseAttack";
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display.")]
|
||||
public readonly string TextNotification = null;
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"Won't play a notification to allies if this is null.")]
|
||||
public readonly string AllyNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display to allies when under attack.")]
|
||||
public readonly string AllyTextNotification = null;
|
||||
|
||||
|
||||
@@ -32,10 +32,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public class ConquestVictoryConditions : ITick, INotifyWinStateChanged, INotifyTimeLimit
|
||||
{
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string PlayerIsVictorious = "notification-player-is-victorious";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string PlayerIsDefeated = "notification-player-is-defeated";
|
||||
|
||||
readonly ConquestVictoryConditionsInfo info;
|
||||
@@ -105,7 +105,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (info.SuppressNotifications)
|
||||
return;
|
||||
|
||||
TextNotificationsManager.AddSystemLine(PlayerIsDefeated, Translation.Arguments("player", player.ResolvedPlayerName));
|
||||
TextNotificationsManager.AddSystemLine(PlayerIsDefeated, FluentBundle.Arguments("player", player.ResolvedPlayerName));
|
||||
Game.RunAfterDelay(info.NotificationDelay, () =>
|
||||
{
|
||||
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
|
||||
@@ -121,7 +121,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (info.SuppressNotifications)
|
||||
return;
|
||||
|
||||
TextNotificationsManager.AddSystemLine(PlayerIsVictorious, Translation.Arguments("player", player.ResolvedPlayerName));
|
||||
TextNotificationsManager.AddSystemLine(PlayerIsVictorious, FluentBundle.Arguments("player", player.ResolvedPlayerName));
|
||||
Game.RunAfterDelay(info.NotificationDelay, () =>
|
||||
{
|
||||
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
|
||||
|
||||
@@ -20,11 +20,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Attach this to the player actor.")]
|
||||
public class DeveloperModeInfo : TraitInfo, ILobbyOptions
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Descriptive label for the developer mode checkbox in the lobby.")]
|
||||
public readonly string CheckboxLabel = "checkbox-debug-menu.label";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the developer mode checkbox in the lobby.")]
|
||||
public readonly string CheckboxDescription = "checkbox-debug-menu.description";
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public class DeveloperMode : IResolveOrder, ISync, INotifyCreated, IUnlocksRenderPlayer
|
||||
{
|
||||
[TranslationReference("cheat", "player", "suffix")]
|
||||
[FluentReference("cheat", "player", "suffix")]
|
||||
const string CheatUsed = "notification-cheat-used";
|
||||
|
||||
readonly DeveloperModeInfo info;
|
||||
@@ -275,8 +275,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return;
|
||||
}
|
||||
|
||||
var arguments = Translation.Arguments("cheat", order.OrderString, "player", self.Owner.ResolvedPlayerName, "suffix", debugSuffix);
|
||||
TextNotificationsManager.Debug(TranslationProvider.GetString(CheatUsed, arguments));
|
||||
var arguments = FluentBundle.Arguments("cheat", order.OrderString, "player", self.Owner.ResolvedPlayerName, "suffix", debugSuffix);
|
||||
TextNotificationsManager.Debug(FluentProvider.GetString(CheatUsed, arguments));
|
||||
}
|
||||
|
||||
bool IUnlocksRenderPlayer.RenderPlayerUnlocked => Enabled;
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification type to play.")]
|
||||
public readonly string Notification = "HarvesterAttack";
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display.")]
|
||||
public readonly string TextNotification = null;
|
||||
|
||||
|
||||
@@ -22,12 +22,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Internal id for this checkbox.")]
|
||||
public readonly string ID = null;
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[FieldLoader.Require]
|
||||
[Desc("Display name for this checkbox.")]
|
||||
public readonly string Label = null;
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Description name for this checkbox.")]
|
||||
public readonly string Description = null;
|
||||
|
||||
|
||||
@@ -54,19 +54,19 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string WinNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string WinTextNotification = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string LoseNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string LoseTextNotification = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string LeaveNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string LeaveTextNotification = null;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new MissionObjectives(init.Self.Owner, this); }
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Internal id for this bot.")]
|
||||
public readonly string Type = null;
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Human-readable name this bot uses.")]
|
||||
public readonly string Name = null;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play after building placement if new construction options are available.")]
|
||||
public readonly string NewOptionsNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display after building placement if new construction options are available.")]
|
||||
public readonly string NewOptionsTextNotification = null;
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play if building placement is not possible.")]
|
||||
public readonly string CannotPlaceNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display if building placement is not possible.")]
|
||||
public readonly string CannotPlaceTextNotification = null;
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play when the player does not have any funds.")]
|
||||
public readonly string InsufficientFundsNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display when the player does not have any funds.")]
|
||||
public readonly string InsufficientFundsTextNotification = null;
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string ReadyAudio = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Notification displayed when production is complete.")]
|
||||
public readonly string ReadyTextNotification = null;
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string BlockedAudio = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Notification displayed when you can't train another actor",
|
||||
"when the build limit exceeded or the exit is jammed.")]
|
||||
public readonly string BlockedTextNotification = null;
|
||||
@@ -85,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string LimitedAudio = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Notification displayed when you can't queue another actor",
|
||||
"when the queue length limit is exceeded.")]
|
||||
public readonly string LimitedTextNotification = null;
|
||||
@@ -101,7 +101,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string QueuedAudio = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Notification displayed when user clicks on the build palette icon.")]
|
||||
public readonly string QueuedTextNotification = null;
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string OnHoldAudio = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Notification displayed when player right-clicks on the build palette icon.")]
|
||||
public readonly string OnHoldTextNotification = null;
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string CancelledAudio = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Notification displayed when player right-clicks on a build palette icon that is already on hold.")]
|
||||
public readonly string CancelledTextNotification = null;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Internal id for this tech level.")]
|
||||
public readonly string Id;
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Name shown in the lobby options.")]
|
||||
public readonly string Name;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech to play for the warning.")]
|
||||
public readonly string Notification = "SilosNeeded";
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text to display for the warning.")]
|
||||
public readonly string TextNotification = null;
|
||||
|
||||
|
||||
@@ -46,10 +46,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public class StrategicVictoryConditions : ITick, ISync, INotifyWinStateChanged, INotifyTimeLimit
|
||||
{
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string PlayerIsVictorious = "notification-player-is-victorious";
|
||||
|
||||
[TranslationReference("player")]
|
||||
[FluentReference("player")]
|
||||
const string PlayerIsDefeated = "notification-player-is-defeated";
|
||||
|
||||
readonly StrategicVictoryConditionsInfo info;
|
||||
@@ -151,7 +151,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (info.SuppressNotifications)
|
||||
return;
|
||||
|
||||
TextNotificationsManager.AddSystemLine(PlayerIsDefeated, Translation.Arguments("player", player.ResolvedPlayerName));
|
||||
TextNotificationsManager.AddSystemLine(PlayerIsDefeated, FluentBundle.Arguments("player", player.ResolvedPlayerName));
|
||||
Game.RunAfterDelay(info.NotificationDelay, () =>
|
||||
{
|
||||
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
|
||||
@@ -167,7 +167,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (info.SuppressNotifications)
|
||||
return;
|
||||
|
||||
TextNotificationsManager.AddSystemLine(PlayerIsVictorious, Translation.Arguments("player", player.ResolvedPlayerName));
|
||||
TextNotificationsManager.AddSystemLine(PlayerIsVictorious, FluentBundle.Arguments("player", player.ResolvedPlayerName));
|
||||
Game.RunAfterDelay(info.NotificationDelay, () =>
|
||||
{
|
||||
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public readonly string SpeechNotification = null;
|
||||
|
||||
[Desc("The text notification to display when the player is low power.")]
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string TextNotification = null;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new PowerManager(init.Self, this); }
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play when dropping the unit.")]
|
||||
public readonly string ReadyAudio = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display when dropping the unit.")]
|
||||
public readonly string ReadyTextNotification = null;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
const string CommandName = "custom-terrain";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string CommandDescription = "description-custom-terrain-debug-overlay";
|
||||
|
||||
public bool Enabled;
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play when a bridge is repaired.")]
|
||||
public readonly string RepairNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display when a bridge is repaired.")]
|
||||
public readonly string RepairTextNotification = null;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification played when starting to repair a unit.")]
|
||||
public readonly string StartRepairingNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification displayed when starting to repair a unit.")]
|
||||
public readonly string StartRepairingTextNotification = null;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification played when repairing a unit is done.")]
|
||||
public readonly string FinishRepairingNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification displayed when repairing a unit is done.")]
|
||||
public readonly string FinishRepairingTextNotification = null;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play.")]
|
||||
public readonly string Notification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display.")]
|
||||
public readonly string TextNotification = null;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
|
||||
public readonly string Notification = "UnitLost";
|
||||
|
||||
[Desc("Text notification to display.")]
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string TextNotification = null;
|
||||
|
||||
public readonly bool NotifyAll = false;
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
|
||||
[Desc("Speech notification to play.")]
|
||||
public readonly string Notification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display.")]
|
||||
public readonly string TextNotification = null;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
|
||||
[Desc("Speech notification to play to the new owner.")]
|
||||
public readonly string Notification = "BuildingCaptured";
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display to the new owner.")]
|
||||
public readonly string TextNotification = null;
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
|
||||
[Desc("Speech notification to play to the old owner.")]
|
||||
public readonly string LoseNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display to the old owner.")]
|
||||
public readonly string LoseTextNotification = null;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play when entering the drop zone.")]
|
||||
public readonly string ReinforcementsArrivedSpeechNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display when entering the drop zone.")]
|
||||
public readonly string ReinforcementsArrivedTextNotification = null;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string ReadyAudio = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification displayed when production is activated.")]
|
||||
public readonly string ReadyTextNotification = null;
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string BlockedAudio = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification displayed when the exit is jammed.")]
|
||||
public readonly string BlockedTextNotification = null;
|
||||
|
||||
|
||||
@@ -30,10 +30,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Palette used for the icon.")]
|
||||
public readonly string IconPalette = "chrome";
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string Name = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string Description = null;
|
||||
|
||||
[Desc("Allow multiple instances of the same support power.")]
|
||||
@@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string DetectedSpeechNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string DetectedTextNotification = null;
|
||||
|
||||
public readonly string BeginChargeSound = null;
|
||||
@@ -69,7 +69,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string BeginChargeSpeechNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string BeginChargeTextNotification = null;
|
||||
|
||||
public readonly string EndChargeSound = null;
|
||||
@@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string EndChargeSpeechNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string EndChargeTextNotification = null;
|
||||
|
||||
public readonly string SelectTargetSound = null;
|
||||
@@ -85,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string SelectTargetSpeechNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string SelectTargetTextNotification = null;
|
||||
|
||||
public readonly string InsufficientPowerSound = null;
|
||||
@@ -93,7 +93,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string InsufficientPowerSpeechNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string InsufficientPowerTextNotification = null;
|
||||
|
||||
public readonly string LaunchSound = null;
|
||||
@@ -101,7 +101,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string LaunchSpeechNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string LaunchTextNotification = null;
|
||||
|
||||
public readonly string IncomingSound = null;
|
||||
@@ -109,7 +109,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string IncomingSpeechNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string IncomingTextNotification = null;
|
||||
|
||||
[Desc("Defines to which players the timer is shown.")]
|
||||
|
||||
@@ -177,8 +177,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
Key = key;
|
||||
TotalTicks = info.ChargeInterval;
|
||||
remainingSubTicks = info.StartFullyCharged ? 0 : TotalTicks * 100;
|
||||
Name = info.Name == null ? string.Empty : TranslationProvider.GetString(info.Name);
|
||||
Description = info.Description == null ? string.Empty : TranslationProvider.GetString(info.Description);
|
||||
Name = info.Name == null ? string.Empty : FluentProvider.GetString(info.Name);
|
||||
Description = info.Description == null ? string.Empty : FluentProvider.GetString(info.Description);
|
||||
|
||||
Manager = manager;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public abstract class TooltipInfoBase : ConditionalTraitInfo, Requires<IMouseBoundsInfo>
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
public readonly string Name;
|
||||
}
|
||||
|
||||
@@ -31,22 +31,22 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("An optional generic name (i.e. \"Soldier\" or \"Structure\")" +
|
||||
"to be shown to chosen players.")]
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string GenericName;
|
||||
|
||||
[Desc("Prefix generic tooltip name with 'Ally/Neutral/EnemyPrefix'.")]
|
||||
public readonly bool GenericStancePrefix = true;
|
||||
|
||||
[Desc("Prefix to display in the tooltip for allied units.")]
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string AllyPrefix = "label-tooltip-prefix.ally";
|
||||
|
||||
[Desc("Prefix to display in the tooltip for neutral units.")]
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string NeutralPrefix;
|
||||
|
||||
[Desc("Prefix to display in the tooltip for enemy units.")]
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
public readonly string EnemyPrefix = "label-tooltip-prefix.enemy";
|
||||
|
||||
[Desc("Player stances that the generic name should be shown to.")]
|
||||
@@ -60,19 +60,19 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public string TooltipForPlayerStance(PlayerRelationship relationship)
|
||||
{
|
||||
if (relationship == PlayerRelationship.None || !GenericVisibility.HasRelationship(relationship))
|
||||
return TranslationProvider.GetString(Name);
|
||||
return FluentProvider.GetString(Name);
|
||||
|
||||
var genericName = string.IsNullOrEmpty(GenericName) ? "" : TranslationProvider.GetString(GenericName);
|
||||
var genericName = string.IsNullOrEmpty(GenericName) ? "" : FluentProvider.GetString(GenericName);
|
||||
if (GenericStancePrefix)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(AllyPrefix) && relationship == PlayerRelationship.Ally)
|
||||
return TranslationProvider.GetString(AllyPrefix) + " " + genericName;
|
||||
return FluentProvider.GetString(AllyPrefix) + " " + genericName;
|
||||
|
||||
if (!string.IsNullOrEmpty(NeutralPrefix) && relationship == PlayerRelationship.Neutral)
|
||||
return TranslationProvider.GetString(NeutralPrefix) + " " + genericName;
|
||||
return FluentProvider.GetString(NeutralPrefix) + " " + genericName;
|
||||
|
||||
if (!string.IsNullOrEmpty(EnemyPrefix) && relationship == PlayerRelationship.Enemy)
|
||||
return TranslationProvider.GetString(EnemyPrefix) + " " + genericName;
|
||||
return FluentProvider.GetString(EnemyPrefix) + " " + genericName;
|
||||
}
|
||||
|
||||
return genericName;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class TooltipDescriptionInfo : ConditionalTraitInfo
|
||||
{
|
||||
[FieldLoader.Require]
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Text shown in tooltip.")]
|
||||
public readonly string Description;
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
: base(info)
|
||||
{
|
||||
this.self = self;
|
||||
TooltipText = TranslationProvider.GetString(info.Description);
|
||||
TooltipText = FluentProvider.GetString(info.Description);
|
||||
}
|
||||
|
||||
public bool IsTooltipVisible(Player forPlayer)
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play when transforming.")]
|
||||
public readonly string TransformNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display when transforming.")]
|
||||
public readonly string TransformTextNotification = null;
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Speech notification to play when the transformation is blocked.")]
|
||||
public readonly string NoTransformNotification = null;
|
||||
|
||||
[TranslationReference(optional: true)]
|
||||
[FluentReference(optional: true)]
|
||||
[Desc("Text notification to display when the transformation is blocked.")]
|
||||
public readonly string NoTransformTextNotification = null;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
const string CommandName = "triggers";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string CommandDescription = "description-cell-triggers-overlay";
|
||||
|
||||
bool enabled;
|
||||
|
||||
@@ -24,13 +24,13 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Configuration options for the lobby player color picker. Attach this to the world actor.")]
|
||||
public class ColorPickerManagerInfo : TraitInfo<ColorPickerManager>, IColorPickerManagerInfo
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string PlayerColorTerrain = "notification-player-color-terrain";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string PlayerColorPlayer = "notification-player-color-player";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string InvalidPlayerColor = "notification-invalid-player-color";
|
||||
|
||||
[Desc("Minimum and maximum saturation levels that are valid for use.")]
|
||||
|
||||
@@ -21,11 +21,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[TraitLocation(SystemActors.World)]
|
||||
public class CrateSpawnerInfo : TraitInfo, ILobbyOptions
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Descriptive label for the crates checkbox in the lobby.")]
|
||||
public readonly string CheckboxLabel = "checkbox-crates.label";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the crates checkbox in the lobby.")]
|
||||
public readonly string CheckboxDescription = "checkbox-crates.description";
|
||||
|
||||
|
||||
@@ -146,12 +146,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
sealed class OpenMapAction : IEditorAction
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string Opened = "notification-opened";
|
||||
|
||||
public OpenMapAction()
|
||||
{
|
||||
Text = TranslationProvider.GetString(Opened);
|
||||
Text = FluentProvider.GetString(Opened);
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public readonly ActorInfo Info;
|
||||
|
||||
public string Tooltip =>
|
||||
(tooltip == null ? " < " + Info.Name + " >" : TranslationProvider.GetString(tooltip.Name)) + "\n" + Owner.Name + " (" + Owner.Faction + ")"
|
||||
(tooltip == null ? " < " + Info.Name + " >" : FluentProvider.GetString(tooltip.Name)) + "\n" + Owner.Name + " (" + Owner.Faction + ")"
|
||||
+ "\nID: " + ID + "\nType: " + Info.Name;
|
||||
|
||||
public string Type => reference.Type;
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
const string CommandName = "exits-overlay";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string CommandDescription = "description-exits-overlay";
|
||||
|
||||
public readonly SpriteFont Font;
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
const string CommandName = "hpf";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
const string CommandDescription = "description-hpf-debug-overlay";
|
||||
|
||||
readonly HierarchicalPathFinderOverlayInfo info;
|
||||
|
||||
@@ -18,11 +18,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Controls the build radius checkboxes in the lobby options.")]
|
||||
public class MapBuildRadiusInfo : TraitInfo, ILobbyOptions
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Descriptive label for the ally build radius checkbox in the lobby.")]
|
||||
public readonly string AllyBuildRadiusCheckboxLabel = "checkbox-ally-build-radius.label";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the ally build radius checkbox in the lobby.")]
|
||||
public readonly string AllyBuildRadiusCheckboxDescription = "checkbox-ally-build-radius.description";
|
||||
|
||||
@@ -38,11 +38,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Display order for the ally build radius checkbox in the lobby.")]
|
||||
public readonly int AllyBuildRadiusCheckboxDisplayOrder = 0;
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the build radius checkbox in the lobby.")]
|
||||
public readonly string BuildRadiusCheckboxLabel = "checkbox-build-radius.label";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the build radius checkbox in the lobby.")]
|
||||
public readonly string BuildRadiusCheckboxDescription = "checkbox-build-radius.description";
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[TraitLocation(SystemActors.World)]
|
||||
public class MapCreepsInfo : TraitInfo, ILobbyOptions
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Descriptive label for the creeps checkbox in the lobby.")]
|
||||
public readonly string CheckboxLabel = "dropdown-map-creeps.label";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the creeps checkbox in the lobby.")]
|
||||
public readonly string CheckboxDescription = "dropdown-map-creeps.description";
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Controls the game speed, tech level, and short game lobby options.")]
|
||||
public class MapOptionsInfo : TraitInfo, ILobbyOptions, IRulesetLoaded
|
||||
{
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Descriptive label for the short game checkbox in the lobby.")]
|
||||
public readonly string ShortGameCheckboxLabel = "checkbox-short-game.label";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the short game checkbox in the lobby.")]
|
||||
public readonly string ShortGameCheckboxDescription = "checkbox-short-game.description";
|
||||
|
||||
@@ -39,11 +39,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Display order for the short game checkbox in the lobby.")]
|
||||
public readonly int ShortGameCheckboxDisplayOrder = 0;
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Descriptive label for the tech level option in the lobby.")]
|
||||
public readonly string TechLevelDropdownLabel = "dropdown-tech-level.label";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the tech level option in the lobby.")]
|
||||
public readonly string TechLevelDropdownDescription = "dropdown-tech-level.description";
|
||||
|
||||
@@ -59,11 +59,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Display order for the tech level option in the lobby.")]
|
||||
public readonly int TechLevelDropdownDisplayOrder = 0;
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the game speed option in the lobby.")]
|
||||
public readonly string GameSpeedDropdownLabel = "dropdown-game-speed.label";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Description of the game speed option in the lobby.")]
|
||||
public readonly string GameSpeedDropdownDescription = "dropdown-game-speed.description";
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
techLevels, TechLevel, TechLevelDropdownLocked);
|
||||
|
||||
var gameSpeeds = Game.ModData.Manifest.Get<GameSpeeds>();
|
||||
var speeds = gameSpeeds.Speeds.ToDictionary(s => s.Key, s => TranslationProvider.GetString(s.Value.Name));
|
||||
var speeds = gameSpeeds.Speeds.ToDictionary(s => s.Key, s => FluentProvider.GetString(s.Value.Name));
|
||||
|
||||
// NOTE: This is just exposing the UI, the backend logic for this option is hardcoded in World.
|
||||
yield return new LobbyOption(map, "gamespeed",
|
||||
|
||||
@@ -25,11 +25,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public readonly WDist InitialExploreRange = WDist.FromCells(5);
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Descriptive label for the spawn positions checkbox in the lobby.")]
|
||||
public readonly string SeparateTeamSpawnsCheckboxLabel = "checkbox-separate-team-spawns.label";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Tooltip description for the spawn positions checkbox in the lobby.")]
|
||||
public readonly string SeparateTeamSpawnsCheckboxDescription = "checkbox-separate-team-spawns.description";
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Internal class ID.")]
|
||||
public readonly string Class = "none";
|
||||
|
||||
[TranslationReference]
|
||||
[FluentReference]
|
||||
[Desc("Exposed via the UI to the player.")]
|
||||
public readonly string ClassName = "Unlabeled";
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user