diff --git a/Capy64/Configuration/HTTP.cs b/Capy64/Configuration/HTTP.cs deleted file mode 100644 index 6e0e1d7..0000000 --- a/Capy64/Configuration/HTTP.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Capy64.Configuration; - -class HTTP -{ - public bool Enable { get; set; } = true; - public string[] Blacklist { get; set; } - public WebSockets WebSockets { get; set; } -} diff --git a/Capy64/Configuration/WebSockets.cs b/Capy64/Configuration/WebSockets.cs deleted file mode 100644 index ab112ff..0000000 --- a/Capy64/Configuration/WebSockets.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Capy64.Configuration; - -class WebSockets -{ - public bool Enable { get; set; } = true; - public int MaxActiveConnections { get; set; } = 5; -} diff --git a/Capy64/LuaRuntime/Handlers/WebSocketHandle.cs b/Capy64/LuaRuntime/Handlers/WebSocketHandle.cs index 9c95721..a5ba4d3 100644 --- a/Capy64/LuaRuntime/Handlers/WebSocketHandle.cs +++ b/Capy64/LuaRuntime/Handlers/WebSocketHandle.cs @@ -1,4 +1,5 @@ -using KeraLua; +using Capy64.LuaRuntime.Libraries; +using KeraLua; using System; using System.Collections.Generic; using System.Linq; @@ -9,7 +10,7 @@ using System.Threading.Tasks; namespace Capy64.LuaRuntime.Handlers; -class WebSocketHandle : IHandle +public class WebSocketHandle : IHandle { private ClientWebSocket _client; private long _requestId; @@ -32,6 +33,16 @@ class WebSocketHandle : IHandle if (newTable) L.NewTable(); + // metatable + L.NewTable(); + L.PushString("__close"); + L.PushCFunction(L_CloseAsync); + L.SetTable(-3); + L.PushString("__gc"); + L.PushCFunction(L_CloseAsync); + L.SetTable(-3); + L.SetMetaTable(-2); + foreach (var pair in functions) { L.PushString(pair.Key); @@ -84,6 +95,8 @@ class WebSocketHandle : IHandle _game.LuaRuntime.PushEvent("websocket_close", h._requestId); }); + HTTP.WebSocketConnections.Remove(h); + return 0; } } diff --git a/Capy64/LuaRuntime/Libraries/HTTP.cs b/Capy64/LuaRuntime/Libraries/HTTP.cs index d0c0bc1..5a73e28 100644 --- a/Capy64/LuaRuntime/Libraries/HTTP.cs +++ b/Capy64/LuaRuntime/Libraries/HTTP.cs @@ -18,10 +18,11 @@ public class HTTP : IPlugin private static IGame _game; private static HttpClient _httpClient; private static long _requestId; + public static readonly HashSet WebSocketConnections = new(); public static readonly string UserAgent = $"Capy64/{Capy64.Version}"; - private readonly IConfiguration _configuration; + private static IConfiguration _configuration; private readonly LuaRegister[] HttpLib = new LuaRegister[] { new() @@ -251,6 +252,20 @@ public class HTTP : IPlugin { var L = Lua.FromIntPtr(state); + var wsSettings = _configuration.GetSection("HTTP:WebSockets"); + + if (!wsSettings.GetValue("Enable")) + { + L.Error("WebSockets are disabled"); + return 0; + } + + if (WebSocketConnections.Count >= wsSettings.GetValue("MaxActiveConnections")) + { + L.Error("Max connections reached"); + return 0; + } + var url = L.CheckString(1); if (!TryGetUri(url, out var uri)) { @@ -308,6 +323,7 @@ public class HTTP : IPlugin await task; var handle = new WebSocketHandle(wsClient, requestId, _game); + WebSocketConnections.Add(handle); _game.LuaRuntime.PushEvent("websocket_connect", L => { @@ -325,7 +341,6 @@ public class HTTP : IPlugin var result = await wsClient.ReceiveAsync(buffer, CancellationToken.None); if (result.MessageType == WebSocketMessageType.Close) { - Console.WriteLine("Closing"); await wsClient.CloseAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None); _game.LuaRuntime.PushEvent("websocket_close", requestId); return;