Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add localization API #64

Merged
merged 25 commits into from
Oct 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0825dee
Localization API
Alexejhero Oct 4, 2022
4002fbd
Merge remote-tracking branch 'upstream/master' into v2
Alexejhero Oct 10, 2022
bc43a4a
Fix CustomStringName
Alexejhero Oct 10, 2022
5439f62
Add examples and fix some issues
Alexejhero Oct 10, 2022
f49ac74
Merge remote-tracking branch 'upstream/master' into v2
Alexejhero Oct 10, 2022
1cdce8b
Add SupportLangs to GetText callback
Alexejhero Oct 10, 2022
4fa3a01
Move Il2CppBoxedPrimitive into extensions
Alexejhero Oct 10, 2022
645b396
Add Xml docs and fix some other warnings
Alexejhero Oct 10, 2022
c70f3f1
Change CustomStringName to be less cringe
Alexejhero Oct 10, 2022
b0d231e
Renamed some methods after 6pak DM
Alexejhero Oct 10, 2022
45c8e1d
Easier way of assigning task types and system types with string names
Alexejhero Oct 10, 2022
1abf7d4
Revert "Easier way of assigning task types and system types with stri…
Alexejhero Oct 10, 2022
5f13318
Use TryGet pattern
Alexejhero Oct 10, 2022
94bd332
Fix formatting
Alexejhero Oct 10, 2022
27785e3
Allow localization providers to format their own strings
Alexejhero Oct 11, 2022
a0b7aa2
Add on language changed event
Alexejhero Oct 12, 2022
83fb108
Store language as property instead of passing it as a parameter
Alexejhero Oct 13, 2022
f4b13b2
Address reviews
Alexejhero Oct 13, 2022
b553741
Sort providers less and update currentlanguage when one is added
Alexejhero Oct 13, 2022
ffe0db0
Check if instance exists before calling setlanguage
Alexejhero Oct 13, 2022
6e42df9
Use default instead StringNames.ExitButton
js6pak Oct 13, 2022
398d504
Add SupportedLangsExtensions
js6pak Oct 13, 2022
d5ee29f
Remove Il2CppBoxedPrimitive in favor of updated Il2CppInterop
js6pak Oct 18, 2022
d00aed4
Merge branch 'master' into localization
js6pak Oct 23, 2022
5169871
Expose providers as a readonly list
js6pak Oct 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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