Fixed bug introduced by null terminator inside IP string. Basic logic to disconnect clients.

This commit is contained in:
wan-may 2023-09-26 18:56:24 -03:00
parent d011885c87
commit 788b7a11f5
3 changed files with 37 additions and 6 deletions

View File

@ -29,9 +29,8 @@ end
function connecting.draw() function connecting.draw()
lg.setColor( 1,1,1,1 ) lg.setColor( 1,1,1,1 )
lg.printf( "CONNECTING\nADDRESS\nATTEMPTS", lg.printf( ("ADDRESS: %s"):format( ip ), lg.getWidth() / 4, 15, lg.getWidth() - 30, "left" )
15, 15, lg.getWidth() - 30, "left" ) lg.printf( ("ATTEMPTS: %d"):format( attempts ), lg.getWidth() / 4, 20 + lg.getFont():getHeight(), lg.getWidth() - 30, "left" )
lg.printf( ("\n%s:%d\n%d"):format( ip, port, attempts ), 15, 15, lg.getWidth() - 30, "right" )
cancelButton:draw() cancelButton:draw()
return false return false
end end

View File

@ -13,6 +13,7 @@ local serverTick = 0
function handlers.connected( data ) function handlers.connected( data )
serverTick = math.max( data.tick, serverTick ) serverTick = math.max( data.tick, serverTick )
tick = math.max( serverTick, tick )
end end
function handlers.insect( data ) function handlers.insect( data )
@ -40,7 +41,10 @@ end
function game.onPacket( msg ) function game.onPacket( msg )
if not msg or (#msg < 1) then return end if not msg or (#msg < 1) then return end
local msgs, types = packet.deserialise( msg ) local msgs, types = packet.deserialise( msg )
if not msgs then return game.onPacket( server.receive() ) end if not msgs then
print( "malformed packet:", types )
return game.onPacket( server.receive() )
end
for i = 1, #msgs do for i = 1, #msgs do
--Handler returns something if msg should be discarded. --Handler returns something if msg should be discarded.
if handlers[ types[i] ]( msgs[i] ) then break end if handlers[ types[i] ]( msgs[i] ) then break end
@ -65,6 +69,9 @@ function game.newGame( )
end end
function game.disconnect( ) function game.disconnect( )
server.newPacket()
server.disconnect()
server.send( packet.get() )
return scene.mainmenu( server.disconnect() ) return scene.mainmenu( server.disconnect() )
end end

View File

@ -20,10 +20,11 @@ local svInfo = packet.serverInfo{ version = 13,
local clients = {} local clients = {}
local connecting = {} local connecting = {}
local server = { tick = 0, } local server = { tick = 0, currentClient = false }
local handlers = setmetatable({ local handlers = setmetatable({
--This is the start of a packet from a connected client.
connected = function( msg, ip, port ) connected = function( msg, ip, port )
local client = clients[msg.token] local client = clients[msg.token]
if not client or if not client or
@ -40,8 +41,22 @@ local handlers = setmetatable({
end end
client.tick = msg.tick client.tick = msg.tick
server.currentClient = client
end,
--A client wants to disconnect.
disconnect = function( msg, ip, port )
--This is the authenticated client whose packets are being processed.
local client = server.currentClient
if client and client.ip == ip and client.port == port then
print( "Client disconnecting:", client.id)
clients[ client.id ] = nil
server.currentClient = false
return true
end
end, end,
--Client responds to handshake challenge.
clChimo = function( clChimo, ip, port ) clChimo = function( clChimo, ip, port )
local key = ip..":"..port local key = ip..":"..port
if not connecting[ key ] then if not connecting[ key ] then
@ -56,12 +71,16 @@ local handlers = setmetatable({
print( "Hashes differ:", shared.hash.hex( clNonce ), shared.hash.hex( svNonce ) ) print( "Hashes differ:", shared.hash.hex( clNonce ), shared.hash.hex( svNonce ) )
return true return true
end end
--Successful handshake.
print( "Client connected:", ip, port, token ) print( "Client connected:", ip, port, token )
clients[ token ] = connecting[ key ] clients[ token ] = connecting[ key ]
clients[ token ].token = token
packet.connected{ token = token, tick = server.tick } packet.connected{ token = token, tick = server.tick }
return udp:sendto( packet.get(), ip, port ) return udp:sendto( packet.get(), ip, port )
end, end,
--Metaserver replying with real IP address.
advertised = function( ack, ip, port ) advertised = function( ack, ip, port )
if ip ~= shared.metaserver.ip then return print( "Advertisement acked from rogue address:", ip, port ) end if ip ~= shared.metaserver.ip then return print( "Advertisement acked from rogue address:", ip, port ) end
if udp:getsockname() then if udp:getsockname() then
@ -72,7 +91,7 @@ local handlers = setmetatable({
server.SetIP( tostring( ack.ip ), ack.port ) server.SetIP( tostring( ack.ip ), ack.port )
end, end,
--New client seeks to connect. Challenge immediately.
clientInfo = function( clientInfo, ip, port ) clientInfo = function( clientInfo, ip, port )
local key = ip..":"..port local key = ip..":"..port
connecting[key] = connecting[key] or { ip = ip, port = port, tick = 0 } connecting[key] = connecting[key] or { ip = ip, port = port, tick = 0 }
@ -114,6 +133,7 @@ function server.Parse( msg, ip, port )
print( "Received: ", types[i], ip, port ) print( "Received: ", types[i], ip, port )
if handlers[ types[i] ]( msgs[i], ip, port ) then break end if handlers[ types[i] ]( msgs[i], ip, port ) then break end
end end
server.currentClient = false
else print( types ) else print( types )
end end
return server.Parse( udp:receivefrom() ) -- Process other packets. return server.Parse( udp:receivefrom() ) -- Process other packets.
@ -150,6 +170,11 @@ function server.Advance()
print( "updating client:", id ) print( "updating client:", id )
packet.connected{ token = id, tick = server.tick } packet.connected{ token = id, tick = server.tick }
udp:sendto( packet.get(), client.ip, client.port ) udp:sendto( packet.get(), client.ip, client.port )
if server.tick - client.tick > 1000 then
print( "dropping client:", id )
clients[id] = nil
end
end end
end end
end end