Skip to content

Translations

Axwabo edited this page Apr 28, 2025 · 1 revision

Translations

The Axwabo.Helpers library's translation system maps enums to strings. Attributes can be used on properties or fields of objects, typically on translation configs.

Translation strings support string.Format meaning you can use curly braces with an index ({0} {1} and on) to specify positional arguments when parameters are required.

Important

The constructor must specify a concrete enum type as a parameter, System.Enum will not compile.

To create a simple translation mapping attribute for an enum, create an attribute like so:

using System;
using Axwabo.Helpers.Configs.Translations;

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public sealed class ConsoleColorTranslationAttribute : TranslationAttribute
{

    public ConsoleColorTranslationAttribute(ConsoleColor value) : base(value)
    {
    }

}

Note

You can separate your translation config file or nest it as an object in the plugin config. Make sure to call RegisterAllTranslations with the correct instance.

Tip

The names of properties don't have to match the translated values. If you don't plan to use properties directly in code, naming them is more relevant for config readability.

Apply it in your (custom) config:

using System;

public sealed class MyConfig
{
    
    [ConsoleColorTranslation(ConsoleColor.DarkBlue)]
    public string DarkBlue { get; set; } = "dark blue";
    
    [ConsoleColorTranslation(ConsoleColor.Yellow)]
    public string Hello { get; set; } = "hellow {0}"; // string.Format argument
    
}

Tip

Use the RegisterNestedTranslationsAttribute on a property to have that object's properties also be processed.

Finally, register the translations in your plugin.

When your plugin is being disabled, invoke UnregisterAllTranslations(object) to unregister the translations provided by a class. Alternatively, you can unregister enums per type by invoking UnregisterAllTranslations<T>()

using Axwabo.Helpers.Config.Translations;

// ...
public override void Enable()
{
    TranslationHelper.RegisterAllTranslations(Config);
}

public override void Disable()
{
    TranslationHelper.UnregisterAllTranslations(Config);
    // or
    TranslationHelper.UnregisterAllTranslations<ConsoleColor>();
}
// ...

Now you can translate ConsoleColor enums to the configured translations. If an enum value was not translated, its default string value will be used.

ConsoleColor.DarkBlue.Translate(); // "dark blue" if config was not modified
ConsoleColor.Blue.Translate(); // "Blue"
ConsoleColor.Yellow.Translate(); // FormatException is thrown, at least 1 parameter is required
ConsoleColor.Yellow.Translate("there"); // "hellow there"

Important

The generic type parameter of Translate must be the exact type of the enum you're translating, otherwise it won't find the associated translation. If the actual type is not known at compile time, use the TranslateRaw method.

Command Results

An enum can be implicitly converted to a CommandResult - this conversion uses the Axwabo.CommandSystem.Translations.CommandResultTranslationSuccessManager::TranslateResultRaw extension method to determine create the result. The response is translated using TranslateRaw

Implicit tuple conversions are also supported up to 4 parameters. The tuple parameters after the enum will be used as string.Format arguments.

Important

If the success state is not set, or you use Translate() when returning a CommandResult the success value will be inferred by [[whether it starts with an ! | CommandBase#string-only-constructor]]

Using the previous enum example:

using System;
using Axwabo.CommandSystem.Commands;
using Axwabo.CommandSystem.Translations;
using Axwabo.Helpers.Config.Translations;

public override CommandResult Execute(ArraySegment<string> args, CommandSender sender)
{
    return ConsoleColor.Blue;
    return ConsoleColor.Blue.TranslateResult(); // same as above
    return ConsoleColor.Blue.Translate(); // translated string is converted to a CommandResult
    return (ConsoleColor.Yellow, "there"); // "hellow there"
}

Specifying Success

To assign success states to a translation, derive your translation attribute from Axwabo.CommandSystem.Translations.CommandResultTranslationAttribute

The defined success values will automatically be registered if you call TranslationHelpers.RegisterAllTranslations

If IsSuccess is null, the success value will be inferred based on the translation string.

Tip

The derived attribute's isSuccess parameter may be a non-nullable boolean, ensuring that the success value is always defined in the attribute.

Example:

using Axwabo.CommandSystem.Translations;
using PlayerRoles.PlayableScps.Scp079;

public sealed class Scp079HudResultAttribute : CommandResultTranslationAttribute
{

    // fail by default
    public Scp079HudResultAttribute(Scp079HudTranslation value, bool? isSuccess = false)
        : base(value, isSuccess)
    {
    }

}
using PlayerRoles.PlayableScps.Scp079;

public sealed class MyConfig
{
    
    [Scp079HudResult(Scp079HudTranslation.Zoom, true)]
    public string Zoom { get; set; } = "Action successful.";
    
     // the tier must be specified when translating
    [Scp079HudResult(Scp079HudTranslation.HigherTierRequired, false)]
    public string InsufficientTier { get; set; } = "Tier {0} is required.";
    
     // false can be omitted as it's the default parameter value
    [Scp079HudResult(Scp079HudTranslation.SignalLost)]
    public string NoSignal { get; set; } = "You've lost signal. Try again in {0}m {1}s."
    
}
using System;
using Axwabo.CommandSystem.Commands;
using PlayerRoles.PlayableScps.Scp079;

public override CommandResult Execute(ArraySegment<string> args, CommandSender sender)
{
    return Scp079HudTranslation.Zoom; // command success: "Action successful."
    return Scp079HudTranslation.HigherTierRequired; // FormatException is thrown
    return (Scp079HudTranslation.HigherTierRequired, 4); // command failure: "Tier 4 is required."
    return (Scp079HudTranslation.SignalLost, 0, 5); // command failure: "You've lost signal. Try again in 0m 5s."
}
Clone this wiki locally