vision/src/metaserver/metaserver.lua

92 lines
2.5 KiB
Lua

local SERVERTIMEOUT = 30
local CLIENTTIMEOUT = 1
local shared = assert( require 'shared' )
local socket = assert( require 'socket' )
local packet = assert( shared.packet )
local udp = assert( socket.udp() )
udp:settimeout(0)
assert( udp:setsockname( shared.metaserver.ip, shared.metaserver.port ) )
--Servers broadcast their information here.
--The metaserver builds a list of available servers. ( available meaning, "broadcasted in last ten heartbeats" )
--Clients ask the metaserver for this list ( maybe with some filter? )
local servers = {}
local clients = {}
local tick = 0
local handlers = setmetatable({
serverInfo = function( svInfo, ip, port )
print( "Received server info from:", ip, port )
if ip ~= tostring( svInfo.ip ) then return print("Server IP mismatch:", ip, svInfo.ip) end
local t = socket.gettime()
if not servers[ip] then servers[ip] = { ip = ip, port = port, info = svInfo } end
servers[ip].time = t
packet.advertised{ time = t }
return udp:sendto( packet.get(), ip, port )
end,
default = function( s, ip, port )
print( ip, port, "Malformed message: ", s )
end,
metaServer = function()
end,
clientInfo = function( clientInfo, ip, port )
--[[if ip ~= tostring( clientInfo.ip ) then
return print( ip, port, "Client IP mismatch:", clientInfo.ip )
end]]
print( "Server List:", ip, port )
clients[ip] = clients[ip] or {}
local t = socket.gettime()
clients[ip].time = t
packet.heartbeat{ tick = tick }
for svIP, server in pairs( servers ) do
print( "", svIP, packet.getString( server.info.svname ))
packet.serverInfo( server.info )
end
return udp:sendto( packet.get(), ip, port )
end
},
{
__index = function(t) return t.default end
})
local function read(msg, ip, port)
if not msg then return end
local msgs, types = packet.deserialise( msg )
if types[1] ~= "metaServer" then
print( ip, port, "Dropped packet, no padding." )
return read( udp:receivefrom() )
end
for i = 1, #msgs do
handlers[ types[i] ]( msgs[i], ip, port )
end
return read( udp:receivefrom() )
end
local function prune( t )
for ip, server in pairs(servers) do
if server.time < t - SERVERTIMEOUT then
print( "Pruning server IP:", ip )
servers[ip] = nil
end
end
end
print( "Starting Metaserver", socket.gettime() )
repeat
read( udp:receivefrom() )
prune( socket.gettime() )
io.flush()
tick = tick + 1
until socket.sleep( 2.0 )