diff --git a/src/ARKServerManager/App.xaml.cs b/src/ARKServerManager/App.xaml.cs index 5fe95cd2..321e4a93 100644 --- a/src/ARKServerManager/App.xaml.cs +++ b/src/ARKServerManager/App.xaml.cs @@ -4,7 +4,7 @@ using NLog.Config; using NLog.Targets; using ServerManagerTool.Common; using ServerManagerTool.Common.Utils; -using ServerManagerTool.Discord; +using ServerManagerTool.DiscordBot; using ServerManagerTool.Enums; using ServerManagerTool.Lib; using ServerManagerTool.Plugin.Common; @@ -456,7 +456,7 @@ namespace ServerManagerTool Task discordTask = Task.Run(async () => { - await ServerManagerBotFactory.GetServerManagerBot()?.StartAsync(Config.Default.DiscordBotToken, Config.Default.DiscordBotPrefix, Config.Default.DataDir, DiscordBotHelper.HandleDiscordCommand, _tokenSource.Token); + await ServerManagerBotFactory.GetServerManagerBot()?.StartAsync(Config.Default.DiscordBotToken, Config.Default.DiscordBotPrefix, Config.Default.DataDir, DiscordBotHelper.HandleDiscordCommand, DiscordBotHelper.HandleTranslation, _tokenSource.Token); }, _tokenSource.Token) .ContinueWith(t => { var message = t.Exception.InnerException is null ? t.Exception.Message : t.Exception.InnerException.Message; diff --git a/src/ARKServerManager/Enums/AvailabilityStatus.cs b/src/ARKServerManager/Enums/AvailabilityStatus.cs index f2588330..81846709 100644 --- a/src/ARKServerManager/Enums/AvailabilityStatus.cs +++ b/src/ARKServerManager/Enums/AvailabilityStatus.cs @@ -3,9 +3,9 @@ public enum AvailabilityStatus { Unknown, - NeedPublicIP, + SetPublicIP, Unavailable, - WaitingForPublication, + Waiting, Available } } diff --git a/src/ARKServerManager/Globalization/en-US/en-US.xaml b/src/ARKServerManager/Globalization/en-US/en-US.xaml index 97c957cf..fd970206 100644 --- a/src/ARKServerManager/Globalization/en-US/en-US.xaml +++ b/src/ARKServerManager/Globalization/en-US/en-US.xaml @@ -5544,6 +5544,18 @@ Discord Bot Error The discord bot requires a valid token so it can log into the discord server\r\nThis can be set in the global settings. The discord bot prefix contains invalid characters. Only letters and numbers are allowed. + + Command '{0}' has not been implemented. + Unknown command '{0}'. + Another command is currently running. + + The command requires a profile id. + Profile id {0} not found or is not associated with the channel. + + Call to the server '{0}' failed. + + Count: + Map: \ No newline at end of file diff --git a/src/ARKServerManager/Lib/ServerRuntime.cs b/src/ARKServerManager/Lib/ServerRuntime.cs index 420cde9f..b3d9f374 100644 --- a/src/ARKServerManager/Lib/ServerRuntime.cs +++ b/src/ARKServerManager/Lib/ServerRuntime.cs @@ -281,13 +281,13 @@ namespace ServerManagerTool.Lib case WatcherServerStatus.RunningLocalCheck: if (oldStatus != ServerStatus.Stopping) - UpdateServerStatus(ServerStatus.Running, this.Availability != AvailabilityStatus.Available ? AvailabilityStatus.WaitingForPublication : this.Availability, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown); + UpdateServerStatus(ServerStatus.Running, this.Availability != AvailabilityStatus.Available ? AvailabilityStatus.Waiting : this.Availability, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown); if (this.ProfileSnapshot.MOTDIntervalEnabled && this.motdIntervalTimer != null && !this.motdIntervalTimer.Enabled) this.motdIntervalTimer.Start(); break; case WatcherServerStatus.RunningExternalCheck: if (oldStatus != ServerStatus.Stopping) - UpdateServerStatus(ServerStatus.Running, AvailabilityStatus.WaitingForPublication, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown); + UpdateServerStatus(ServerStatus.Running, AvailabilityStatus.Waiting, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown); if (this.ProfileSnapshot.MOTDIntervalEnabled && this.motdIntervalTimer != null && !this.motdIntervalTimer.Enabled) this.motdIntervalTimer.Start(); break; diff --git a/src/ARKServerManager/Utils/DiscordBotHelper.cs b/src/ARKServerManager/Utils/DiscordBotHelper.cs index 2ca1be1f..7c5b9f55 100644 --- a/src/ARKServerManager/Utils/DiscordBotHelper.cs +++ b/src/ARKServerManager/Utils/DiscordBotHelper.cs @@ -1,13 +1,189 @@ -using ServerManagerTool.Discord.Enums; +using QueryMaster; +using ServerManagerTool.Common.Utils; +using ServerManagerTool.DiscordBot.Enums; +using ServerManagerTool.Lib; +using System; using System.Collections.Generic; +using System.Linq; +using System.Net; +using WPFSharp.Globalizer; namespace ServerManagerTool.Utils { internal static class DiscordBotHelper { + private static readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance; + private static bool _runningCommand = false; + public static IList HandleDiscordCommand(CommandType commandType, string serverId, string channelId, string profileId) { - return new List() { $"{commandType}; {serverId}; {channelId}; {profileId ?? "no profile"}" }; + // check if incoming values are valid + if (string.IsNullOrWhiteSpace(serverId) || string.IsNullOrWhiteSpace(channelId)) + return null; + + // check if the server ids match + if (!serverId.Equals(Config.Default.DiscordBotServerId)) + return new List(); + + if (_runningCommand) + return new List { _globalizer.GetResourceString("DiscordBot_CommandRunning") }; + _runningCommand = true; + + try + { + switch (commandType) + { + case CommandType.Info: + return GetServerInfo(channelId, profileId); + case CommandType.List: + return GetServerList(channelId); + case CommandType.Status: + return GetServerStatus(channelId, profileId); + + case CommandType.Backup: + return BackupServer(channelId, profileId); + case CommandType.Shutdown: + return ShutdownServer(channelId, profileId); + case CommandType.Stop: + return StopServer(channelId, profileId); + case CommandType.Start: + return StartServer(channelId, profileId); + case CommandType.Update: + return UpdateServer(channelId, profileId); + + default: + return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), commandType) }; + } + } + catch (Exception ex) + { + var message = ex.InnerException is null ? ex.Message : ex.InnerException.Message; + return new string[] { message }; + } + finally + { + _runningCommand = false; + } + } + + public static string HandleTranslation(string translationKey) + { + return string.IsNullOrWhiteSpace(translationKey) ? string.Empty : _globalizer.GetResourceString(translationKey) ?? translationKey; + } + + private static IList GetServerInfo(string channelId, string profileId) + { + if (string.IsNullOrWhiteSpace(profileId)) + { + return new List { _globalizer.GetResourceString("DiscordBot_CommandProfileMissing") }; + } + + var serverName = string.Empty; + var serverIp = IPAddress.Loopback; + var queryPort = 0; + + TaskUtils.RunOnUIThreadAsync(() => + { + var server = ServerManager.Instance.Servers.Where(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID)).FirstOrDefault(); + + if (server is null) + { + throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandProfileNotFound"), profileId)); + } + + serverName = server.Profile.ServerName; + if (!string.IsNullOrWhiteSpace(server.Profile.ServerIP)) + { + IPAddress.TryParse(server.Profile.ServerIP, out serverIp); + } + queryPort = server.Profile.QueryPort; + }).Wait(); + + List response = new List(); + + try + { + using (var gameServer = ServerQuery.GetServerInstance(EngineType.Source, new IPEndPoint(serverIp, queryPort))) + { + var info = gameServer?.GetInfo(); + if (info is null) + { + response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_CommandInfoFailed"), serverName)); + } + else + { + var mapName = _globalizer.GetResourceString($"Map_{info.Map}") ?? info.Map; + response.Add($"```{info.Name}\n{_globalizer.GetResourceString("DiscordBot_MapLabel")} {mapName}\n{_globalizer.GetResourceString("ServerSettings_PlayersLabel")} {info.Players} / {info.MaxPlayers}```"); + } + } + } + catch (Exception) + { + response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_CommandInfoFailed"), serverName)); + } + + return response; + } + + private static IList GetServerList(string channelId) + { + List response = new List(); + + TaskUtils.RunOnUIThreadAsync(() => + { + var serverList = ServerManager.Instance.Servers.Where(s => Equals(channelId, s.Profile.DiscordChannelId)); + + response.Add($"**{_globalizer.GetResourceString("DiscordBot_CountLabel")}** {serverList.Count()}"); + foreach (var server in serverList) + { + response.Add($"```{_globalizer.GetResourceString("ServerSettings_ProfileIdLabel")} {server.Profile.ProfileID}\n{_globalizer.GetResourceString("ServerSettings_ProfileLabel")} {server.Profile.ProfileName}\n{_globalizer.GetResourceString("ServerSettings_ServerNameLabel")} {server.Profile.ServerName}```"); + } + }).Wait(); + + return response; + } + + private static IList GetServerStatus(string channelId, string profileId) + { + List response = new List(); + + TaskUtils.RunOnUIThreadAsync(() => + { + var serverList = ServerManager.Instance.Servers.Where(s => Equals(channelId, s.Profile.DiscordChannelId) && (string.IsNullOrWhiteSpace(profileId) || Equals(profileId, s.Profile.ProfileID))); + + response.Add($"**{_globalizer.GetResourceString("DiscordBot_CountLabel")}** {serverList.Count()}"); + foreach (var server in serverList) + { + response.Add($"```{_globalizer.GetResourceString("ServerSettings_ProfileLabel")} {server.Profile.ProfileName}\n{_globalizer.GetResourceString("ServerSettings_ServerNameLabel")} {server.Profile.ServerName}\n{_globalizer.GetResourceString("ServerSettings_StatusLabel")} {server.Runtime.StatusString}\n{_globalizer.GetResourceString("ServerSettings_AvailabilityLabel")} {_globalizer.GetResourceString($"ServerSettings_Availability_{server.Runtime.Availability}")}```"); + } + }).Wait(); + + return response; + } + + private static IList BackupServer(string channelId, string profileId) + { + return new List() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Backup) }; + } + + private static IList ShutdownServer(string channelId, string profileId) + { + return new List() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Shutdown) }; + } + + private static IList StopServer(string channelId, string profileId) + { + return new List() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Stop) }; + } + + private static IList StartServer(string channelId, string profileId) + { + return new List() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Start) }; + } + + private static IList UpdateServer(string channelId, string profileId) + { + return new List() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Update) }; } } } diff --git a/src/ARKServerManager/Windows/ServerSettingsControl.xaml b/src/ARKServerManager/Windows/ServerSettingsControl.xaml index 9916a9c7..4e0044d1 100644 --- a/src/ARKServerManager/Windows/ServerSettingsControl.xaml +++ b/src/ARKServerManager/Windows/ServerSettingsControl.xaml @@ -420,13 +420,13 @@ - + - + diff --git a/src/ConanServerManager/App.xaml.cs b/src/ConanServerManager/App.xaml.cs index 15a08442..f6ebab3d 100644 --- a/src/ConanServerManager/App.xaml.cs +++ b/src/ConanServerManager/App.xaml.cs @@ -3,15 +3,13 @@ using NLog.Config; using NLog.Targets; using ServerManagerTool.Common; using ServerManagerTool.Common.Utils; -using ServerManagerTool.Discord; -using ServerManagerTool.Discord.Enums; +using ServerManagerTool.DiscordBot; using ServerManagerTool.Enums; using ServerManagerTool.Lib; using ServerManagerTool.Plugin.Common; using ServerManagerTool.Utils; using ServerManagerTool.Windows; using System; -using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; @@ -214,11 +212,6 @@ namespace ServerManagerTool return LogManager.GetLogger(loggerName); } - private static IList HandleDiscordCommand(CommandType commandType, string serverId, string channelId, string profileId) - { - return new List() { $"{commandType}; {serverId}; {channelId}; {profileId ?? "no profile"}" }; - } - private static void MigrateSettings() { var installFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); @@ -444,7 +437,7 @@ namespace ServerManagerTool Task discordTask = Task.Run(async () => { - await ServerManagerBotFactory.GetServerManagerBot()?.StartAsync(Config.Default.DiscordBotToken,Config.Default.DiscordBotPrefix, Config.Default.DataPath, DiscordBotHelper.HandleDiscordCommand, _tokenSource.Token); + await ServerManagerBotFactory.GetServerManagerBot()?.StartAsync(Config.Default.DiscordBotToken,Config.Default.DiscordBotPrefix, Config.Default.DataPath, DiscordBotHelper.HandleDiscordCommand, DiscordBotHelper.HandleTranslation, _tokenSource.Token); }, _tokenSource.Token) .ContinueWith(t => { var message = t.Exception.InnerException is null ? t.Exception.Message : t.Exception.InnerException.Message; diff --git a/src/ConanServerManager/Enums/AvailabilityStatus.cs b/src/ConanServerManager/Enums/AvailabilityStatus.cs index f2588330..81846709 100644 --- a/src/ConanServerManager/Enums/AvailabilityStatus.cs +++ b/src/ConanServerManager/Enums/AvailabilityStatus.cs @@ -3,9 +3,9 @@ public enum AvailabilityStatus { Unknown, - NeedPublicIP, + SetPublicIP, Unavailable, - WaitingForPublication, + Waiting, Available } } diff --git a/src/ConanServerManager/Globalization/en-US/en-US.xaml b/src/ConanServerManager/Globalization/en-US/en-US.xaml index 706f59bb..c56e4c92 100644 --- a/src/ConanServerManager/Globalization/en-US/en-US.xaml +++ b/src/ConanServerManager/Globalization/en-US/en-US.xaml @@ -1214,6 +1214,18 @@ Discord Bot Error The discord bot requires a valid token so it can log into the discord server\r\nThis can be set in the global settings. The discord bot prefix contains invalid characters. Only letters and numbers are allowed. + + Command '{0}' has not been implemented. + Unknown command '{0}'. + Another command is currently running. + + The command requires a profile id. + Profile id {0} not found or is not associated with the channel. + + Call to the server '{0}' failed. + + Count: + Map: \ No newline at end of file diff --git a/src/ConanServerManager/Lib/ServerRuntime.cs b/src/ConanServerManager/Lib/ServerRuntime.cs index 44ff0e60..479e14e5 100644 --- a/src/ConanServerManager/Lib/ServerRuntime.cs +++ b/src/ConanServerManager/Lib/ServerRuntime.cs @@ -277,13 +277,13 @@ namespace ServerManagerTool.Lib case WatcherServerStatus.RunningLocalCheck: if (oldStatus != ServerStatus.Stopping) - UpdateServerStatus(ServerStatus.Running, this.Availability != AvailabilityStatus.Available ? AvailabilityStatus.WaitingForPublication : this.Availability, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown); + UpdateServerStatus(ServerStatus.Running, this.Availability != AvailabilityStatus.Available ? AvailabilityStatus.Waiting : this.Availability, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown); if (this.ProfileSnapshot.MOTDIntervalEnabled && this.motdIntervalTimer != null && !this.motdIntervalTimer.Enabled) this.motdIntervalTimer.Start(); break; case WatcherServerStatus.RunningExternalCheck: if (oldStatus != ServerStatus.Stopping) - UpdateServerStatus(ServerStatus.Running, AvailabilityStatus.WaitingForPublication, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown); + UpdateServerStatus(ServerStatus.Running, AvailabilityStatus.Waiting, oldStatus != ServerStatus.Running && oldStatus != ServerStatus.Unknown); if (this.ProfileSnapshot.MOTDIntervalEnabled && this.motdIntervalTimer != null && !this.motdIntervalTimer.Enabled) this.motdIntervalTimer.Start(); break; diff --git a/src/ConanServerManager/Utils/DiscordBotHelper.cs b/src/ConanServerManager/Utils/DiscordBotHelper.cs index 2ca1be1f..fc793e95 100644 --- a/src/ConanServerManager/Utils/DiscordBotHelper.cs +++ b/src/ConanServerManager/Utils/DiscordBotHelper.cs @@ -1,13 +1,188 @@ -using ServerManagerTool.Discord.Enums; +using QueryMaster; +using ServerManagerTool.Common.Utils; +using ServerManagerTool.DiscordBot.Enums; +using ServerManagerTool.Lib; +using System; using System.Collections.Generic; +using System.Linq; +using System.Net; +using WPFSharp.Globalizer; namespace ServerManagerTool.Utils { internal static class DiscordBotHelper { + private static readonly GlobalizedApplication _globalizer = GlobalizedApplication.Instance; + private static bool _runningCommand = false; + public static IList HandleDiscordCommand(CommandType commandType, string serverId, string channelId, string profileId) { - return new List() { $"{commandType}; {serverId}; {channelId}; {profileId ?? "no profile"}" }; + // check if incoming values are valid + if (string.IsNullOrWhiteSpace(serverId) || string.IsNullOrWhiteSpace(channelId)) + return null; + + // check if the server ids match + if (!serverId.Equals(Config.Default.DiscordBotServerId)) + return new List(); + + if (_runningCommand) + return new List { _globalizer.GetResourceString("DiscordBot_CommandRunning") }; + _runningCommand = true; + + try + { + switch (commandType) + { + case CommandType.Info: + return GetServerInfo(channelId, profileId); + case CommandType.List: + return GetServerList(channelId); + case CommandType.Status: + return GetServerStatus(channelId, profileId); + + case CommandType.Backup: + return BackupServer(channelId, profileId); + case CommandType.Shutdown: + return ShutdownServer(channelId, profileId); + case CommandType.Stop: + return StopServer(channelId, profileId); + case CommandType.Start: + return StartServer(channelId, profileId); + case CommandType.Update: + return UpdateServer(channelId, profileId); + + default: + return new List { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), commandType) }; + } + } + catch (Exception ex) + { + return new string[] { ex.Message }; + } + finally + { + _runningCommand = false; + } + } + + public static string HandleTranslation(string translationKey) + { + return string.IsNullOrWhiteSpace(translationKey) ? string.Empty : _globalizer.GetResourceString(translationKey) ?? translationKey; + } + + private static IList GetServerInfo(string channelId, string profileId) + { + if (string.IsNullOrWhiteSpace(profileId)) + { + return new List { _globalizer.GetResourceString("DiscordBot_CommandProfileMissing") }; + } + + var serverName = string.Empty; + var serverIp = IPAddress.Loopback; + var queryPort = 0; + + TaskUtils.RunOnUIThreadAsync(() => + { + var server = ServerManager.Instance.Servers.Where(s => Equals(channelId, s.Profile.DiscordChannelId) && Equals(profileId, s.Profile.ProfileID)).FirstOrDefault(); + + if (server is null) + { + throw new Exception(string.Format(_globalizer.GetResourceString("DiscordBot_CommandProfileNotFound"), profileId)); + } + + serverName = server.Profile.ServerName; + if (!string.IsNullOrWhiteSpace(server.Profile.ServerIP)) + { + IPAddress.TryParse(server.Profile.ServerIP, out serverIp); + } + queryPort = server.Profile.QueryPort; + }).Wait(); + + List response = new List(); + + try + { + using (var gameServer = ServerQuery.GetServerInstance(EngineType.Source, new IPEndPoint(serverIp, queryPort))) + { + var info = gameServer?.GetInfo(); + if (info is null) + { + response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_CommandInfoFailed"), serverName)); + } + else + { + var mapName = _globalizer.GetResourceString($"Map_{info.Map}") ?? info.Map; + response.Add($"```{info.Name}\n{_globalizer.GetResourceString("DiscordBot_MapLabel")} {mapName}\n{_globalizer.GetResourceString("ServerSettings_PlayersLabel")} {info.Players} / {info.MaxPlayers}```"); + } + } + } + catch (Exception) + { + response.Add(string.Format(_globalizer.GetResourceString("DiscordBot_CommandInfoFailed"), serverName)); + } + + return response; + } + + private static IList GetServerList(string channelId) + { + List response = new List(); + + TaskUtils.RunOnUIThreadAsync(() => + { + var serverList = ServerManager.Instance.Servers.Where(s => Equals(channelId, s.Profile.DiscordChannelId)); + + response.Add($"**{_globalizer.GetResourceString("DiscordBot_CountLabel")}** {serverList.Count()}"); + foreach (var server in serverList) + { + response.Add($"```{_globalizer.GetResourceString("ServerSettings_ProfileIdLabel")} {server.Profile.ProfileID}\n{_globalizer.GetResourceString("ServerSettings_ProfileLabel")} {server.Profile.ProfileName}\n{_globalizer.GetResourceString("ServerSettings_ServerNameLabel")} {server.Profile.ServerName}```"); + } + }).Wait(); + + return response; + } + + private static IList GetServerStatus(string channelId, string profileId) + { + List response = new List(); + + TaskUtils.RunOnUIThreadAsync(() => + { + var serverList = ServerManager.Instance.Servers.Where(s => Equals(channelId, s.Profile.DiscordChannelId) && (string.IsNullOrWhiteSpace(profileId) || Equals(profileId, s.Profile.ProfileID))); + + response.Add($"**{_globalizer.GetResourceString("DiscordBot_CountLabel")}** {serverList.Count()}"); + foreach (var server in serverList) + { + response.Add($"```{_globalizer.GetResourceString("ServerSettings_ProfileLabel")} {server.Profile.ProfileName}\n{_globalizer.GetResourceString("ServerSettings_ServerNameLabel")} {server.Profile.ServerName}\n{_globalizer.GetResourceString("ServerSettings_StatusLabel")} {server.Runtime.StatusString}\n{_globalizer.GetResourceString("ServerSettings_AvailabilityLabel")} {_globalizer.GetResourceString($"ServerSettings_Availability_{server.Runtime.Availability}")}```"); + } + }).Wait(); + + return response; + } + + private static IList BackupServer(string channelId, string profileId) + { + return new List() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Backup) }; + } + + private static IList ShutdownServer(string channelId, string profileId) + { + return new List() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Shutdown) }; + } + + private static IList StopServer(string channelId, string profileId) + { + return new List() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Stop) }; + } + + private static IList StartServer(string channelId, string profileId) + { + return new List() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Start) }; + } + + private static IList UpdateServer(string channelId, string profileId) + { + return new List() { string.Format(_globalizer.GetResourceString("DiscordBot_CommandUnknown"), CommandType.Update) }; } } } diff --git a/src/ConanServerManager/Windows/ServerSettingsControl.xaml b/src/ConanServerManager/Windows/ServerSettingsControl.xaml index 7388d096..016fe8f3 100644 --- a/src/ConanServerManager/Windows/ServerSettingsControl.xaml +++ b/src/ConanServerManager/Windows/ServerSettingsControl.xaml @@ -282,13 +282,13 @@ - + - + diff --git a/src/ServerManager.Discord/Delegates/HandleCommandDelegate.cs b/src/ServerManager.Discord/Delegates/HandleCommandDelegate.cs index 5d7f9a1d..a6b973f1 100644 --- a/src/ServerManager.Discord/Delegates/HandleCommandDelegate.cs +++ b/src/ServerManager.Discord/Delegates/HandleCommandDelegate.cs @@ -1,7 +1,7 @@ -using ServerManagerTool.Discord.Enums; +using ServerManagerTool.DiscordBot.Enums; using System.Collections.Generic; -namespace ServerManagerTool.Discord.Delegates +namespace ServerManagerTool.DiscordBot.Delegates { public delegate IList HandleCommandDelegate(CommandType commandType, string serverId, string channelId, string profileId); } diff --git a/src/ServerManager.Discord/Delegates/HandleTranslationDelegate.cs b/src/ServerManager.Discord/Delegates/HandleTranslationDelegate.cs new file mode 100644 index 00000000..181930ec --- /dev/null +++ b/src/ServerManager.Discord/Delegates/HandleTranslationDelegate.cs @@ -0,0 +1,4 @@ +namespace ServerManagerTool.DiscordBot.Delegates +{ + public delegate string HandleTranslationDelegate(string translationKey); +} diff --git a/src/ServerManager.Discord/DiscordBot.cs b/src/ServerManager.Discord/DiscordBot.cs index 976cc984..63cc1c7a 100644 --- a/src/ServerManager.Discord/DiscordBot.cs +++ b/src/ServerManager.Discord/DiscordBot.cs @@ -1,6 +1,6 @@ -using ServerManagerTool.Discord.Delegates; +using ServerManagerTool.DiscordBot.Delegates; -namespace ServerManagerTool.Discord +namespace ServerManagerTool.DiscordBot { public static class DiscordBot { diff --git a/src/ServerManager.Discord/Enums/CommandType.cs b/src/ServerManager.Discord/Enums/CommandType.cs index 1da59236..efe398a8 100644 --- a/src/ServerManager.Discord/Enums/CommandType.cs +++ b/src/ServerManager.Discord/Enums/CommandType.cs @@ -1,14 +1,15 @@ -namespace ServerManagerTool.Discord.Enums +namespace ServerManagerTool.DiscordBot.Enums { public enum CommandType { - BackupServer, - ServerInfo, - ServerList, - ServerStatus, - ShutdownServer, - StartServer, - StopServer, - UpdateServer, + Info, + List, + Status, + + Backup, + Shutdown, + Start, + Stop, + Update, } } diff --git a/src/ServerManager.Discord/Interfaces/IServerManagerBot.cs b/src/ServerManager.Discord/Interfaces/IServerManagerBot.cs index 4b6714bc..1d5867af 100644 --- a/src/ServerManager.Discord/Interfaces/IServerManagerBot.cs +++ b/src/ServerManager.Discord/Interfaces/IServerManagerBot.cs @@ -1,11 +1,11 @@ -using ServerManagerTool.Discord.Delegates; +using ServerManagerTool.DiscordBot.Delegates; using System.Threading; using System.Threading.Tasks; -namespace ServerManagerTool.Discord.Interfaces +namespace ServerManagerTool.DiscordBot.Interfaces { public interface IServerManagerBot { - Task StartAsync(string discordToken, string commandPrefix, string dataDirectory, HandleCommandDelegate handleCommandCallback, CancellationToken token); + Task StartAsync(string discordToken, string commandPrefix, string dataDirectory, HandleCommandDelegate handleCommandCallback, HandleTranslationDelegate handleTranslationCallback, CancellationToken token); } } diff --git a/src/ServerManager.Discord/Modules/HelpModule.cs b/src/ServerManager.Discord/Modules/HelpModule.cs index d4b70531..003da7a1 100644 --- a/src/ServerManager.Discord/Modules/HelpModule.cs +++ b/src/ServerManager.Discord/Modules/HelpModule.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -namespace ServerManagerTool.Discord.Modules +namespace ServerManagerTool.DiscordBot.Modules { [Name("Help")] public sealed class HelpModule : ModuleBase @@ -26,6 +26,7 @@ namespace ServerManagerTool.Discord.Modules [Command("help")] [Summary("Provides a list of available commands")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task HelpAsync() { var prefix = _config["DiscordSettings:Prefix"]; @@ -102,6 +103,7 @@ namespace ServerManagerTool.Discord.Modules [Command("help")] [Summary("Searches a list of available commands")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task HelpAsync(string command) { var searchResults = _service.Search(Context, command); diff --git a/src/ServerManager.Discord/Modules/ServerCommandModule.cs b/src/ServerManager.Discord/Modules/ServerCommandModule.cs index 49921a6a..6948f4bc 100644 --- a/src/ServerManager.Discord/Modules/ServerCommandModule.cs +++ b/src/ServerManager.Discord/Modules/ServerCommandModule.cs @@ -1,12 +1,13 @@ -using Discord.Addons.Interactive; +using Discord; +using Discord.Addons.Interactive; using Discord.Commands; using Microsoft.Extensions.Configuration; -using ServerManagerTool.Discord.Delegates; -using ServerManagerTool.Discord.Enums; +using ServerManagerTool.DiscordBot.Delegates; +using ServerManagerTool.DiscordBot.Enums; using System; using System.Threading.Tasks; -namespace ServerManagerTool.Discord.Modules +namespace ServerManagerTool.DiscordBot.Modules { [Name("Server Commands")] public sealed class ServerCommandModule : InteractiveBase @@ -25,6 +26,7 @@ namespace ServerManagerTool.Discord.Modules [Command("backup", RunMode = RunMode.Async)] [Summary("Perform a backup of the server")] [Remarks("backup")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task BackupServerAsync() { await BackupServerAsync(null); @@ -33,6 +35,7 @@ namespace ServerManagerTool.Discord.Modules [Command("backup", RunMode = RunMode.Async)] [Summary("Perform a backup of the server")] [Remarks("backup profileId")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task BackupServerAsync(string profileId) { try @@ -40,8 +43,8 @@ namespace ServerManagerTool.Discord.Modules var serverId = Context?.Guild?.Id.ToString() ?? string.Empty; var channelId = Context?.Channel?.Id.ToString() ?? string.Empty; - var response = _handleCommandCallback?.Invoke(CommandType.BackupServer, serverId, channelId, profileId); - if (response is null || response.Count == 0) + var response = _handleCommandCallback?.Invoke(CommandType.Backup, serverId, channelId, profileId); + if (response is null) { await ReplyAsync("No servers associated with this channel."); } @@ -49,7 +52,7 @@ namespace ServerManagerTool.Discord.Modules { foreach (var output in response) { - await ReplyAsync(output); + await ReplyAsync(output.Replace("&", "_")); await Task.Delay(1000); } } @@ -63,6 +66,7 @@ namespace ServerManagerTool.Discord.Modules [Command("shutdown", RunMode = RunMode.Async)] [Summary("Shuts down the server properly")] [Remarks("shutdown")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task ShutdownServerAsync() { await ShutdownServerAsync(null); @@ -71,6 +75,7 @@ namespace ServerManagerTool.Discord.Modules [Command("shutdown", RunMode = RunMode.Async)] [Summary("Shuts down the server properly")] [Remarks("shutdown profileId")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task ShutdownServerAsync(string profileId) { try @@ -78,8 +83,8 @@ namespace ServerManagerTool.Discord.Modules var serverId = Context?.Guild?.Id.ToString() ?? string.Empty; var channelId = Context?.Channel?.Id.ToString() ?? string.Empty; - var response = _handleCommandCallback?.Invoke(CommandType.ShutdownServer, serverId, channelId, profileId); - if (response is null || response.Count == 0) + var response = _handleCommandCallback?.Invoke(CommandType.Shutdown, serverId, channelId, profileId); + if (response is null) { await ReplyAsync("No servers associated with this channel."); } @@ -87,7 +92,7 @@ namespace ServerManagerTool.Discord.Modules { foreach (var output in response) { - await ReplyAsync(output); + await ReplyAsync(output.Replace("&", "_")); await Task.Delay(1000); } } @@ -101,6 +106,7 @@ namespace ServerManagerTool.Discord.Modules [Command("start", RunMode = RunMode.Async)] [Summary("Starts the server")] [Remarks("start")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task StartServerAsync() { await StartServerAsync(null); @@ -109,6 +115,7 @@ namespace ServerManagerTool.Discord.Modules [Command("start", RunMode = RunMode.Async)] [Summary("Starts the server")] [Remarks("start profileId")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task StartServerAsync(string profileId) { try @@ -116,8 +123,8 @@ namespace ServerManagerTool.Discord.Modules var serverId = Context?.Guild?.Id.ToString() ?? string.Empty; var channelId = Context?.Channel?.Id.ToString() ?? string.Empty; - var response = _handleCommandCallback?.Invoke(CommandType.StartServer, serverId, channelId, profileId); - if (response is null || response.Count == 0) + var response = _handleCommandCallback?.Invoke(CommandType.Start, serverId, channelId, profileId); + if (response is null) { await ReplyAsync("No servers associated with this channel."); } @@ -125,7 +132,7 @@ namespace ServerManagerTool.Discord.Modules { foreach (var output in response) { - await ReplyAsync(output); + await ReplyAsync(output.Replace("&", "_")); await Task.Delay(1000); } } @@ -139,6 +146,7 @@ namespace ServerManagerTool.Discord.Modules [Command("stop", RunMode = RunMode.Async)] [Summary("Forcibly stops the server")] [Remarks("stop")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task StopServerAsync() { await StopServerAsync(null); @@ -147,6 +155,7 @@ namespace ServerManagerTool.Discord.Modules [Command("stop", RunMode = RunMode.Async)] [Summary("Forcibly stops the server")] [Remarks("stop profileId")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task StopServerAsync(string profileId) { try @@ -154,8 +163,8 @@ namespace ServerManagerTool.Discord.Modules var serverId = Context?.Guild?.Id.ToString() ?? string.Empty; var channelId = Context?.Channel?.Id.ToString() ?? string.Empty; - var response = _handleCommandCallback?.Invoke(CommandType.StopServer, serverId, channelId, profileId); - if (response is null || response.Count == 0) + var response = _handleCommandCallback?.Invoke(CommandType.Stop, serverId, channelId, profileId); + if (response is null) { await ReplyAsync("No servers associated with this channel."); } @@ -163,7 +172,7 @@ namespace ServerManagerTool.Discord.Modules { foreach (var output in response) { - await ReplyAsync(output); + await ReplyAsync(output.Replace("&", "_")); await Task.Delay(1000); } } @@ -177,6 +186,7 @@ namespace ServerManagerTool.Discord.Modules [Command("update", RunMode = RunMode.Async)] [Summary("Updates the server")] [Remarks("update")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task UpdateServerAsync() { await UpdateServerAsync(null); @@ -185,6 +195,7 @@ namespace ServerManagerTool.Discord.Modules [Command("update", RunMode = RunMode.Async)] [Summary("Updates the server")] [Remarks("update profileId")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task UpdateServerAsync(string profileId) { try @@ -192,8 +203,8 @@ namespace ServerManagerTool.Discord.Modules var serverId = Context?.Guild?.Id.ToString() ?? string.Empty; var channelId = Context?.Channel?.Id.ToString() ?? string.Empty; - var response = _handleCommandCallback?.Invoke(CommandType.UpdateServer, serverId, channelId, profileId); - if (response is null || response.Count == 0) + var response = _handleCommandCallback?.Invoke(CommandType.Update, serverId, channelId, profileId); + if (response is null) { await ReplyAsync("No servers associated with this channel."); } @@ -201,7 +212,7 @@ namespace ServerManagerTool.Discord.Modules { foreach (var output in response) { - await ReplyAsync(output); + await ReplyAsync(output.Replace("&", "_")); await Task.Delay(1000); } } diff --git a/src/ServerManager.Discord/Modules/ServerQueryModule.cs b/src/ServerManager.Discord/Modules/ServerQueryModule.cs index 767a3413..c4d89e6b 100644 --- a/src/ServerManager.Discord/Modules/ServerQueryModule.cs +++ b/src/ServerManager.Discord/Modules/ServerQueryModule.cs @@ -1,12 +1,13 @@ -using Discord.Addons.Interactive; +using Discord; +using Discord.Addons.Interactive; using Discord.Commands; using Microsoft.Extensions.Configuration; -using ServerManagerTool.Discord.Delegates; -using ServerManagerTool.Discord.Enums; +using ServerManagerTool.DiscordBot.Delegates; +using ServerManagerTool.DiscordBot.Enums; using System; using System.Threading.Tasks; -namespace ServerManagerTool.Discord.Modules +namespace ServerManagerTool.DiscordBot.Modules { [Name("Server Query")] public sealed class ServerQueryModule : InteractiveBase @@ -25,6 +26,7 @@ namespace ServerManagerTool.Discord.Modules [Command("info", RunMode = RunMode.Async)] [Summary("Poll server for information")] [Remarks("info")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task ServerInfoAsync() { await ServerInfoAsync(null); @@ -33,6 +35,7 @@ namespace ServerManagerTool.Discord.Modules [Command("info", RunMode = RunMode.Async)] [Summary("Poll server for information")] [Remarks("info profileId")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task ServerInfoAsync(string profileId) { try @@ -40,8 +43,8 @@ namespace ServerManagerTool.Discord.Modules var serverId = Context?.Guild?.Id.ToString() ?? string.Empty; var channelId = Context?.Channel?.Id.ToString() ?? string.Empty; - var response = _handleCommandCallback?.Invoke(CommandType.ServerInfo, serverId, channelId, profileId); - if (response is null || response.Count == 0) + var response = _handleCommandCallback?.Invoke(CommandType.Info, serverId, channelId, profileId); + if (response is null) { await ReplyAsync("No servers associated with this channel."); } @@ -49,7 +52,7 @@ namespace ServerManagerTool.Discord.Modules { foreach (var output in response) { - await ReplyAsync(output); + await ReplyAsync(output.Replace("&", "_")); await Task.Delay(1000); } } @@ -63,6 +66,7 @@ namespace ServerManagerTool.Discord.Modules [Command("list", RunMode = RunMode.Async)] [Summary("List of all servers associated with this channel")] [Remarks("list")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task ServerListAsync() { try @@ -70,8 +74,8 @@ namespace ServerManagerTool.Discord.Modules var serverId = Context?.Guild?.Id.ToString() ?? string.Empty; var channelId = Context?.Channel?.Id.ToString() ?? string.Empty; - var response = _handleCommandCallback?.Invoke(CommandType.ServerList, serverId, channelId, null); - if (response is null || response.Count == 0) + var response = _handleCommandCallback?.Invoke(CommandType.List, serverId, channelId, null); + if (response is null) { await ReplyAsync("No servers associated with this channel."); } @@ -79,7 +83,7 @@ namespace ServerManagerTool.Discord.Modules { foreach (var output in response) { - await ReplyAsync(output); + await ReplyAsync(output.Replace("&", "_")); await Task.Delay(1000); } } @@ -93,6 +97,7 @@ namespace ServerManagerTool.Discord.Modules [Command("status", RunMode = RunMode.Async)] [Summary("Poll server for status")] [Remarks("status")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task ServerStatusAsync() { await ServerStatusAsync(null); @@ -101,6 +106,7 @@ namespace ServerManagerTool.Discord.Modules [Command("status", RunMode = RunMode.Async)] [Summary("Poll server for status")] [Remarks("status profileId")] + [RequireBotPermission(ChannelPermission.ViewChannel | ChannelPermission.SendMessages)] public async Task ServerStatusAsync(string profileId) { try @@ -108,8 +114,8 @@ namespace ServerManagerTool.Discord.Modules var serverId = Context?.Guild?.Id.ToString() ?? string.Empty; var channelId = Context?.Channel?.Id.ToString() ?? string.Empty; - var response = _handleCommandCallback?.Invoke(CommandType.ServerStatus, serverId, channelId, profileId); - if (response is null || response.Count == 0) + var response = _handleCommandCallback?.Invoke(CommandType.Status, serverId, channelId, profileId); + if (response is null) { await ReplyAsync("No servers associated with this channel."); } @@ -117,7 +123,7 @@ namespace ServerManagerTool.Discord.Modules { foreach (var output in response) { - await ReplyAsync(output); + await ReplyAsync(output.Replace("&", "_")); await Task.Delay(1000); } } diff --git a/src/ServerManager.Discord/ServerManager.Discord.csproj b/src/ServerManager.Discord/ServerManager.Discord.csproj index 51a6255d..3a28fd00 100644 --- a/src/ServerManager.Discord/ServerManager.Discord.csproj +++ b/src/ServerManager.Discord/ServerManager.Discord.csproj @@ -5,7 +5,7 @@ net462 false - ServerManagerTool.Discord + ServerManagerTool.DiscordBot none diff --git a/src/ServerManager.Discord/ServerManagerBot.cs b/src/ServerManager.Discord/ServerManagerBot.cs index 72e44731..3b5fedab 100644 --- a/src/ServerManager.Discord/ServerManagerBot.cs +++ b/src/ServerManager.Discord/ServerManagerBot.cs @@ -5,9 +5,9 @@ using Discord.Net.Providers.WS4Net; using Discord.WebSocket; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using ServerManagerTool.Discord.Delegates; -using ServerManagerTool.Discord.Interfaces; -using ServerManagerTool.Discord.Services; +using ServerManagerTool.DiscordBot.Delegates; +using ServerManagerTool.DiscordBot.Interfaces; +using ServerManagerTool.DiscordBot.Services; using System; using System.Collections.Generic; using System.Diagnostics; @@ -15,7 +15,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -namespace ServerManagerTool.Discord +namespace ServerManagerTool.DiscordBot { public sealed class ServerManagerBot : IServerManagerBot { @@ -30,7 +30,7 @@ namespace ServerManagerTool.Discord set; } - public async Task StartAsync(string discordToken, string commandPrefix, string dataDirectory, HandleCommandDelegate handleCommandCallback, CancellationToken token) + public async Task StartAsync(string discordToken, string commandPrefix, string dataDirectory, HandleCommandDelegate handleCommandCallback, HandleTranslationDelegate handleTranslationCallback, CancellationToken token) { if (Started) { @@ -38,7 +38,7 @@ namespace ServerManagerTool.Discord } Started = true; - if (string.IsNullOrWhiteSpace(commandPrefix) || string.IsNullOrWhiteSpace(discordToken) || handleCommandCallback is null) + if (string.IsNullOrWhiteSpace(commandPrefix) || string.IsNullOrWhiteSpace(discordToken) || handleTranslationCallback is null || handleCommandCallback is null) { return; } @@ -55,8 +55,8 @@ namespace ServerManagerTool.Discord var settings = new Dictionary { - { "DiscordSettings:Prefix", commandPrefix }, { "DiscordSettings:Token", discordToken }, + { "DiscordSettings:Prefix", commandPrefix }, { "ServerManager:DataDirectory", dataDirectory } }; @@ -106,7 +106,8 @@ namespace ServerManagerTool.Discord .AddSingleton() .AddSingleton() .AddSingleton(config) - .AddSingleton(handleCommandCallback); + .AddSingleton(handleCommandCallback) + .AddSingleton(handleTranslationCallback); // Create the service provider using (var provider = services.BuildServiceProvider()) diff --git a/src/ServerManager.Discord/ServerManagerBotFactory.cs b/src/ServerManager.Discord/ServerManagerBotFactory.cs index f4143d5a..f4b78128 100644 --- a/src/ServerManager.Discord/ServerManagerBotFactory.cs +++ b/src/ServerManager.Discord/ServerManagerBotFactory.cs @@ -1,6 +1,6 @@ -using ServerManagerTool.Discord.Interfaces; +using ServerManagerTool.DiscordBot.Interfaces; -namespace ServerManagerTool.Discord +namespace ServerManagerTool.DiscordBot { public static class ServerManagerBotFactory { diff --git a/src/ServerManager.Discord/Services/CommandHandlerService.cs b/src/ServerManager.Discord/Services/CommandHandlerService.cs index a4578631..dcb2f917 100644 --- a/src/ServerManager.Discord/Services/CommandHandlerService.cs +++ b/src/ServerManager.Discord/Services/CommandHandlerService.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.Configuration; using System; using System.Threading.Tasks; -namespace ServerManagerTool.Discord.Services +namespace ServerManagerTool.DiscordBot.Services { public class CommandHandlerService { diff --git a/src/ServerManager.Discord/Services/LoggingService.cs b/src/ServerManager.Discord/Services/LoggingService.cs index de540d9d..03b0d34e 100644 --- a/src/ServerManager.Discord/Services/LoggingService.cs +++ b/src/ServerManager.Discord/Services/LoggingService.cs @@ -6,7 +6,7 @@ using System; using System.IO; using System.Threading.Tasks; -namespace ServerManagerTool.Discord.Services +namespace ServerManagerTool.DiscordBot.Services { public class LoggingService { diff --git a/src/ServerManager.Discord/Services/ShutdownService.cs b/src/ServerManager.Discord/Services/ShutdownService.cs index 65d816f5..d940c57d 100644 --- a/src/ServerManager.Discord/Services/ShutdownService.cs +++ b/src/ServerManager.Discord/Services/ShutdownService.cs @@ -1,7 +1,7 @@ using Discord.WebSocket; using System.Threading.Tasks; -namespace ServerManagerTool.Discord.Services +namespace ServerManagerTool.DiscordBot.Services { public class ShutdownService { diff --git a/src/ServerManager.Discord/Services/StartupService.cs b/src/ServerManager.Discord/Services/StartupService.cs index 98f63328..aee2f846 100644 --- a/src/ServerManager.Discord/Services/StartupService.cs +++ b/src/ServerManager.Discord/Services/StartupService.cs @@ -6,7 +6,7 @@ using System; using System.Reflection; using System.Threading.Tasks; -namespace ServerManagerTool.Discord.Services +namespace ServerManagerTool.DiscordBot.Services { public class StartupService {