vision/src/metaserver/main.lua

106 lines
3.0 KiB
Lua
Raw Normal View History

2023-09-23 20:36:06 +00:00
--Note, this won't work unless you set up port forwarding!
2023-09-12 01:00:00 +00:00
local SERVERTIMEOUT = 30
local CLIENTTIMEOUT = 1
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-23 20:36:06 +00:00
local msip = assert( require 'getip' )
udp:settimeout(0)
2023-09-23 20:36:06 +00:00
local localIP = socket.dns.toip(socket.dns.gethostname())
print( "Metaserver local IP:", localIP )
assert( udp:setsockname( localIP, 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 = {}
local tick = 0
2023-09-12 01:00:00 +00:00
2023-12-05 02:02:11 +00:00
local function serverID( ip, port )
return ip..":"..port
end
2023-09-12 01:00:00 +00:00
local handlers = setmetatable({
serverInfo = function( svInfo, ip, port )
print( "Server:", ip, port )
2023-12-05 02:02:11 +00:00
local id = serverID(ip, port)
2023-09-12 01:00:00 +00:00
local t = socket.gettime()
2023-12-05 02:02:11 +00:00
if not servers[id] then
servers[id] = { ip = ip, port = port, info = svInfo }
--NAT punch: the server doesn't know its own external IP
--so it contacts a third party (the metaserver) to discover it.
--This external IP gets advertised to prospective clients.
svInfo.ip.ip = ip
svInfo.port = port
end
2023-12-05 02:02:11 +00:00
servers[id].time = t
packet.advertised{ time = t, ip = svInfo.ip, port = svInfo.port }
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 )
--[[if ip ~= tostring( clientInfo.ip ) then
2023-09-12 01:00:00 +00:00
return print( ip, port, "Client IP mismatch:", clientInfo.ip )
end]]
print( "Server List:", ip, port )
2023-09-12 01:00:00 +00:00
clients[ip] = clients[ip] or {}
2023-09-12 01:00:00 +00:00
local t = socket.gettime()
clients[ip].time = t
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
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
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
2023-09-19 05:48:14 +00:00
print( "Starting Metaserver", os.time(), udp:getsockname() )
function love.update()
2023-09-12 01:00:00 +00:00
read( udp:receivefrom() )
prune( socket.gettime() )
io.flush()
tick = tick + 1
end