Connection protocol. Joinable servers!
This commit is contained in:
parent
76beae271c
commit
74e328d86c
|
@ -1,2 +1,3 @@
|
||||||
|
color 0a
|
||||||
D:/dev/love/love.exe "./client/"
|
D:/dev/love/love.exe "./client/"
|
||||||
pause
|
pause
|
|
@ -36,10 +36,28 @@ function connecting.draw()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function connecting.svChimo( msg )
|
||||||
|
return server.answerChallenge( msg.nonce )
|
||||||
|
end
|
||||||
|
|
||||||
|
function connecting.connected( msg )
|
||||||
|
server.setToken( msg.token )
|
||||||
|
return scene.game()
|
||||||
|
end
|
||||||
|
|
||||||
function connecting.keypressed(key, code, isrepeat)
|
function connecting.keypressed(key, code, isrepeat)
|
||||||
if code == "escape" then return scene.browser() end
|
if code == "escape" then return scene.browser() end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function connecting.read( msg )
|
||||||
|
if not msg then return false end
|
||||||
|
local msgs, types = server.deserialise( msg )
|
||||||
|
for i = 1, #msgs do
|
||||||
|
( connecting[ types[i] ] or print )( msgs[i], ip, port )
|
||||||
|
end
|
||||||
|
return connecting.read( server.receive() )
|
||||||
|
end
|
||||||
|
|
||||||
function connecting.update(dt)
|
function connecting.update(dt)
|
||||||
time = time + dt
|
time = time + dt
|
||||||
|
|
||||||
|
@ -49,12 +67,14 @@ function connecting.update(dt)
|
||||||
server.connect( ip, port )
|
server.connect( ip, port )
|
||||||
--return scene.loadScene( scene.game )
|
--return scene.loadScene( scene.game )
|
||||||
end
|
end
|
||||||
return false
|
|
||||||
|
return connecting.read( server.receive() )
|
||||||
end
|
end
|
||||||
|
|
||||||
function connecting:onLoad( params )
|
function connecting:onLoad( params )
|
||||||
lg.setCanvas()
|
lg.setCanvas()
|
||||||
time = 0
|
time = 0
|
||||||
|
attempts = 1
|
||||||
params = params or { ip = "8.8.8.8", port = 8 }
|
params = params or { ip = "8.8.8.8", port = 8 }
|
||||||
ip, port = params.ip, params.port
|
ip, port = params.ip, params.port
|
||||||
return server.isValid( ip, port ) and server.connect( ip, port )
|
return server.isValid( ip, port ) and server.connect( ip, port )
|
||||||
|
|
|
@ -4,7 +4,9 @@ local config = assert( require 'config' )
|
||||||
|
|
||||||
local udp = {}
|
local udp = {}
|
||||||
local packet = assert( require 'shared.packet' )
|
local packet = assert( require 'shared.packet' )
|
||||||
|
local hash = assert( require 'shared.hash' )
|
||||||
|
|
||||||
|
local token
|
||||||
local cxn = assert( socket.udp() )
|
local cxn = assert( socket.udp() )
|
||||||
local mscxn = assert( socket.udp() )
|
local mscxn = assert( socket.udp() )
|
||||||
cxn:settimeout( 0 )
|
cxn:settimeout( 0 )
|
||||||
|
@ -15,6 +17,8 @@ function udp.receive()
|
||||||
return cxn:receive()
|
return cxn:receive()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
udp.deserialise = packet.deserialise
|
||||||
|
|
||||||
function udp.receiveMeta()
|
function udp.receiveMeta()
|
||||||
return mscxn:receive()
|
return mscxn:receive()
|
||||||
end
|
end
|
||||||
|
@ -27,6 +31,17 @@ function udp.requestServerList()
|
||||||
return mscxn:send( packet.get() )
|
return mscxn:send( packet.get() )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function udp.setToken( token )
|
||||||
|
token = token
|
||||||
|
end
|
||||||
|
|
||||||
|
function udp.answerChallenge( svNonce )
|
||||||
|
local clNonce = hash.rand()
|
||||||
|
packet.get()
|
||||||
|
packet.clChimo{ nonce = clNonce, hash = hash.hash( clNonce, svNonce ) }
|
||||||
|
return cxn:send( packet.get() )
|
||||||
|
end
|
||||||
|
|
||||||
function udp.isValid( ip, port )
|
function udp.isValid( ip, port )
|
||||||
local s, e = socket.udp()
|
local s, e = socket.udp()
|
||||||
if s then s, e = s:setpeername( ip, port ) end
|
if s then s, e = s:setpeername( ip, port ) end
|
||||||
|
@ -40,7 +55,9 @@ function udp.connect( ip, port )
|
||||||
end
|
end
|
||||||
|
|
||||||
function udp.disconnect( )
|
function udp.disconnect( )
|
||||||
|
udp.send( packet.get( packet.disconnect{ reason = 0 }))
|
||||||
|
cxn = assert( socket.udp() )
|
||||||
|
cxn:settimeout( 0 )
|
||||||
end
|
end
|
||||||
|
|
||||||
function udp.send( s )
|
function udp.send( s )
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
|
color 04
|
||||||
D:/dev/love/love.exe "./server/"
|
D:/dev/love/love.exe "./server/"
|
||||||
pause
|
pause
|
|
@ -20,21 +20,9 @@ local svInfo = packet.serverInfo{ version = 13,
|
||||||
|
|
||||||
local clients = {}
|
local clients = {}
|
||||||
local connecting = {}
|
local connecting = {}
|
||||||
|
local server = { tick = 0, }
|
||||||
|
|
||||||
local server = {
|
local handlers = setmetatable({
|
||||||
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 )
|
clChimo = function( clChimo, ip, port )
|
||||||
if not connecting[ ip..port ] then
|
if not connecting[ ip..port ] then
|
||||||
|
@ -54,11 +42,31 @@ local server = {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
advertised = function( ack, ip, port )
|
advertised = function( ack, ip, port )
|
||||||
print( "Advertised via:", ip, port )
|
if ip ~= shared.metaserver.ip then return print( "Advertisement acked from rogue address:", ip, port ) end
|
||||||
|
if udp:getsockname() then
|
||||||
|
assert( udp:getsockname() == tostring( ack.ip ) )
|
||||||
|
return print( "Advertised. Address already set." )
|
||||||
|
end
|
||||||
|
print( "Advertised. Setting address:", ack.ip, ack.port )
|
||||||
|
server.SetIP( tostring( ack.ip ), ack.port )
|
||||||
end,
|
end,
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
|
|
||||||
|
}, {__index = function() return print end })
|
||||||
|
|
||||||
function server.Advertise()
|
function server.Advertise()
|
||||||
print( "Advertise." )
|
print( "Advertise." )
|
||||||
packet.get()
|
packet.get()
|
||||||
|
@ -85,8 +93,8 @@ function server.Parse( msg, ip, port )
|
||||||
|
|
||||||
local msgs, types = packet.deserialise( msg )
|
local msgs, types = packet.deserialise( msg )
|
||||||
if msgs then for i = 1, #msgs do
|
if msgs then for i = 1, #msgs do
|
||||||
print( "Received: ", types[i], ip, port );
|
print( "Received: ", types[i], ip, port )
|
||||||
( server[ types[i] ] or print )( msgs[i], ip, port )
|
handlers[ types[i] ]( msgs[i], ip, port )
|
||||||
end end
|
end end
|
||||||
return server.Parse( udp:receivefrom() ) -- Process other packets.
|
return server.Parse( udp:receivefrom() ) -- Process other packets.
|
||||||
end
|
end
|
||||||
|
@ -94,13 +102,16 @@ end
|
||||||
function server.SetIP( ipString, port )
|
function server.SetIP( ipString, port )
|
||||||
svInfo.ip = shared.ip.fromString( ipString )
|
svInfo.ip = shared.ip.fromString( ipString )
|
||||||
svInfo.port = port
|
svInfo.port = port
|
||||||
if udp:setsockname( ipString, port ) then
|
local ok, err = udp:setsockname( ipString, port )
|
||||||
|
if ok then
|
||||||
|
print( "Server IP:", udp:getsockname() )
|
||||||
|
return true
|
||||||
--Find another port.
|
--Find another port.
|
||||||
elseif port < 65536 then
|
elseif port < 65536 then
|
||||||
print( "Trying port:", port )
|
print( "Could not use port:", ipString, port, err )
|
||||||
return server.SetIP( ipString, port + 1 )
|
return server.SetIP( ipString, port + 1 )
|
||||||
else
|
else
|
||||||
print( "Could not use IP: "..ipString )
|
print( "Could not use IP:", ipString, err )
|
||||||
return error( "Connection failed." )
|
return error( "Connection failed." )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -109,8 +120,6 @@ end
|
||||||
function server.Start()
|
function server.Start()
|
||||||
udp = assert( socket.udp() )
|
udp = assert( socket.udp() )
|
||||||
udp:settimeout(0)
|
udp:settimeout(0)
|
||||||
server.SetIP( socket.dns.toip(socket.dns.gethostname()), 51312 )
|
|
||||||
print( "Server started:", udp:getsockname() )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function server.Advance()
|
function server.Advance()
|
||||||
|
@ -135,6 +144,7 @@ function love.update( dt )
|
||||||
server.Advance()
|
server.Advance()
|
||||||
if server.tick % 250 == 0 then
|
if server.tick % 250 == 0 then
|
||||||
server.Advertise()
|
server.Advertise()
|
||||||
|
server.Parse( mscxn:receive(), shared.metaserver.ip, shared.metaserver.port )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
local math = math
|
||||||
local bit = assert( require 'bit' )
|
local bit = assert( require 'bit' )
|
||||||
|
local max = bit.tobit( 0xffffffff )
|
||||||
|
math.randomseed( 4 )
|
||||||
--hash of a pair of 32-bit numbers
|
--hash of a pair of 32-bit numbers
|
||||||
return { hash = bit.bxor, rand = function() return 5 end, hex = bit.tohex }
|
return {
|
||||||
|
hash = bit.bxor,
|
||||||
|
hex = bit.tohex,
|
||||||
|
rand = function()
|
||||||
|
return math.random( 1, max )
|
||||||
|
end, }
|
|
@ -104,6 +104,13 @@ newStruct{
|
||||||
newStruct{
|
newStruct{
|
||||||
name = "advertised",
|
name = "advertised",
|
||||||
"uint32_t time",
|
"uint32_t time",
|
||||||
|
"ipAddress ip",
|
||||||
|
"uint16_t port",
|
||||||
|
}
|
||||||
|
|
||||||
|
newStruct{
|
||||||
|
name = "disconnect",
|
||||||
|
"uint32_t reason",
|
||||||
}
|
}
|
||||||
|
|
||||||
local readBuffer = buffer.new( 1024 )
|
local readBuffer = buffer.new( 1024 )
|
||||||
|
|
Loading…
Reference in New Issue