diff --git a/src/client/connecting.lua b/src/client/connecting.lua index 136ed48..642030e 100644 --- a/src/client/connecting.lua +++ b/src/client/connecting.lua @@ -5,7 +5,7 @@ local button = assert( require 'ui.button' ) local strings = assert( require 'strings' ) local connecting = {} -local time, ip, port, attempts = 0, 0, 0, 1 +local time, ip, port, attempts, svInfo = 0, 0, 0, 1 local cancelButton = button{ x = lg.getWidth() / 4, @@ -76,7 +76,10 @@ function connecting:onLoad( params ) attempts = 1 params = params or { ip = "8.8.8.8", port = 8 } ip, port = params.ip, params.port - return server.isValid( ip, port ) and server.connect( ip, port ) + if server.isValid( ip, port ) then + server.setInfo( params.svInfo ) + return server.connect( ip, port ) + end end function connecting.exit() diff --git a/src/client/game.lua b/src/client/game.lua index 6b29c7a..bc2a2bd 100644 --- a/src/client/game.lua +++ b/src/client/game.lua @@ -28,14 +28,22 @@ function handlers.playerChange( data ) end +function handlers.svInfo( data ) + if server.svInfo.map ~= data.map then end + return server.setInfo( data ) +end + function handlers.chatMessage( msg ) print( msg.cmsg ) end function game.draw() lg.setColor( 1, 1, 1, 1 ) - lg.print( tick, 0, 0 ) - lg.print( serverTick, 0, 25 ) + lg.print( "Client Tick: "..tick, 0, 0 ) + lg.print( "Server Tick: "..serverTick, 0, 25 ) + lg.print( "Current Map: "..packet.getString(server.svInfo.map), 0, 50 ) + lg.print( "Server Name: "..packet.getString(server.svInfo.svname), 0, 75 ) + lg.print( "# Connected: "..server.svInfo.players, 0, 100 ) end function game.onPacket( msg ) diff --git a/src/client/udp.lua b/src/client/udp.lua index 51f153e..90a60a8 100644 --- a/src/client/udp.lua +++ b/src/client/udp.lua @@ -2,7 +2,7 @@ local socket = assert( require 'socket' ) local ms = assert( require 'shared.metaserver' ) local config = assert( require 'config' ) -local udp = {} +local udp = { svInfo = {}, token = false, } local packet = assert( require 'shared.packet' ) local hash = assert( require 'shared.hash' ) @@ -39,6 +39,10 @@ function udp.setToken( token ) udp.token = token end +function udp.setInfo( svInfo ) + udp.svInfo = svInfo +end + function udp.answerChallenge( svNonce ) local clNonce = hash.rand() packet.get() diff --git a/src/client/ui/browser.lua b/src/client/ui/browser.lua index a2def5c..2cd8178 100644 --- a/src/client/ui/browser.lua +++ b/src/client/ui/browser.lua @@ -18,7 +18,7 @@ local cw = fonts.font:getWidth( "w" ) local function joinServerCallback( button ) if button.ip and button.port then - return browser.joinIP( button.ip, button.port ) + return browser.joinIP( button.ip, button.port, button.serverInfo ) end end @@ -79,7 +79,7 @@ function ti:callback() return self:enterText( browser.joinIPString ) end local headerButtons = { button{ - callback = function() return serverList.requestServers() end, + callback = function() serverList.clear() return serverList.requestServers() end, text = lg.newText( fonts.midFont, strings.refresh_button ) , color = color, x = cw * 32, @@ -144,7 +144,6 @@ end local metaServerHandlers = setmetatable( { default = function() end, - connected = serverList.clear, serverInfo = serverList.add, }, {__index = function( t ) return t.default end }) @@ -221,9 +220,9 @@ function browser.joinIPString( s ) if ip and port then return browser.joinIP( ip, port ) end end -function browser.joinIP( ip, port ) +function browser.joinIP( ip, port, svInfo ) print( "Joining server:", ip, port ) - return scene.loadScene( scene.connecting, { ip = ip, port = port } ) + return scene.loadScene( scene.connecting, { ip = ip, port = port, svInfo = svInfo } ) end function browser.keypressed( key, code, isRepeat ) diff --git a/src/metaserver/main.lua b/src/metaserver/main.lua index 4b5e46f..48da66e 100644 --- a/src/metaserver/main.lua +++ b/src/metaserver/main.lua @@ -19,20 +19,25 @@ local servers = {} local clients = {} local tick = 0 +local function serverID( ip, port ) + return ip..":"..port +end + local handlers = setmetatable({ serverInfo = function( svInfo, ip, port ) print( "Server:", ip, port ) + local id = serverID(ip, port) local t = socket.gettime() - if not servers[ip..port] then - servers[ip..port] = { ip = ip, port = port, info = svInfo } + if not servers[id] then + servers[id] = { ip = ip, port = port, info = svInfo } --NAT punch: the server doesn't know its own external IP --so it contacts a third party (the metaserver) to discover it. --This external IP gets advertised to prospective clients. svInfo.ip.ip = ip svInfo.port = port end - servers[ip..port].time = t + servers[id].time = t packet.advertised{ time = t, ip = svInfo.ip, port = svInfo.port } return udp:sendto( packet.get(), ip, port ) end, @@ -56,8 +61,6 @@ local handlers = setmetatable({ local t = socket.gettime() clients[ip].time = t - - packet.connected{ token = 5, tick = tick } for svIP, server in pairs( servers ) do print( "", svIP, packet.getString( server.info.svname )) diff --git a/src/server/client.lua b/src/server/client.lua index b787557..ede7514 100644 --- a/src/server/client.lua +++ b/src/server/client.lua @@ -1,19 +1,23 @@ +local clients = {} local client = {} +client.__index = client + +function client.new() + local c = setmetatable( {}, client ) + clients[ c.id ] = c + return c +end + +function client:disconnect() + clients[self.id] = nil +end + +function client:assignRole( role ) + self.role = role +end function client.connect( ip, port ) end -function client.challenge( ) - -end - -function client.acceptConnection( ) - -end - -function client.disconnect( ) - -end - -return \ No newline at end of file +return client \ No newline at end of file diff --git a/src/server/main.lua b/src/server/main.lua index 6197b77..4f3f4be 100644 --- a/src/server/main.lua +++ b/src/server/main.lua @@ -22,7 +22,7 @@ local svInfo = packet.serverInfo{ version = 13, local clients = {} local connecting = {} -local server = { tick = 0, currentClient = false } +local server = { tick = 0, time = 0, currentClient = false } local handlers = setmetatable({ @@ -43,10 +43,10 @@ local handlers = setmetatable({ end client.tick = msg.tick - client.time = socket.gettime() + client.time = server.time server.currentClient = client end, - + --A client wants to disconnect. disconnect = function( msg, ip, port ) --This is the authenticated client whose packets are being processed. @@ -61,16 +61,16 @@ local handlers = setmetatable({ --Client responds to handshake challenge. clChimo = function( clChimo, ip, port ) - + print( "Received handshake response." ) - + --No active challenge, don't send anything. local key = ip..":"..port if not connecting[ key ] then print( "Old connection attempt from:", key ) return true end - + --Compute session token. local remoteHash = clChimo.hash local clNonce = clChimo.nonce @@ -80,10 +80,10 @@ local handlers = setmetatable({ print( "Hashes differ:", shared.hash.hex( clNonce ), shared.hash.hex( svNonce ) ) return true end - + --Hash collision. while clients[token] do token = token + 1 end - + --Successful handshake. print( "Client connected:", token, port, ip ) clients[ token ] = connecting[ key ] @@ -175,17 +175,14 @@ end function server.Advance() server.tick = server.tick + 1 - server.time = socket.gettime() - if server.tick % 100 == 0 then - for id, client in pairs( clients ) do - packet.get() - packet.connected{ token = id, tick = server.tick } - udp:sendto( packet.get(), client.ip, client.port ) - - if server.time - client.time > CLIENTTIMEOUT then - print( "dropping client:", id ) - clients[id] = nil - end + for id, client in pairs( clients ) do + packet.get() + packet.connected{ token = id, tick = server.tick } + udp:sendto( packet.get(), client.ip, client.port ) + + if server.time - client.time > CLIENTTIMEOUT then + print( "dropping client:", id ) + clients[id] = nil end end end @@ -199,13 +196,16 @@ function server.Quit() end server.Start() - function love.update( dt ) + server.time = server.time + dt server.Parse( udp:receivefrom() ) - server.Advance() - if server.tick % 4000 == 0 then - server.Advertise() - server.Parse( mscxn:receive(), shared.metaserver.ip, shared.metaserver.port ) + if server.time > 0.1 then + if (server.tick % 50) == 0 then + server.Advertise() + server.Parse( mscxn:receive(), shared.metaserver.ip, shared.metaserver.port ) + end + server.time = 0 + server.Advance() end end diff --git a/src/shared/packet.lua b/src/shared/packet.lua index 2df5b1c..1ab2e49 100644 --- a/src/shared/packet.lua +++ b/src/shared/packet.lua @@ -1,6 +1,7 @@ local ffi = assert( require 'ffi' ) local buffer = assert( require( "string.buffer" ) ) local ipString = assert( require 'shared.ipstring' ) +local roles = assert( require 'shared.roles' ) local packet = {} local mt = { __index = { new = function( self ) return ffi.new( self.ct ) end } } @@ -63,12 +64,13 @@ newStruct{ name = "insect", "uint8_t id", "bool dead", + "int16_t z", "int8_t hp", "int8_t vx", "int8_t vy", - "uint8_t folio", - "uint32_t x", - "uint32_t y", + "int8_t vz", + "int32_t x", + "int32_t y", } newStruct{ @@ -80,9 +82,9 @@ newStruct{ } newStruct{ - name = "playerChange", + name = "playerInfo", "uint8_t id", - "uint8_t role", + "role_t role", "char username[31]", } diff --git a/src/shared/roles.lua b/src/shared/roles.lua new file mode 100644 index 0000000..41f595f --- /dev/null +++ b/src/shared/roles.lua @@ -0,0 +1,9 @@ +local ffi = require 'ffi' +ffi.cdef[[ +typedef enum { + roleSpectator = 0, + roleSoleil = 1, + roleInsect = 2, + } role_t; +]] +return ffi.typeof( ffi.new 'role_t' ) \ No newline at end of file