From 378ce1b6bc3822b1eec7ff12ce2e0699bc4d84e8 Mon Sep 17 00:00:00 2001 From: j4nk Date: Sun, 23 Mar 2025 17:14:21 -0400 Subject: [PATCH] Clients periodically ping server, server checks for disconnects --- lobby.lua | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/lobby.lua b/lobby.lua index bf1a6db..f585e0b 100644 --- a/lobby.lua +++ b/lobby.lua @@ -13,11 +13,33 @@ OCT_LOBBY_MSG_NAK = 6; -- "no" -- end message type constants oct_lobby_clientlist = {}; -oct_lobby_timers = {}; -oct_lobby_timers["clientlist"] = 1000; -- Every 1000 calls to lobby_client broadcast client list server_needs_broadcast_client_list = false +lobby_server_first_call = true + +function lobby_server_checkclients() + for k,v in pairs(oct_lobby_clientlist) + do + -- if we weren't pinged, remove the client + if not v["pinged"] + then + OCT_LOG_WARNING("Lost connection to " .. k) + oct_lobby_clientlist[k] = nil -- remove the client + server_needs_broadcast_client_list = true -- rebroadcast the client list + else + v["pinged"] = false + end + end + + oct_timer_register("lobby_server_checkclients", 3000, "lobby_server_checkclients", "") +end + function lobby_server(maxplayers) + if lobby_server_first_call then + oct_timer_register("lobby_server_checkclients", 3000, "lobby_server_checkclients", "") + lobby_server_first_call = false + end + msg,addr,port = oct_recv(); if (msg ~= "") then msg_obj = json.decode(msg)[1] -- dumps to 1-elem array, get first elem @@ -50,6 +72,7 @@ function lobby_server(maxplayers) oct_lobby_clientlist[req_name] = {} oct_lobby_clientlist[req_name]["addr"] = req_addr oct_lobby_clientlist[req_name]["port"] = req_port + oct_lobby_clientlist[req_name]["pinged"] = false OCT_LOG_INFO("Registered new client: " .. req_name .. " @ " .. req_addr .. ":" .. req_port) oct_send(response, req_addr, req_port) @@ -57,8 +80,24 @@ function lobby_server(maxplayers) server_needs_broadcast_client_list = true end end + + if (msg_obj["msg_type"] == OCT_LOBBY_MSG_PING) then + req_addr = convert_known_host_to_ip(addr) + for k,v in pairs(oct_lobby_clientlist) + do + -- TODO this is insecure + -- have server issue a token based on a random number on registration and check against that + -- like SHA256(addr::port::rand()) + if v["addr"] == req_addr and k == msg_obj["name"] + then + v["pinged"] = true + break + end + end + end end + if (server_needs_broadcast_client_list == true) then msg = json.encode({ { msg_type = OCT_LOBBY_MSG_CLIENTLIST, @@ -106,6 +145,15 @@ function lobby_clear_connect_form() unregister_textbox(lobby_name_textbox) end +-- every 1 second, ping the server to let it know we are still alive +function lobby_client_ping() + local msg = json.encode({ + { msg_type=OCT_LOBBY_MSG_PING, name=client_connect_name } + }) + oct_send(msg, client_connect_ip, client_connect_port) + oct_timer_register("ping_server", 1000, "lobby_client_ping", "") +end + --function lobby_client(ip, port, name, my_port) function lobby_client(key, ch, my_port) if (lobby_first_call) @@ -173,6 +221,13 @@ function lobby_client(key, ch, my_port) client_wait_for_reg_response = false client_filling_in_connect_form = false lobby_clear_connect_form() + -- ping the server to let them know we are alive + local ping_msg = json.encode({ + { msg_type=OCT_LOBBY_MSG_PING, name=client_connect_name } + }) + oct_send(ping_msg, client_connect_ip, client_connect_port) + -- then ping every second + oct_timer_register("ping_server", 1000, "lobby_client_ping", "") -- Registration was unsuccessful elseif (client_wait_for_reg_response == true and