diff --git a/src/client/connecting.lua b/src/client/connecting.lua index 8e63b4c..cb8a3c8 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, 0 +local time, ip, port, attempts = 0, 0, 0, 1 local cancelButton = button{ x = lg.getWidth() / 4, @@ -43,7 +43,10 @@ end function connecting.update(dt) time = time + dt - if time > 5 then + if time > 2 then + time = 0 + attempts = attempts + 1 + server.connect( ip, port ) --return scene.loadScene( scene.game ) end return false diff --git a/src/client/udp.lua b/src/client/udp.lua index eb041b7..c0df8f8 100644 --- a/src/client/udp.lua +++ b/src/client/udp.lua @@ -1,5 +1,6 @@ local socket = assert( require 'socket' ) local ms = assert( require 'shared.metaserver' ) +local config = assert( require 'config' ) local udp = {} local packet = assert( require 'shared.packet' ) @@ -35,11 +36,11 @@ end function udp.connect( ip, port ) assert( cxn:setpeername( ip, port ) ) - return udp.send( packet.get( packet.heartbeat{ tick = 0, hash = 1234 } ) ) + return udp.send( packet.get( packet.clientInfo{ username = config.plName } ) ) end function udp.disconnect( ) - + end function udp.send( s ) diff --git a/src/metaserver/getip.lua b/src/metaserver/getip.lua index 805bc68..2d722bc 100644 --- a/src/metaserver/getip.lua +++ b/src/metaserver/getip.lua @@ -1 +1 @@ -assert( assert( require 'socket.http' ).request 'https://api.ipify.org' ) == '142.162.167.92' \ No newline at end of file +assert( assert( require 'socket.http' ).request 'https://api.ipify.org' == '142.162.167.92') \ No newline at end of file diff --git a/src/metaserver/main.lua b/src/metaserver/main.lua index 438cc46..cb723d9 100644 --- a/src/metaserver/main.lua +++ b/src/metaserver/main.lua @@ -1,3 +1,4 @@ +--Note, this won't work unless you set up port forwarding! local SERVERTIMEOUT = 30 local CLIENTTIMEOUT = 1 @@ -5,8 +6,11 @@ local shared = assert( require '../shared.shared' ) local socket = assert( require 'socket' ) local packet = assert( shared.packet ) local udp = assert( socket.udp() ) +local msip = assert( require 'getip' ) udp:settimeout(0) -assert( udp:setsockname( socket.dns.toip(socket.dns.gethostname()), shared.metaserver.port )) +local localIP = socket.dns.toip(socket.dns.gethostname()) +print( "Metaserver local IP:", localIP ) +assert( udp:setsockname( localIP, shared.metaserver.port )) --Servers broadcast their information here. --The metaserver builds a list of available servers. ( available meaning, "broadcasted in last ten heartbeats" ) diff --git a/src/server/main.lua b/src/server/main.lua index 559925a..8807391 100644 --- a/src/server/main.lua +++ b/src/server/main.lua @@ -18,20 +18,46 @@ local svInfo = packet.serverInfo{ version = 13, map = "Test Map" } +local clients = {} +local connecting = {} + local server = { tick = 0, + + clientInfo = function( clientInfo, ip, port ) + local key = ip..port + connecting[key] = connecting[key] or {} + local client = connecting[key] + local nonce = shared.hash.rand() + client.nonce = nonce + print( "Received connection request from:", ip, port ) + print( "Sending authentication nonce:", nonce ) + packet.svChimo{ nonce = nonce } + return udp:sendto( packet.get(), ip, port ) + end, + + clChimo = function( clChimo, ip, port ) + if not connecting[ ip..port ] then + return print( "Old connection attempt from:", ip, port ) + end + local remoteHash = clChimo.hash + local clNonce = clChimo.nonce + local svNonce = connecting[ip..port].nonce + local localHash = shared.hash.hash( clNonce, svNonce ) + if localHash ~= remoteHash then + return print( "Hashes differ:", shared.hash.hex( clNonce ), shared.hash.hex( svNonce ) ) + end + print( "Client connected:", ip, port, localHash ) + clients[ localHash ] = { ip = ip, port = port } + packet.connected{ token = localHash } + return udp:sendto( packet.get(), ip, port ) + end, - advertised = function() - print( "Advertised." ) + advertised = function( ack, ip, port ) + print( "Advertised via:", ip, port ) end, } -local clients = {} - ---Developer convenience function: start the local client program. -function server.StartLocalClient() - os.execute( "start vision.bat" ) -end function server.Advertise() print( "Advertise." ) @@ -69,10 +95,9 @@ function server.SetIP( ipString, port ) svInfo.ip = shared.ip.fromString( ipString ) svInfo.port = port if udp:setsockname( ipString, port ) then - print( ipString, port ) --Find another port. elseif port < 65536 then - print( "Trying IP:", ipString, port ) + print( "Trying port:", port ) return server.SetIP( ipString, port + 1 ) else print( "Could not use IP: "..ipString ) diff --git a/src/shared/hash.lua b/src/shared/hash.lua new file mode 100644 index 0000000..2acc8e0 --- /dev/null +++ b/src/shared/hash.lua @@ -0,0 +1,3 @@ +local bit = assert( require 'bit' ) +--hash of a pair of 32-bit numbers +return { hash = bit.bxor, rand = function() return 5 end, hex = bit.tohex } \ No newline at end of file diff --git a/src/shared/metaserver.lua b/src/shared/metaserver.lua index 644a6ee..3dd3299 100644 --- a/src/shared/metaserver.lua +++ b/src/shared/metaserver.lua @@ -1 +1,3 @@ -return { ip = '192.168.2.15', port = 42069 } \ No newline at end of file +local ms = { ip = '192.168.2.15', port = 42069 } +print( "Metaserver public address:", ms.ip, ms.port ) +return ms \ No newline at end of file diff --git a/src/shared/packet.lua b/src/shared/packet.lua index e87e944..3f6f679 100644 --- a/src/shared/packet.lua +++ b/src/shared/packet.lua @@ -4,22 +4,25 @@ local ipString = assert( require 'shared.ipstring' ) local packet = {} local mt = { __index = { new = function( self ) return ffi.new( self.ct ) end } } +local headerByte = 0x41 --Ensure printable characters at start of packets. + local function newStruct( t ) - assert( not( packet[ t.name ] or packet[ t.netname ] )) + assert( not( packet[ t.name ] )) packet[ t.name ] = t - packet[ t.netname ] = t + t.netname = headerByte + packet[ headerByte ] = t + headerByte = headerByte + 1 ffi.cdef(("typedef struct {uint8_t netname;\n%s;\n} %s;"):format( table.concat( t, ";\n" ), t.name )) t.ct = ffi.typeof( ffi.new( t.name ) ) t.size = ffi.sizeof( t.ct ) assert( t.size < 500, t.name ) setmetatable( t, mt ) - --print( "Packet:", t.name, "Members:", #t + 1, "Size:", t.size, "Alignment:", ffi.alignof( t.ct ) ) + print( "Packet:", t.name, "Members:", #t + 1, "Size:", t.size, "Alignment:", ffi.alignof( t.ct ) ) end newStruct{ name = "serverInfo", - netname = 42, "uint8_t players", "uint8_t capacity", "ipAddress ip", @@ -31,26 +34,38 @@ newStruct{ newStruct{ name = "clientInfo", - netname = 22, "char username[31]", } +newStruct{ + name = "svChimo", + "uint32_t nonce", +} + +newStruct{ + name = "clChimo", + "uint32_t nonce", + "uint32_t hash", +} + +newStruct{ + name = "connected", + "uint32_t token", +} + newStruct{ name = "metaServer", - netname = 123, "char padding[300]" --Just a bunch of padding to mitigate amplification. } newStruct{ name = "heartbeat", - netname = 69, "uint32_t tick", "uint32_t hash", } newStruct{ name = "insect", - netname = 81, "uint8_t id", "bool dead", "int8_t hp", @@ -63,7 +78,6 @@ newStruct{ newStruct{ name = "soleil", - netname = 27, "uint16_t azimuth", "uint16_t altitude", "int8_t vazi", @@ -72,7 +86,6 @@ newStruct{ newStruct{ name = "playerChange", - netname = 72, "uint8_t id", "uint8_t role", "char username[31]", @@ -80,19 +93,16 @@ newStruct{ newStruct{ name = "chatMessage", - netname = 54, "char cmsg[127]", } newStruct{ name = "command", - netname = 32, "char command", } newStruct{ name = "advertised", - netname = 144, "uint32_t time", } diff --git a/src/shared/shared.lua b/src/shared/shared.lua index 5bccc2b..6eec1c1 100644 --- a/src/shared/shared.lua +++ b/src/shared/shared.lua @@ -8,6 +8,7 @@ local shared = {} return rq( ... ) end end]] +shared.hash = assert( require 'shared.hash' ) shared.ip = assert( require 'shared.ipstring' ) shared.packet = assert( require 'shared.packet' ) shared.print = assert( require 'shared.print' )