Skip to content

Commit

Permalink
Add localization API (#64)
Browse files Browse the repository at this point in the history
Co-authored-by: js6pak <[email protected]>
  • Loading branch information
Alexejhero and js6pak authored Oct 23, 2022
1 parent f2da251 commit 0c8156a
Show file tree
Hide file tree
Showing 14 changed files with 523 additions and 86 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="all" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\stylecop.json" Link="stylecop.json" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\stylecop.json" Link="stylecop.json" Visible="false" />
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)\stylecop.ruleset</CodeAnalysisRuleSet>
Expand Down
26 changes: 26 additions & 0 deletions Reactor.Example/ExampleLocalizationProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Reactor.Localization;

namespace Reactor.Example;

public class ExampleLocalizationProvider : LocalizationProvider
{
public override bool TryGetText(StringNames stringName, out string? result)
{
if (stringName == (StringNames) 1337)
{
switch (CurrentLanguage)
{
case SupportedLangs.English:
result = "Cringe English";
return true;

default:
result = "Based " + CurrentLanguage;
return true;
}
}

result = null;
return false;
}
}
23 changes: 20 additions & 3 deletions Reactor.Example/ExamplePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using BepInEx;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime.Attributes;
using Reactor.Localization;
using Reactor.Localization.Utilities;
using Reactor.Networking;
using Reactor.Networking.Attributes;
using Reactor.Networking.Rpc;
Expand All @@ -19,9 +21,14 @@ namespace Reactor.Example;
[ReactorModFlags(ModFlags.RequireOnAllClients)]
public partial class ExamplePlugin : BasePlugin
{
private static StringNames _helloStringName;

public override void Load()
{
this.AddComponent<ExampleComponent>();

_helloStringName = CustomStringName.CreateAndRegister("Hello!");
LocalizationManager.Register(new ExampleLocalizationProvider());
}

[RegisterInIl2Cpp]
Expand All @@ -34,19 +41,29 @@ public ExampleComponent(IntPtr ptr) : base(ptr)
{
TestWindow = new DragWindow(new Rect(60, 20, 0, 0), "Example", () =>
{
if (GUILayout.Button("Log CustomStringName"))
{
Logger<ExamplePlugin>.Info(TranslationController.Instance.GetString(_helloStringName));
}

if (GUILayout.Button("Log localized string"))
{
Logger<ExamplePlugin>.Info(TranslationController.Instance.GetString((StringNames) 1337));
}

if (AmongUsClient.Instance && PlayerControl.LocalPlayer)
{
if (GUILayout.Button("Send ExampleRpc"))
{
var name = PlayerControl.LocalPlayer.Data.PlayerName;
Rpc<ExampleRpc>.Instance.Send(new ExampleRpc.Data($"Send: from {name}"), ackCallback: () =>
var playerName = PlayerControl.LocalPlayer.Data.PlayerName;
Rpc<ExampleRpc>.Instance.Send(new ExampleRpc.Data($"Send: from {playerName}"), ackCallback: () =>
{
Logger<ExamplePlugin>.Info("Got an acknowledgement for example rpc");
});

if (!AmongUsClient.Instance.AmHost)
{
Rpc<ExampleRpc>.Instance.SendTo(AmongUsClient.Instance.HostId, new ExampleRpc.Data($"SendTo: from {name} to host"));
Rpc<ExampleRpc>.Instance.SendTo(AmongUsClient.Instance.HostId, new ExampleRpc.Data($"SendTo: from {playerName} to host"));
}
}

Expand Down
2 changes: 2 additions & 0 deletions Reactor.sln
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Files", "Solution
AmongUs.props = AmongUs.props
Directory.Build.props = Directory.Build.props
nuget.config = nuget.config
stylecop.json = stylecop.json
stylecop.ruleset = stylecop.ruleset
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reactor.Networking.Shared", "Reactor.Networking.Shared\Reactor.Networking.Shared.csproj", "{1E68CA20-22EB-4E57-B525-81970BE6363D}"
Expand Down
82 changes: 0 additions & 82 deletions Reactor/Localization/CustomStringName.cs

This file was deleted.

39 changes: 39 additions & 0 deletions Reactor/Localization/Extensions/SupportedLangsExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Globalization;

namespace Reactor.Localization.Extensions;

/// <summary>
/// Provides extension methods for <see cref="SupportedLangs"/>.
/// </summary>
public static class SupportedLangsExtensions
{
/// <summary>
/// Gets a <see cref="CultureInfo"/> from the specified <paramref name="language"/>.
/// </summary>
/// <param name="language">The <see cref="SupportedLangs"/>.</param>
/// <returns>a <see cref="CultureInfo"/>.</returns>
public static CultureInfo ToCultureInfo(this SupportedLangs language)
{
return language switch
{
SupportedLangs.English => CultureInfo.GetCultureInfo("en"),
SupportedLangs.Latam => CultureInfo.GetCultureInfo("es"),
SupportedLangs.Brazilian => CultureInfo.GetCultureInfo("pt-BR"),
SupportedLangs.Portuguese => CultureInfo.GetCultureInfo("pt"),
SupportedLangs.Korean => CultureInfo.GetCultureInfo("ko"),
SupportedLangs.Russian => CultureInfo.GetCultureInfo("ru"),
SupportedLangs.Dutch => CultureInfo.GetCultureInfo("nl"),
SupportedLangs.Filipino => CultureInfo.GetCultureInfo("fil"),
SupportedLangs.French => CultureInfo.GetCultureInfo("fr"),
SupportedLangs.German => CultureInfo.GetCultureInfo("de"),
SupportedLangs.Italian => CultureInfo.GetCultureInfo("it"),
SupportedLangs.Japanese => CultureInfo.GetCultureInfo("ja"),
SupportedLangs.Spanish => CultureInfo.GetCultureInfo("es"),
SupportedLangs.SChinese => CultureInfo.GetCultureInfo("zh-Hans"),
SupportedLangs.TChinese => CultureInfo.GetCultureInfo("zh-Hant"),
SupportedLangs.Irish => CultureInfo.GetCultureInfo("ga"),
_ => throw new ArgumentOutOfRangeException(nameof(language), language, null),
};
}
}
111 changes: 111 additions & 0 deletions Reactor/Localization/LocalizationManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System.Collections.Generic;
using Il2CppInterop.Runtime.InteropTypes.Arrays;

namespace Reactor.Localization;

/// <summary>
/// Handles custom <see cref="StringNames"/> localization.
/// </summary>
public static class LocalizationManager
{
private static readonly List<LocalizationProvider> _providers = new();

/// <summary>
/// Gets registered <see cref="LocalizationProvider"/>s.
/// </summary>
public static IReadOnlyList<LocalizationProvider> Providers { get; } = _providers.AsReadOnly();

/// <summary>
/// Registers a new <see cref="LocalizationProvider"/> to be used for obtaining translations.
/// </summary>
/// <param name="provider">A <see cref="LocalizationProvider"/> instance.</param>
public static void Register(LocalizationProvider provider)
{
if (!_providers.Contains(provider))
{
_providers.Add(provider);

if (TranslationController.InstanceExists)
{
provider.SetLanguage(TranslationController.Instance.currentLanguage.languageID);
}

_providers.Sort((a, b) => b.Priority - a.Priority);
}
}

/// <summary>
/// Unregisters a <see cref="LocalizationProvider"/>.
/// </summary>
/// <param name="provider">The <see cref="LocalizationProvider"/> to unregister.</param>
public static void Unregister(LocalizationProvider provider)
{
_providers.Remove(provider);
}

internal static bool TryGetTextFormatted(StringNames stringName, Il2CppReferenceArray<Il2CppSystem.Object> parts, out string text)
{
foreach (var provider in _providers)
{
if (provider.TryGetTextFormatted(stringName, parts, out text!))
{
return true;
}
}

text = string.Empty;
return false;
}

internal static bool TryGetText(StringNames stringName, out string text)
{
foreach (var provider in _providers)
{
if (provider.TryGetText(stringName, out text!))
{
return true;
}
}

text = string.Empty;
return false;
}

internal static bool TryGetStringName(SystemTypes systemType, out StringNames stringName)
{
foreach (var provider in _providers)
{
if (provider.TryGetStringName(systemType, out var stringNameNullable))
{
stringName = stringNameNullable!.Value;
return true;
}
}

stringName = default;
return false;
}

internal static bool TryGetStringName(TaskTypes taskTypes, out StringNames stringName)
{
foreach (var provider in _providers)
{
if (provider.TryGetStringName(taskTypes, out var stringNameNullable))
{
stringName = stringNameNullable!.Value;
return true;
}
}

stringName = default;
return false;
}

internal static void OnLanguageChanged(SupportedLangs newLanguage)
{
foreach (var provider in _providers)
{
provider.SetLanguage(newLanguage);
}
}
}
Loading

0 comments on commit 0c8156a

Please sign in to comment.