diff --git a/Geekbot.net/Commands/Admin.cs b/Geekbot.net/Commands/Admin.cs index 376101a..a0fcc58 100644 --- a/Geekbot.net/Commands/Admin.cs +++ b/Geekbot.net/Commands/Admin.cs @@ -17,12 +17,14 @@ namespace Geekbot.net.Commands private readonly IDatabase _redis; private readonly DiscordSocketClient _client; private readonly IErrorHandler _errorHandler; + private readonly ITranslationHandler _translation; - public Admin(IDatabase redis, DiscordSocketClient client, IErrorHandler errorHandler) + public Admin(IDatabase redis, DiscordSocketClient client, IErrorHandler errorHandler, ITranslationHandler translationHandler) { _redis = redis; _client = client; _errorHandler = errorHandler; + _translation = translationHandler; } [Command("welcome", RunMode = RunMode.Async)] @@ -107,5 +109,28 @@ namespace Geekbot.net.Commands _errorHandler.HandleCommandException(e, Context, "Modchannel doesn't seem to exist, please set one with `!admin modchannel [channelId]`"); } } + + [Command("setlang", RunMode = RunMode.Async)] + [Remarks(CommandCategories.Admin)] + [Summary("Change the bots language")] + public async Task setLanguage([Summary("language")] string languageRaw) + { + try + { + var language = languageRaw.ToUpper(); + var success = _translation.SetLanguage(Context.Guild.Id, language); + if (success) + { + await ReplyAsync(_translation.GetString(Context.Guild.Id, "LanguageChanger", "Confirm")); + return; + } + await ReplyAsync( + $"That doesn't seem to be a supported language\r\nSupported Languages are {string.Join(", ", _translation.GetSupportedLanguages())}"); + } + catch (Exception e) + { + _errorHandler.HandleCommandException(e, Context); + } + } } } \ No newline at end of file diff --git a/Geekbot.net/Lib/TranslationHandler.cs b/Geekbot.net/Lib/TranslationHandler.cs new file mode 100644 index 0000000..06587e6 --- /dev/null +++ b/Geekbot.net/Lib/TranslationHandler.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Discord.WebSocket; +using Serilog; +using StackExchange.Redis; + +namespace Geekbot.net.Lib +{ + public class TranslationHandler : ITranslationHandler + { + private readonly ILogger _logger; + private readonly IDatabase _redis; + private Dictionary>> _translations; + private Dictionary _serverLanguages; + public List _supportedLanguages; + + public TranslationHandler(IReadOnlyCollection clientGuilds, IDatabase redis, ILogger logger) + { + _logger = logger; + _redis = redis; + _logger.Information("[Geekbot] Loading Translations"); + LoadTranslations(); + CheckSupportedLanguages(); + LoadServerLanguages(clientGuilds); + } + + private void LoadTranslations() + { + try + { + var translations = File.ReadAllText(Path.GetFullPath("./Storage/Translations.json")); + _translations = + Utf8Json.JsonSerializer.Deserialize>>>( + translations); + } + catch (Exception e) + { + _logger.Fatal(e, "Failed to load Translations"); + Environment.Exit(110); + } + } + + private void CheckSupportedLanguages() + { + try + { + _supportedLanguages = new List(); + foreach (var lang in _translations.First().Value.First().Value) + { + _supportedLanguages.Add(lang.Key); + } + } + catch (Exception e) + { + _logger.Fatal(e, "Failed to load Translations"); + Environment.Exit(110); + } + } + + private void LoadServerLanguages(IReadOnlyCollection clientGuilds) + { + _serverLanguages = new Dictionary(); + foreach (var guild in clientGuilds) + { + var language = _redis.HashGet($"{guild.Id}:Settings", "Language"); + if (string.IsNullOrEmpty(language) || !_supportedLanguages.Contains(language)) + { + _serverLanguages[guild.Id] = "EN"; + } + else + { + _serverLanguages[guild.Id] = language.ToString(); + } + } + } + + public string GetString(ulong guildId, string command, string stringName) + { + var translation = _translations[command][stringName][_serverLanguages[guildId]]; + if (!string.IsNullOrWhiteSpace(translation)) return translation; + translation = _translations[command][stringName]["EN"]; + if (string.IsNullOrWhiteSpace(translation)) + { + _logger.Warning($"No translation found for {command} - {stringName}"); + } + return translation; + } + + public bool SetLanguage(ulong guildId, string language) + { + try + { + if (!_supportedLanguages.Contains(language)) return false; + _redis.HashSet($"{guildId}:Settings", new HashEntry[]{ new HashEntry("Language", language), }); + _serverLanguages[guildId] = language; + return true; + } + catch (Exception e) + { + _logger.Error(e, "[Geekbot] Error while changing language"); + return false; + } + } + + public List GetSupportedLanguages() + { + return _supportedLanguages; + } + } + + public interface ITranslationHandler + { + string GetString(ulong guildId, string command, string stringName); + bool SetLanguage(ulong guildId, string language); + List GetSupportedLanguages(); + } +} \ No newline at end of file diff --git a/Geekbot.net/Program.cs b/Geekbot.net/Program.cs index e79824e..7f397c0 100755 --- a/Geekbot.net/Program.cs +++ b/Geekbot.net/Program.cs @@ -153,9 +153,10 @@ namespace Geekbot.net logger.Information($"[Geekbot] Now Connected as {client.CurrentUser.Username} to {client.Guilds.Count} Servers"); logger.Information("[Geekbot] Registering Stuff"); - + var translationHandler = new TranslationHandler(client.Guilds, redis, logger); await commands.AddModulesAsync(Assembly.GetEntryAssembly()); services.AddSingleton(commands); + services.AddSingleton(translationHandler); services.AddSingleton(client); servicesProvider = services.BuildServiceProvider(); diff --git a/Geekbot.net/Storage/Translations.json b/Geekbot.net/Storage/Translations.json new file mode 100644 index 0000000..b801411 --- /dev/null +++ b/Geekbot.net/Storage/Translations.json @@ -0,0 +1,8 @@ +{ + "LanguageChanger": { + "Confirm": { + "EN": "I will in english from now on", + "CHDE": "I werd ab jetzt in schwiizerdüütsch antworte, äuuä" + } + } +} \ No newline at end of file