2023-09-12 01:00:00 +00:00
|
|
|
local SERVERTIMEOUT = 30
|
|
|
|
local CLIENTTIMEOUT = 1
|
|
|
|
|
2023-09-19 04:31:42 +00:00
|
|
|
local shared = assert( require '../shared.shared' )
|
2023-09-11 22:44:36 +00:00
|
|
|
local socket = assert( require 'socket' )
|
2023-09-12 01:00:00 +00:00
|
|
|
local packet = assert( shared.packet )
|
2023-09-11 22:44:36 +00:00
|
|
|
local udp = assert( socket.udp() )
|
2023-09-17 03:09:51 +00:00
|
|
|
udp:settimeout(0)
|
|
|
|
assert( udp:setsockname( shared.metaserver.ip, shared.metaserver.port ) )
|
2023-09-11 22:44:36 +00:00
|
|
|
|
|
|
|
--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? )
|
2023-09-12 01:00:00 +00:00
|
|
|
local servers = {}
|
|
|
|
local clients = {}
|
2023-09-17 03:09:51 +00:00
|
|
|
local tick = 0
|
2023-09-12 01:00:00 +00:00
|
|
|
|
|
|
|
local handlers = setmetatable({
|
|
|
|
|
|
|
|
serverInfo = function( svInfo, ip, port )
|
2023-09-17 03:09:51 +00:00
|
|
|
print( "Received server info from:", ip, port )
|
2023-09-12 01:00:00 +00:00
|
|
|
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 }
|
2023-09-17 22:12:13 +00:00
|
|
|
return udp:sendto( packet.get(), ip, port )
|
2023-09-12 01:00:00 +00:00
|
|
|
end,
|
|
|
|
|
|
|
|
default = function( s, ip, port )
|
|
|
|
print( ip, port, "Malformed message: ", s )
|
|
|
|
end,
|
|
|
|
|
|
|
|
metaServer = function()
|
2023-09-11 22:44:36 +00:00
|
|
|
|
2023-09-12 01:00:00 +00:00
|
|
|
end,
|
|
|
|
|
|
|
|
clientInfo = function( clientInfo, ip, port )
|
2023-09-17 03:09:51 +00:00
|
|
|
--[[if ip ~= tostring( clientInfo.ip ) then
|
2023-09-12 01:00:00 +00:00
|
|
|
return print( ip, port, "Client IP mismatch:", clientInfo.ip )
|
2023-09-17 03:09:51 +00:00
|
|
|
end]]
|
|
|
|
|
2023-09-17 22:12:13 +00:00
|
|
|
print( "Server List:", ip, port )
|
2023-09-12 01:00:00 +00:00
|
|
|
|
2023-09-17 03:09:51 +00:00
|
|
|
clients[ip] = clients[ip] or {}
|
2023-09-12 01:00:00 +00:00
|
|
|
|
|
|
|
local t = socket.gettime()
|
|
|
|
clients[ip].time = t
|
|
|
|
|
2023-09-17 03:09:51 +00:00
|
|
|
packet.heartbeat{ tick = tick }
|
2023-09-17 22:12:13 +00:00
|
|
|
for svIP, server in pairs( servers ) do
|
|
|
|
print( "", svIP, packet.getString( server.info.svname ))
|
2023-09-12 01:00:00 +00:00
|
|
|
packet.serverInfo( server.info )
|
|
|
|
end
|
|
|
|
|
2023-09-17 22:12:13 +00:00
|
|
|
return udp:sendto( packet.get(), ip, port )
|
2023-09-12 01:00:00 +00:00
|
|
|
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
|
2023-09-11 22:44:36 +00:00
|
|
|
|
2023-09-12 01:00:00 +00:00
|
|
|
local function prune( t )
|
|
|
|
for ip, server in pairs(servers) do
|
|
|
|
if server.time < t - SERVERTIMEOUT then
|
2023-09-17 03:09:51 +00:00
|
|
|
print( "Pruning server IP:", ip )
|
2023-09-12 01:00:00 +00:00
|
|
|
servers[ip] = nil
|
|
|
|
end
|
|
|
|
end
|
2023-09-11 22:44:36 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
print( "Starting Metaserver", socket.gettime() )
|
2023-09-19 04:31:42 +00:00
|
|
|
function love.update()
|
2023-09-12 01:00:00 +00:00
|
|
|
read( udp:receivefrom() )
|
|
|
|
prune( socket.gettime() )
|
|
|
|
io.flush()
|
2023-09-17 03:09:51 +00:00
|
|
|
tick = tick + 1
|
2023-09-19 04:31:42 +00:00
|
|
|
end
|