Rename Fluent-related code to be more precise.

This commit is contained in:
Paul Chote
2024-10-01 19:34:12 +01:00
committed by Gustas
parent 771b9ddfda
commit b29b685058
176 changed files with 1349 additions and 1369 deletions

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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);
}
}
}

View File

@@ -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)));
}
}

View File

@@ -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));
}

View File

@@ -15,7 +15,7 @@ namespace OpenRA
{
public class GameSpeed
{
[TranslationReference]
[FluentReference]
[FieldLoader.Require]
public readonly string Name;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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");
}
}

View File

@@ -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()

View File

@@ -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;

View File

@@ -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));
}

View File

@@ -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;
}

View File

@@ -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())

View File

@@ -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());

View File

@@ -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)

View File

@@ -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";

View File

@@ -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;

View File

@@ -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))
{

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 =

View File

@@ -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;
}

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -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()

View File

@@ -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>

View File

@@ -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()

View File

@@ -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()

View File

@@ -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));
}
}
}

View File

@@ -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()

View File

@@ -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);
}

View File

@@ -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))
{

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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))
{

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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());
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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); }

View File

@@ -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;

View File

@@ -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.")]

View File

@@ -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); }

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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); }

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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); }

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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.")]

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits
{
const string CommandName = "triggers";
[TranslationReference]
[FluentReference]
const string CommandDescription = "description-cell-triggers-overlay";
bool enabled;

View File

@@ -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.")]

View File

@@ -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";

View File

@@ -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()

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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";

View File

@@ -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";

View File

@@ -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",

View File

@@ -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";

View File

@@ -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