From 86b9d39266bae9860c58650fa7c837922586c467 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 27 Feb 2025 17:39:39 -0800 Subject: [PATCH 1/6] implement ``BanCommand`` --- src/Management/Commands/BanCommand.cs | 34 +++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/Management/Commands/BanCommand.cs diff --git a/src/Management/Commands/BanCommand.cs b/src/Management/Commands/BanCommand.cs new file mode 100644 index 0000000..0b26233 --- /dev/null +++ b/src/Management/Commands/BanCommand.cs @@ -0,0 +1,34 @@ +using System; +using System.Net.Http.Json; +using sodoffmmo.Attributes; +using sodoffmmo.Core; + +namespace sodoffmmo.Management.Commands; + +[ManagementCommand("ban", Role.Moderator)] +class BanCommand : IManagementCommand +{ + public void Handle(Client client, string[] arguments) + { + if(arguments.Length < 2) { client.Send(Utils.BuildServerSideMessage($"Expected 3 Args, Got {arguments.Length + 1}", "Server")); return; } + + // send an http request to the api set in appsettings + HttpClient httpClient = new(); + var content = new FormUrlEncodedContent( + new Dictionary { + { "token", client.PlayerData.UNToken }, + { "userId", arguments[0] }, + { "banType", arguments[1] }, + { "days", arguments[2] } + } + ); + + httpClient.Timeout = new TimeSpan(0, 0, 3); + var response = httpClient.PostAsync($"{Configuration.ServerConfiguration.ApiUrl}/Moderation/AddBanToVikingByGuid", content).Result; + string? responseString = response.Content.ReadAsStringAsync().Result; + + if (response.StatusCode != System.Net.HttpStatusCode.OK && responseString != null) { client.Send(Utils.BuildServerSideMessage(responseString, "Server")); return; } + else if (responseString != null) { client.Send(Utils.BuildServerSideMessage("User Banned Successfully", "Server")); return; } + else { client.Send(Utils.BuildServerSideMessage("Empty Response", "Server")); } + } +} From 998efe56246c77d0f2592be8b0d3b78546566c95 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 27 Feb 2025 18:00:46 -0800 Subject: [PATCH 2/6] add ``UserBanType`` schema from API modify ``ChatMessageHandler.Chat`` to check for bans before sending out message --- src/CommandHandlers/ChatMessageHandler.cs | 19 ++++++++++++++++++- src/Core/UserBanType.cs | 10 ++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/Core/UserBanType.cs diff --git a/src/CommandHandlers/ChatMessageHandler.cs b/src/CommandHandlers/ChatMessageHandler.cs index ffdacf7..d573a5b 100644 --- a/src/CommandHandlers/ChatMessageHandler.cs +++ b/src/CommandHandlers/ChatMessageHandler.cs @@ -1,4 +1,6 @@ -using sodoffmmo.Attributes; +using System.Net; +using System.Net.Http.Json; +using sodoffmmo.Attributes; using sodoffmmo.Core; using sodoffmmo.Data; using sodoffmmo.Management; @@ -37,6 +39,21 @@ class ChatMessageHandler : CommandHandler { return; } + // send an http request to api to check for 'IndefiniteOpenChatBan' or 'TemporaryOpenChatBan' + HttpClient httpClient = new(); + var content = new FormUrlEncodedContent( + new Dictionary { + { "token", client.PlayerData.UNToken } + } + ); + + httpClient.Timeout = new TimeSpan(0, 0, 3); + var response = httpClient.PostAsync($"{Configuration.ServerConfiguration.ApiUrl}/Moderation/CheckForVikingBan", content).Result; + UserBanType? banType = response.Content.ReadFromJsonAsync().Result; + + if (banType != null && (banType == UserBanType.IndefiniteOpenChatBan || banType == UserBanType.TemporaryOpenChatBan)) + { client.Send(Utils.ArrNetworkPacket(new string[] { "CB", "-1", "1" }, "CB")); return; } + client.Room.Send(Utils.BuildChatMessage(client.PlayerData.Uid, message, client.PlayerData.DiplayName), client); NetworkObject cmd = new(); diff --git a/src/Core/UserBanType.cs b/src/Core/UserBanType.cs new file mode 100644 index 0000000..294ba61 --- /dev/null +++ b/src/Core/UserBanType.cs @@ -0,0 +1,10 @@ +namespace sodoffmmo.Core; + +public enum UserBanType +{ + NotBanned = 0, + IndefiniteOpenChatBan = 1, + TemporaryOpenChatBan = 2, + IndefiniteAccountBan = 3, + TemporaryAccountBan = 4 +} From e1c19b792c71e8e1b5e3d3917ba3f4f465d5e359 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Thu, 27 Feb 2025 18:57:30 -0800 Subject: [PATCH 3/6] require authentication send ``SMF`` if chat ban is detected --- src/CommandHandlers/ChatMessageHandler.cs | 2 +- src/appsettings.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CommandHandlers/ChatMessageHandler.cs b/src/CommandHandlers/ChatMessageHandler.cs index d573a5b..066f574 100644 --- a/src/CommandHandlers/ChatMessageHandler.cs +++ b/src/CommandHandlers/ChatMessageHandler.cs @@ -52,7 +52,7 @@ class ChatMessageHandler : CommandHandler { UserBanType? banType = response.Content.ReadFromJsonAsync().Result; if (banType != null && (banType == UserBanType.IndefiniteOpenChatBan || banType == UserBanType.TemporaryOpenChatBan)) - { client.Send(Utils.ArrNetworkPacket(new string[] { "CB", "-1", "1" }, "CB")); return; } + { client.Send(Utils.ArrNetworkPacket(new string[] { "SMF", "-1", "CB", "1", "Sorry, You've Been Banned From Using Type Chat", "1" }, "SMF")); return; } client.Room.Send(Utils.BuildChatMessage(client.PlayerData.Uid, message, client.PlayerData.DiplayName), client); diff --git a/src/appsettings.json b/src/appsettings.json index a9a6b85..db66cae 100644 --- a/src/appsettings.json +++ b/src/appsettings.json @@ -61,7 +61,7 @@ "// Authentication Optional": "authentication is required only for moderation activities", "// Authentication RequiredForChat": "authentication is required only for moderation activities and using chat (if chat is enabled)", "// Authentication Required": "authentication is required to connect to mmo", - "Authentication": "Disabled", + "Authentication": "Required", "// ApiUrl": "SoDOff API server URL for authentication calls", "ApiUrl": "http://localhost:5000", From 53db86f3c71808d8c70f42d21f7a7b98d4737ee3 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Sun, 2 Mar 2025 14:52:58 -0800 Subject: [PATCH 4/6] implement ``ApiWebService`` change ``ChatMessageHandler`` and ``BanCommand`` to use it --- src/CommandHandlers/ChatMessageHandler.cs | 12 ++----- src/Core/ApiWebService.cs | 38 +++++++++++++++++++++++ src/Management/Commands/BanCommand.cs | 16 ++-------- 3 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 src/Core/ApiWebService.cs diff --git a/src/CommandHandlers/ChatMessageHandler.cs b/src/CommandHandlers/ChatMessageHandler.cs index 066f574..fb754fc 100644 --- a/src/CommandHandlers/ChatMessageHandler.cs +++ b/src/CommandHandlers/ChatMessageHandler.cs @@ -40,16 +40,8 @@ class ChatMessageHandler : CommandHandler { } // send an http request to api to check for 'IndefiniteOpenChatBan' or 'TemporaryOpenChatBan' - HttpClient httpClient = new(); - var content = new FormUrlEncodedContent( - new Dictionary { - { "token", client.PlayerData.UNToken } - } - ); - - httpClient.Timeout = new TimeSpan(0, 0, 3); - var response = httpClient.PostAsync($"{Configuration.ServerConfiguration.ApiUrl}/Moderation/CheckForVikingBan", content).Result; - UserBanType? banType = response.Content.ReadFromJsonAsync().Result; + ApiWebService apiWebService = new(); + var banType = apiWebService.CheckForUserBan(client); if (banType != null && (banType == UserBanType.IndefiniteOpenChatBan || banType == UserBanType.TemporaryOpenChatBan)) { client.Send(Utils.ArrNetworkPacket(new string[] { "SMF", "-1", "CB", "1", "Sorry, You've Been Banned From Using Type Chat", "1" }, "SMF")); return; } diff --git a/src/Core/ApiWebService.cs b/src/Core/ApiWebService.cs new file mode 100644 index 0000000..5612a38 --- /dev/null +++ b/src/Core/ApiWebService.cs @@ -0,0 +1,38 @@ +using System; +using System.Net.Http.Json; + +namespace sodoffmmo.Core; + +public class ApiWebService +{ + public UserBanType? CheckForUserBan(Client client) + { + HttpClient httpClient = new(); + var content = new FormUrlEncodedContent( + new Dictionary { + { "token", client.PlayerData.UNToken } + } + ); + httpClient.Timeout = new TimeSpan(0, 0, 3); + + var response = httpClient.PostAsync($"{Configuration.ServerConfiguration.ApiUrl}/Moderation/CheckForVikingBan", content).Result; + if (response.StatusCode == System.Net.HttpStatusCode.OK && response.Content != null) return response.Content.ReadFromJsonAsync().Result; + else return null; + } + + public HttpResponseMessage BanUser(Client client, string userId, string banType, string days) + { + HttpClient httpClient = new(); + var content = new FormUrlEncodedContent( + new Dictionary { + { "token", client.PlayerData.UNToken }, + { "userId", userId }, + { "banType", banType }, + { "days", days } + } + ); + httpClient.Timeout = new TimeSpan(0, 0, 3); + var response = httpClient.PostAsync($"{Configuration.ServerConfiguration.ApiUrl}/Moderation/AddBanToVikingByGuid", content).Result; + return response; + } +} diff --git a/src/Management/Commands/BanCommand.cs b/src/Management/Commands/BanCommand.cs index 0b26233..a772172 100644 --- a/src/Management/Commands/BanCommand.cs +++ b/src/Management/Commands/BanCommand.cs @@ -13,19 +13,9 @@ class BanCommand : IManagementCommand if(arguments.Length < 2) { client.Send(Utils.BuildServerSideMessage($"Expected 3 Args, Got {arguments.Length + 1}", "Server")); return; } // send an http request to the api set in appsettings - HttpClient httpClient = new(); - var content = new FormUrlEncodedContent( - new Dictionary { - { "token", client.PlayerData.UNToken }, - { "userId", arguments[0] }, - { "banType", arguments[1] }, - { "days", arguments[2] } - } - ); - - httpClient.Timeout = new TimeSpan(0, 0, 3); - var response = httpClient.PostAsync($"{Configuration.ServerConfiguration.ApiUrl}/Moderation/AddBanToVikingByGuid", content).Result; - string? responseString = response.Content.ReadAsStringAsync().Result; + ApiWebService apiWebService = new(); + var response = apiWebService.BanUser(client, arguments[0], arguments[1], arguments[2]); + var responseString = response.Content.ReadAsStringAsync().Result; if (response.StatusCode != System.Net.HttpStatusCode.OK && responseString != null) { client.Send(Utils.BuildServerSideMessage(responseString, "Server")); return; } else if (responseString != null) { client.Send(Utils.BuildServerSideMessage("User Banned Successfully", "Server")); return; } From 1edbbde74c5628485cf13c3dae8da779308be189 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Sun, 2 Mar 2025 15:17:55 -0800 Subject: [PATCH 5/6] rework ``BanCommand`` to take in a user id of someone in the room instead of a full guid edit comment at ``ApiUrl`` in appsettings.json --- src/Management/Commands/BanCommand.cs | 6 +++++- src/appsettings.json | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Management/Commands/BanCommand.cs b/src/Management/Commands/BanCommand.cs index a772172..86802c7 100644 --- a/src/Management/Commands/BanCommand.cs +++ b/src/Management/Commands/BanCommand.cs @@ -12,9 +12,13 @@ class BanCommand : IManagementCommand { if(arguments.Length < 2) { client.Send(Utils.BuildServerSideMessage($"Expected 3 Args, Got {arguments.Length + 1}", "Server")); return; } + if (arguments[0] == "help") client.Send(Utils.BuildServerSideMessage($"::ban - This bans a user who is in-room. First argument is the id of the user in-room. Room user lists start at 0.", "Server")); + var clientToBan = client.Room!.Clients.ToArray()[int.Parse(arguments[0])].PlayerData.Uid; + if (clientToBan == null) { client.Send(Utils.BuildServerSideMessage($"User Could Not Be Found", "Server")); return; } + // send an http request to the api set in appsettings ApiWebService apiWebService = new(); - var response = apiWebService.BanUser(client, arguments[0], arguments[1], arguments[2]); + var response = apiWebService.BanUser(client, clientToBan, arguments[1], arguments[2]); var responseString = response.Content.ReadAsStringAsync().Result; if (response.StatusCode != System.Net.HttpStatusCode.OK && responseString != null) { client.Send(Utils.BuildServerSideMessage(responseString, "Server")); return; } diff --git a/src/appsettings.json b/src/appsettings.json index db66cae..98a03f2 100644 --- a/src/appsettings.json +++ b/src/appsettings.json @@ -63,7 +63,7 @@ "// Authentication Required": "authentication is required to connect to mmo", "Authentication": "Required", - "// ApiUrl": "SoDOff API server URL for authentication calls", + "// ApiUrl": "SoDOff API server URL for authentication calls and other calls", "ApiUrl": "http://localhost:5000", "// BypassToken": "Token allowed to connect without authentication", From aa85aeab324ad4e90d3f2f0e87426ebc06447ea6 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Sun, 2 Mar 2025 15:54:49 -0800 Subject: [PATCH 6/6] add exception handling to ``ApiWebService`` improve ``BanCommand`` API response handling --- src/Core/ApiWebService.cs | 28 +++++++++++++++++++++------ src/Management/Commands/BanCommand.cs | 4 +--- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/Core/ApiWebService.cs b/src/Core/ApiWebService.cs index 5612a38..602ce9b 100644 --- a/src/Core/ApiWebService.cs +++ b/src/Core/ApiWebService.cs @@ -1,5 +1,6 @@ using System; using System.Net.Http.Json; +using sodoffmmo.CommandHandlers; namespace sodoffmmo.Core; @@ -15,12 +16,16 @@ public class ApiWebService ); httpClient.Timeout = new TimeSpan(0, 0, 3); - var response = httpClient.PostAsync($"{Configuration.ServerConfiguration.ApiUrl}/Moderation/CheckForVikingBan", content).Result; - if (response.StatusCode == System.Net.HttpStatusCode.OK && response.Content != null) return response.Content.ReadFromJsonAsync().Result; - else return null; + try + { + var response = httpClient.PostAsync($"{Configuration.ServerConfiguration.ApiUrl}/Moderation/CheckForVikingBan", content).Result; + Log("Moderation/CheckForVikingBan"); + if (response.StatusCode == System.Net.HttpStatusCode.OK && response.Content != null) return response.Content.ReadFromJsonAsync().Result; + else return null; + } catch (Exception e) { LogError(e.Message); return null; } } - public HttpResponseMessage BanUser(Client client, string userId, string banType, string days) + public string? BanUser(Client client, string userId, string banType, string days) { HttpClient httpClient = new(); var content = new FormUrlEncodedContent( @@ -32,7 +37,18 @@ public class ApiWebService } ); httpClient.Timeout = new TimeSpan(0, 0, 3); - var response = httpClient.PostAsync($"{Configuration.ServerConfiguration.ApiUrl}/Moderation/AddBanToVikingByGuid", content).Result; - return response; + + try + { + var response = httpClient.PostAsync($"{Configuration.ServerConfiguration.ApiUrl}/Moderation/AddBanToVikingByGuid", content).Result; + Log("Moderation/AddBanToVikingByGuid"); + + if (response.StatusCode == System.Net.HttpStatusCode.OK && response.Content != null) return response.Content.ReadAsStringAsync().Result; + else return null; + } catch (Exception e) { LogError(e.Message); return null; } } + + private void Log(string endpoint) => Console.WriteLine($"Sent API Request To {Configuration.ServerConfiguration.ApiUrl}/{endpoint}"); + + private void LogError(string message) => Console.WriteLine($"An Error Has Occured When Sending An API Request - {message}"); } diff --git a/src/Management/Commands/BanCommand.cs b/src/Management/Commands/BanCommand.cs index 86802c7..6f8e57a 100644 --- a/src/Management/Commands/BanCommand.cs +++ b/src/Management/Commands/BanCommand.cs @@ -19,10 +19,8 @@ class BanCommand : IManagementCommand // send an http request to the api set in appsettings ApiWebService apiWebService = new(); var response = apiWebService.BanUser(client, clientToBan, arguments[1], arguments[2]); - var responseString = response.Content.ReadAsStringAsync().Result; - if (response.StatusCode != System.Net.HttpStatusCode.OK && responseString != null) { client.Send(Utils.BuildServerSideMessage(responseString, "Server")); return; } - else if (responseString != null) { client.Send(Utils.BuildServerSideMessage("User Banned Successfully", "Server")); return; } + if (response != null) { client.Send(Utils.BuildServerSideMessage("User Banned Successfully", "Server")); return; } else { client.Send(Utils.BuildServerSideMessage("Empty Response", "Server")); } } }