diff options
| author | RblSb <msrblsb@gmail.com> | 2024-08-15 08:29:24 +0300 |
|---|---|---|
| committer | RblSb <msrblsb@gmail.com> | 2024-08-15 08:33:17 +0300 |
| commit | 4ac52a44ced3691581a1390bbdbdc0906074b3f3 (patch) | |
| tree | db18acc64e20d5837c0ef92787ccf8ab1eb6af2d /src | |
| parent | 38cc0a1d9b4b146af7110c681389378fd26761fa (diff) | |
Add uuids for better reconection
Kick zombie users with same uuids.
Minimal node version is 14.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Client.hx | 1 | ||||
| -rw-r--r-- | src/Types.hx | 1 | ||||
| -rw-r--r-- | src/client/ClientSettings.hx | 1 | ||||
| -rw-r--r-- | src/client/Main.hx | 8 | ||||
| -rw-r--r-- | src/server/Main.hx | 31 |
5 files changed, 37 insertions, 5 deletions
diff --git a/src/Client.hx b/src/Client.hx index 64d7e54..dc1a555 100644 --- a/src/Client.hx +++ b/src/Client.hx @@ -25,6 +25,7 @@ class Client { public final ws:WebSocket; public final req:IncomingMessage; public final id:Int; + public var uuid:String; public var isAlive = true; #end public var name:String; diff --git a/src/Types.hx b/src/Types.hx index a02b4a9..0e89b85 100644 --- a/src/Types.hx +++ b/src/Types.hx @@ -133,6 +133,7 @@ typedef FlashbackItem = { typedef WsEvent = { type:WsEventType, ?connected:{ + uuid:String, config:Config, history:Array<Message>, clients:Array<ClientData>, diff --git a/src/client/ClientSettings.hx b/src/client/ClientSettings.hx index 8403ff3..a004213 100644 --- a/src/client/ClientSettings.hx +++ b/src/client/ClientSettings.hx @@ -2,6 +2,7 @@ package client; typedef ClientSettings = { version:Int, + uuid:Null<String>, name:String, hash:String, isExtendedPlayer:Bool, diff --git a/src/client/Main.hx b/src/client/Main.hx index 8cdd914..6d50b5e 100644 --- a/src/client/Main.hx +++ b/src/client/Main.hx @@ -61,6 +61,7 @@ class Main { final defaults:ClientSettings = { version: SETTINGS_VERSION, + uuid: null, name: "", hash: "", isExtendedPlayer: false, @@ -124,7 +125,8 @@ class Main { final port = Browser.location.port; final colonPort = port.length > 0 ? ':$port' : port; final path = Browser.location.pathname; - ws = new WebSocket('$protocol//$host$colonPort$path'); + final query = settings.uuid == null ? "" : '?uuid=${settings.uuid}'; + ws = new WebSocket('$protocol//$host$colonPort$path$query'); ws.onmessage = onMessage; ws.onopen = () -> { disconnectNotification?.stop(); @@ -585,6 +587,10 @@ class Main { function onConnected(data:WsEvent):Void { final connected = data.connected; + + settings.uuid = connected.uuid; + Settings.write(settings); + globalIp = connected.globalIp; setConfig(connected.config); if (connected.isUnknownClient) { diff --git a/src/server/Main.hx b/src/server/Main.hx index 2b1aafa..a0b255e 100644 --- a/src/server/Main.hx +++ b/src/server/Main.hx @@ -13,8 +13,10 @@ import haxe.Timer; import haxe.crypto.Sha256; import js.Node.__dirname; import js.Node.process; +import js.node.Crypto; import js.node.Http; import js.node.http.IncomingMessage; +import js.node.url.URL; import js.npm.ws.Server as WSServer; import js.npm.ws.WebSocket; import json2object.ErrorUtils; @@ -378,13 +380,35 @@ class Main { } } + function randomUuid():String { + return (Crypto : Dynamic).randomUUID(); + } + + function getUrlUuid(link:String):Null<String> { + try { + if (link.startsWith('/')) link = 'http://127.0.0.1$link'; + final url = new URL(link); + return url.searchParams.get("uuid"); + } catch (e) { + return null; + } + } + function onConnect(ws:WebSocket, req:IncomingMessage):Void { + final uuid = getUrlUuid(req.url) ?? randomUuid(); + final oldClient = clients.find(client -> client.uuid == uuid); + if (oldClient != null) { + send(oldClient, {type: KickClient}); + onMessage(oldClient, {type: Disconnected}, true); + } + final ip = clientIp(req); final id = freeIds.length > 0 ? freeIds.shift() : clients.length; final name = 'Guest ${id + 1}'; trace(Date.now().toString(), '$name connected ($ip)'); final isAdmin = config.localAdmins && req.socket.localAddress == ip; final client = new Client(ws, req, id, name, 0); + client.uuid = uuid; client.isAdmin = isAdmin; clients.push(client); ws.on("pong", () -> client.isAlive = true); @@ -444,6 +468,7 @@ class Main { send(client, { type: Connected, connected: { + uuid: client.uuid, config: config, history: messages, isUnknownClient: true, @@ -490,8 +515,7 @@ class Main { case BanClient: if (!checkPermission(client, BanClientPerm)) return; final name = data.banClient.name; - final bannedClient = clients.getByName(name); - if (bannedClient == null) return; + final bannedClient = clients.getByName(name) ?? return; if (client.name == name || bannedClient.isAdmin) { serverMessage(client, "adminsCannotBeBannedError"); return; @@ -517,8 +541,7 @@ class Main { case KickClient: if (!checkPermission(client, BanClientPerm)) return; final name = data.kickClient.name; - final kickedClient = clients.getByName(name); - if (kickedClient == null) return; + final kickedClient = clients.getByName(name) ?? return; if (client.name != name && kickedClient.isAdmin) { serverMessage(client, "adminsCannotBeBannedError"); return; |
