diff --git a/ChatTwo/Http/MessageProtocol/DataStructure.cs b/ChatTwo/Http/MessageProtocol/DataStructure.cs index 14b5157..d7a3112 100644 --- a/ChatTwo/Http/MessageProtocol/DataStructure.cs +++ b/ChatTwo/Http/MessageProtocol/DataStructure.cs @@ -2,6 +2,7 @@ namespace ChatTwo.Http.MessageProtocol; +#region Outgoing public struct SwitchChannel(string name) { [JsonProperty("channel")] public string Name = name; @@ -21,4 +22,17 @@ public struct MessageResponse() { [JsonProperty("timestamp")] public string Timestamp = ""; [JsonProperty("messageHTML")] public string Message = ""; -} \ No newline at end of file +} +#endregion + +#region Incoming +public struct IncomingMessage() +{ + [JsonProperty("message")] public string Message = string.Empty; +} + +public struct IncomingChannel() +{ + [JsonProperty("channel")] public uint Channel = uint.MaxValue; +} +#endregion \ No newline at end of file diff --git a/ChatTwo/Http/RouteController.cs b/ChatTwo/Http/RouteController.cs index 99e1226..8025a64 100644 --- a/ChatTwo/Http/RouteController.cs +++ b/ChatTwo/Http/RouteController.cs @@ -1,10 +1,12 @@ using System.Collections.Concurrent; using System.Web; +using ChatTwo.Code; using ChatTwo.Http.MessageProtocol; using ChatTwo.Util; using Lumina.Data.Files; +using Newtonsoft.Json; using WatsonWebserver.Core; - +using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; using HttpMethod = WatsonWebserver.Core.HttpMethod; namespace ChatTwo.Http; @@ -20,6 +22,11 @@ public class RouteController private readonly ConcurrentDictionary RateLimit = []; internal readonly ConcurrentDictionary SessionTokens = []; + private readonly JsonSerializerSettings JsonSettings = new() + { + Error = delegate(object? sender, ErrorEventArgs args) { args.ErrorContext.Handled = true; } + }; + public RouteController(Plugin plugin, ServerCore core) { Plugin = plugin; @@ -40,7 +47,7 @@ public class RouteController // Post Auth Core.HostContext.Routes.PostAuthentication.Static.Add(HttpMethod.GET, "/chat", ChatBoxRoute, ExceptionRoute); Core.HostContext.Routes.PostAuthentication.Static.Add(HttpMethod.POST, "/send", ReceiveMessage, ExceptionRoute); - Core.HostContext.Routes.PostAuthentication.Static.Add(HttpMethod.POST, "/switch", ReceiveChannelSwitch, ExceptionRoute); + Core.HostContext.Routes.PostAuthentication.Static.Add(HttpMethod.POST, "/channel", ReceiveChannelSwitch, ExceptionRoute); // Server-Sent Events Route Core.HostContext.Routes.PostAuthentication.Static.Add(HttpMethod.GET, "/sse", NewSSEConnection, ExceptionRoute); @@ -141,16 +148,22 @@ public class RouteController private async Task ReceiveMessage(HttpContextBase ctx) { - var content = ctx.Request.DataAsString; - if (content.Length is > 500 or < 2) + if (ctx.Request.ContentType != "application/json") { - await ctx.Response.Send("Invalid length for a chat message received."); + await ctx.Response.Send("Request contains wrong content type."); + return; + } + + var content = JsonConvert.DeserializeObject(ctx.Request.DataAsString, JsonSettings); + if (content.Message.Length is < 2 or > 500) + { + await ctx.Response.Send("Invalid message received."); return; } await Plugin.Framework.RunOnFrameworkThread(() => { - Plugin.ChatLogWindow.Chat = content; + Plugin.ChatLogWindow.Chat = content.Message; Plugin.ChatLogWindow.SendChatBox(Plugin.ChatLogWindow.CurrentTab); }); @@ -159,20 +172,25 @@ public class RouteController private async Task ReceiveChannelSwitch(HttpContextBase ctx) { - var content = ctx.Request.DataAsString; - if (content.Length is > 500 or < 2) + if (ctx.Request.ContentType != "application/json") { - await ctx.Response.Send("Invalid length for a chat message received."); + await ctx.Response.Send("Request contains wrong content type."); + return; + } + + var channel = JsonConvert.DeserializeObject(ctx.Request.DataAsString, JsonSettings); + if (!Enum.IsDefined(typeof(InputChannel), channel.Channel)) + { + await ctx.Response.Send("Invalid channel received."); return; } await Plugin.Framework.RunOnFrameworkThread(() => { - Plugin.ChatLogWindow.Chat = content; - Plugin.ChatLogWindow.SendChatBox(Plugin.ChatLogWindow.CurrentTab); + Plugin.ChatLogWindow.SetChannel((InputChannel)channel.Channel); }); - await ctx.Response.Send("Message was send to the channel."); + await ctx.Response.Send("Function to switch channels has been called."); } private async Task NewSSEConnection(HttpContextBase ctx) diff --git a/ChatTwo/Http/static/start.js b/ChatTwo/Http/static/start.js index 9149221..ba6ebac 100644 --- a/ChatTwo/Http/static/start.js +++ b/ChatTwo/Http/static/start.js @@ -38,8 +38,20 @@ function updateChannelHint(label) { } document.getElementById('channel-select').addEventListener('change', (event) => { - // TODO: send new channel to "backend" - // ws.send(...); + (async () => { + const rawResponse = await fetch('/channel', { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({channel: event.target.value}) + }); + const content = await rawResponse.json(); + + // TODO use the response + console.log(content); + })(); }); function updateChannelOptions(channels) { @@ -122,6 +134,21 @@ document.querySelector('#input > form').addEventListener('submit', (event) => { } }); + (async () => { + const rawResponse = await fetch('/send', { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify({message: message}) + }); + const content = await rawResponse.json(); + + // TODO use the response + console.log(content); + })(); + chatInput.value = ''; });