starting to work on this again
This commit is contained in:
parent
2ca4a77b33
commit
bf12de9373
|
@ -5,7 +5,7 @@ local button = assert( require 'ui.button' )
|
||||||
local strings = assert( require 'strings' )
|
local strings = assert( require 'strings' )
|
||||||
local connecting = {}
|
local connecting = {}
|
||||||
|
|
||||||
local time, ip, port, attempts = 0, 0, 0, 1
|
local time, ip, port, attempts, svInfo = 0, 0, 0, 1
|
||||||
|
|
||||||
local cancelButton = button{
|
local cancelButton = button{
|
||||||
x = lg.getWidth() / 4,
|
x = lg.getWidth() / 4,
|
||||||
|
@ -76,7 +76,10 @@ function connecting:onLoad( params )
|
||||||
attempts = 1
|
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 )
|
if server.isValid( ip, port ) then
|
||||||
|
server.setInfo( params.svInfo )
|
||||||
|
return server.connect( ip, port )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function connecting.exit()
|
function connecting.exit()
|
||||||
|
|
|
@ -28,14 +28,22 @@ function handlers.playerChange( data )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function handlers.svInfo( data )
|
||||||
|
if server.svInfo.map ~= data.map then end
|
||||||
|
return server.setInfo( data )
|
||||||
|
end
|
||||||
|
|
||||||
function handlers.chatMessage( msg )
|
function handlers.chatMessage( msg )
|
||||||
print( msg.cmsg )
|
print( msg.cmsg )
|
||||||
end
|
end
|
||||||
|
|
||||||
function game.draw()
|
function game.draw()
|
||||||
lg.setColor( 1, 1, 1, 1 )
|
lg.setColor( 1, 1, 1, 1 )
|
||||||
lg.print( tick, 0, 0 )
|
lg.print( "Client Tick: "..tick, 0, 0 )
|
||||||
lg.print( serverTick, 0, 25 )
|
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
|
end
|
||||||
|
|
||||||
function game.onPacket( msg )
|
function game.onPacket( msg )
|
||||||
|
|
|
@ -2,7 +2,7 @@ local socket = assert( require 'socket' )
|
||||||
local ms = assert( require 'shared.metaserver' )
|
local ms = assert( require 'shared.metaserver' )
|
||||||
local config = assert( require 'config' )
|
local config = assert( require 'config' )
|
||||||
|
|
||||||
local udp = {}
|
local udp = { svInfo = {}, token = false, }
|
||||||
local packet = assert( require 'shared.packet' )
|
local packet = assert( require 'shared.packet' )
|
||||||
local hash = assert( require 'shared.hash' )
|
local hash = assert( require 'shared.hash' )
|
||||||
|
|
||||||
|
@ -39,6 +39,10 @@ function udp.setToken( token )
|
||||||
udp.token = token
|
udp.token = token
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function udp.setInfo( svInfo )
|
||||||
|
udp.svInfo = svInfo
|
||||||
|
end
|
||||||
|
|
||||||
function udp.answerChallenge( svNonce )
|
function udp.answerChallenge( svNonce )
|
||||||
local clNonce = hash.rand()
|
local clNonce = hash.rand()
|
||||||
packet.get()
|
packet.get()
|
||||||
|
|
|
@ -18,7 +18,7 @@ local cw = fonts.font:getWidth( "w" )
|
||||||
|
|
||||||
local function joinServerCallback( button )
|
local function joinServerCallback( button )
|
||||||
if button.ip and button.port then
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ function ti:callback() return self:enterText( browser.joinIPString ) end
|
||||||
local headerButtons = {
|
local headerButtons = {
|
||||||
|
|
||||||
button{
|
button{
|
||||||
callback = function() return serverList.requestServers() end,
|
callback = function() serverList.clear() return serverList.requestServers() end,
|
||||||
text = lg.newText( fonts.midFont, strings.refresh_button ) ,
|
text = lg.newText( fonts.midFont, strings.refresh_button ) ,
|
||||||
color = color,
|
color = color,
|
||||||
x = cw * 32,
|
x = cw * 32,
|
||||||
|
@ -144,7 +144,6 @@ end
|
||||||
local metaServerHandlers = setmetatable(
|
local metaServerHandlers = setmetatable(
|
||||||
{
|
{
|
||||||
default = function() end,
|
default = function() end,
|
||||||
connected = serverList.clear,
|
|
||||||
serverInfo = serverList.add,
|
serverInfo = serverList.add,
|
||||||
},
|
},
|
||||||
{__index = function( t ) return t.default end })
|
{__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
|
if ip and port then return browser.joinIP( ip, port ) end
|
||||||
end
|
end
|
||||||
|
|
||||||
function browser.joinIP( ip, port )
|
function browser.joinIP( ip, port, svInfo )
|
||||||
print( "Joining server:", ip, port )
|
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
|
end
|
||||||
|
|
||||||
function browser.keypressed( key, code, isRepeat )
|
function browser.keypressed( key, code, isRepeat )
|
||||||
|
|
|
@ -19,20 +19,25 @@ local servers = {}
|
||||||
local clients = {}
|
local clients = {}
|
||||||
local tick = 0
|
local tick = 0
|
||||||
|
|
||||||
|
local function serverID( ip, port )
|
||||||
|
return ip..":"..port
|
||||||
|
end
|
||||||
|
|
||||||
local handlers = setmetatable({
|
local handlers = setmetatable({
|
||||||
|
|
||||||
serverInfo = function( svInfo, ip, port )
|
serverInfo = function( svInfo, ip, port )
|
||||||
print( "Server:", ip, port )
|
print( "Server:", ip, port )
|
||||||
|
local id = serverID(ip, port)
|
||||||
local t = socket.gettime()
|
local t = socket.gettime()
|
||||||
if not servers[ip..port] then
|
if not servers[id] then
|
||||||
servers[ip..port] = { ip = ip, port = port, info = svInfo }
|
servers[id] = { ip = ip, port = port, info = svInfo }
|
||||||
--NAT punch: the server doesn't know its own external IP
|
--NAT punch: the server doesn't know its own external IP
|
||||||
--so it contacts a third party (the metaserver) to discover it.
|
--so it contacts a third party (the metaserver) to discover it.
|
||||||
--This external IP gets advertised to prospective clients.
|
--This external IP gets advertised to prospective clients.
|
||||||
svInfo.ip.ip = ip
|
svInfo.ip.ip = ip
|
||||||
svInfo.port = port
|
svInfo.port = port
|
||||||
end
|
end
|
||||||
servers[ip..port].time = t
|
servers[id].time = t
|
||||||
packet.advertised{ time = t, ip = svInfo.ip, port = svInfo.port }
|
packet.advertised{ time = t, ip = svInfo.ip, port = svInfo.port }
|
||||||
return udp:sendto( packet.get(), ip, port )
|
return udp:sendto( packet.get(), ip, port )
|
||||||
end,
|
end,
|
||||||
|
@ -56,8 +61,6 @@ local handlers = setmetatable({
|
||||||
|
|
||||||
local t = socket.gettime()
|
local t = socket.gettime()
|
||||||
clients[ip].time = t
|
clients[ip].time = t
|
||||||
|
|
||||||
packet.connected{ token = 5, tick = tick }
|
|
||||||
|
|
||||||
for svIP, server in pairs( servers ) do
|
for svIP, server in pairs( servers ) do
|
||||||
print( "", svIP, packet.getString( server.info.svname ))
|
print( "", svIP, packet.getString( server.info.svname ))
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
|
local clients = {}
|
||||||
local client = {}
|
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 )
|
function client.connect( ip, port )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function client.challenge( )
|
return client
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function client.acceptConnection( )
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function client.disconnect( )
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
return
|
|
|
@ -22,7 +22,7 @@ local svInfo = packet.serverInfo{ version = 13,
|
||||||
|
|
||||||
local clients = {}
|
local clients = {}
|
||||||
local connecting = {}
|
local connecting = {}
|
||||||
local server = { tick = 0, currentClient = false }
|
local server = { tick = 0, time = 0, currentClient = false }
|
||||||
|
|
||||||
local handlers = setmetatable({
|
local handlers = setmetatable({
|
||||||
|
|
||||||
|
@ -43,10 +43,10 @@ local handlers = setmetatable({
|
||||||
end
|
end
|
||||||
|
|
||||||
client.tick = msg.tick
|
client.tick = msg.tick
|
||||||
client.time = socket.gettime()
|
client.time = server.time
|
||||||
server.currentClient = client
|
server.currentClient = client
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--A client wants to disconnect.
|
--A client wants to disconnect.
|
||||||
disconnect = function( msg, ip, port )
|
disconnect = function( msg, ip, port )
|
||||||
--This is the authenticated client whose packets are being processed.
|
--This is the authenticated client whose packets are being processed.
|
||||||
|
@ -61,16 +61,16 @@ local handlers = setmetatable({
|
||||||
|
|
||||||
--Client responds to handshake challenge.
|
--Client responds to handshake challenge.
|
||||||
clChimo = function( clChimo, ip, port )
|
clChimo = function( clChimo, ip, port )
|
||||||
|
|
||||||
print( "Received handshake response." )
|
print( "Received handshake response." )
|
||||||
|
|
||||||
--No active challenge, don't send anything.
|
--No active challenge, don't send anything.
|
||||||
local key = ip..":"..port
|
local key = ip..":"..port
|
||||||
if not connecting[ key ] then
|
if not connecting[ key ] then
|
||||||
print( "Old connection attempt from:", key )
|
print( "Old connection attempt from:", key )
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
--Compute session token.
|
--Compute session token.
|
||||||
local remoteHash = clChimo.hash
|
local remoteHash = clChimo.hash
|
||||||
local clNonce = clChimo.nonce
|
local clNonce = clChimo.nonce
|
||||||
|
@ -80,10 +80,10 @@ 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
|
||||||
|
|
||||||
--Hash collision.
|
--Hash collision.
|
||||||
while clients[token] do token = token + 1 end
|
while clients[token] do token = token + 1 end
|
||||||
|
|
||||||
--Successful handshake.
|
--Successful handshake.
|
||||||
print( "Client connected:", token, port, ip )
|
print( "Client connected:", token, port, ip )
|
||||||
clients[ token ] = connecting[ key ]
|
clients[ token ] = connecting[ key ]
|
||||||
|
@ -175,17 +175,14 @@ end
|
||||||
|
|
||||||
function server.Advance()
|
function server.Advance()
|
||||||
server.tick = server.tick + 1
|
server.tick = server.tick + 1
|
||||||
server.time = socket.gettime()
|
for id, client in pairs( clients ) do
|
||||||
if server.tick % 100 == 0 then
|
packet.get()
|
||||||
for id, client in pairs( clients ) do
|
packet.connected{ token = id, tick = server.tick }
|
||||||
packet.get()
|
udp:sendto( packet.get(), client.ip, client.port )
|
||||||
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 )
|
||||||
if server.time - client.time > CLIENTTIMEOUT then
|
clients[id] = nil
|
||||||
print( "dropping client:", id )
|
|
||||||
clients[id] = nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -199,13 +196,16 @@ function server.Quit()
|
||||||
end
|
end
|
||||||
|
|
||||||
server.Start()
|
server.Start()
|
||||||
|
|
||||||
function love.update( dt )
|
function love.update( dt )
|
||||||
|
server.time = server.time + dt
|
||||||
server.Parse( udp:receivefrom() )
|
server.Parse( udp:receivefrom() )
|
||||||
server.Advance()
|
if server.time > 0.1 then
|
||||||
if server.tick % 4000 == 0 then
|
if (server.tick % 50) == 0 then
|
||||||
server.Advertise()
|
server.Advertise()
|
||||||
server.Parse( mscxn:receive(), shared.metaserver.ip, shared.metaserver.port )
|
server.Parse( mscxn:receive(), shared.metaserver.ip, shared.metaserver.port )
|
||||||
|
end
|
||||||
|
server.time = 0
|
||||||
|
server.Advance()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
local ffi = assert( require 'ffi' )
|
local ffi = assert( require 'ffi' )
|
||||||
local buffer = assert( require( "string.buffer" ) )
|
local buffer = assert( require( "string.buffer" ) )
|
||||||
local ipString = assert( require 'shared.ipstring' )
|
local ipString = assert( require 'shared.ipstring' )
|
||||||
|
local roles = assert( require 'shared.roles' )
|
||||||
local packet = {}
|
local packet = {}
|
||||||
local mt = { __index = { new = function( self ) return ffi.new( self.ct ) end } }
|
local mt = { __index = { new = function( self ) return ffi.new( self.ct ) end } }
|
||||||
|
|
||||||
|
@ -63,12 +64,13 @@ newStruct{
|
||||||
name = "insect",
|
name = "insect",
|
||||||
"uint8_t id",
|
"uint8_t id",
|
||||||
"bool dead",
|
"bool dead",
|
||||||
|
"int16_t z",
|
||||||
"int8_t hp",
|
"int8_t hp",
|
||||||
"int8_t vx",
|
"int8_t vx",
|
||||||
"int8_t vy",
|
"int8_t vy",
|
||||||
"uint8_t folio",
|
"int8_t vz",
|
||||||
"uint32_t x",
|
"int32_t x",
|
||||||
"uint32_t y",
|
"int32_t y",
|
||||||
}
|
}
|
||||||
|
|
||||||
newStruct{
|
newStruct{
|
||||||
|
@ -80,9 +82,9 @@ newStruct{
|
||||||
}
|
}
|
||||||
|
|
||||||
newStruct{
|
newStruct{
|
||||||
name = "playerChange",
|
name = "playerInfo",
|
||||||
"uint8_t id",
|
"uint8_t id",
|
||||||
"uint8_t role",
|
"role_t role",
|
||||||
"char username[31]",
|
"char username[31]",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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' )
|
Loading…
Reference in New Issue