new metaserver
This commit is contained in:
parent
b6acaeb496
commit
8558d918ec
|
|
@ -1,2 +1,3 @@
|
||||||
logs/
|
logs/
|
||||||
build/
|
build/
|
||||||
|
mood/
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
color 0a
|
|
||||||
D:/dev/love/love.exe "./client/"
|
|
||||||
pause
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
D:/dev/love/love.exe "./metaserver/"
|
|
||||||
pause
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
function love.conf(t)
|
|
||||||
t.identity = "metaserver" -- The name of the save directory (string)
|
|
||||||
t.appendidentity = false -- Search files in source directory before save directory (boolean)
|
|
||||||
t.version = "11.4" -- The LÖVE version this game was made for (string)
|
|
||||||
t.console = true -- Attach a console (boolean, Windows only)
|
|
||||||
t.accelerometerjoystick = false -- Enable the accelerometer on iOS and Android by exposing it as a Joystick (boolean)
|
|
||||||
t.externalstorage = false -- True to save files (and read from the save directory) in external storage on Android (boolean)
|
|
||||||
t.gammacorrect = false -- Enable gamma-correct rendering, when supported by the system (boolean)
|
|
||||||
|
|
||||||
t.audio.mic = false -- Request and use microphone capabilities in Android (boolean)
|
|
||||||
t.audio.mixwithsystem = true -- Keep background music playing when opening LOVE (boolean, iOS and Android only)
|
|
||||||
|
|
||||||
t.window.title = "metaserver" -- The window title (string)
|
|
||||||
t.window.icon = false -- Filepath to an image to use as the window's icon (string)
|
|
||||||
t.window.width = 800 -- The window width (number)
|
|
||||||
t.window.height = 600 -- The window height (number)
|
|
||||||
t.window.borderless = false -- Remove all border visuals from the window (boolean)
|
|
||||||
t.window.resizable = true -- Let the window be user-resizable (boolean)
|
|
||||||
t.window.minwidth = 400 -- Minimum window width if the window is resizable (number)
|
|
||||||
t.window.minheight = 400 -- Minimum window height if the window is resizable (number)
|
|
||||||
t.window.fullscreen = false -- Enable fullscreen (boolean)
|
|
||||||
t.window.fullscreentype = "desktop" -- Choose between "desktop" fullscreen or "exclusive" fullscreen mode (string)
|
|
||||||
t.window.vsync = 1 -- Vertical sync mode (number)
|
|
||||||
t.window.msaa = 3 -- The number of samples to use with multi-sampled antialiasing (number)
|
|
||||||
t.window.depth = nil -- The number of bits per sample in the depth buffer
|
|
||||||
t.window.stencil = nil -- The number of bits per sample in the stencil buffer
|
|
||||||
t.window.display = 1 -- Index of the monitor to show the window in (number)
|
|
||||||
t.window.highdpi = false -- Enable high-dpi mode for the window on a Retina display (boolean)
|
|
||||||
t.window.usedpiscale = true -- Enable automatic DPI scaling when highdpi is set to true as well (boolean)
|
|
||||||
t.window.x = nil -- The x-coordinate of the window's position in the specified display (number)
|
|
||||||
t.window.y = nil -- The y-coordinate of the window's position in the specified display (number)
|
|
||||||
|
|
||||||
t.modules.audio = false -- Enable the audio module (boolean)
|
|
||||||
t.modules.data = true -- Enable the data module (boolean)
|
|
||||||
t.modules.event = true -- Enable the event module (boolean)
|
|
||||||
t.modules.font = false -- Enable the font module (boolean)
|
|
||||||
t.modules.graphics = false -- Enable the graphics module (boolean)
|
|
||||||
t.modules.image = false -- Enable the image module (boolean)
|
|
||||||
t.modules.joystick = false -- Enable the joystick module (boolean)
|
|
||||||
t.modules.keyboard = false -- Enable the keyboard module (boolean)
|
|
||||||
t.modules.math = false -- Enable the math module (boolean)
|
|
||||||
t.modules.mouse = false -- Enable the mouse module (boolean)
|
|
||||||
t.modules.physics = false -- Enable the physics module (boolean)
|
|
||||||
t.modules.sound = false -- Enable the sound module (boolean)
|
|
||||||
t.modules.system = false -- Enable the system module (boolean)
|
|
||||||
t.modules.thread = false -- Enable the thread module (boolean)
|
|
||||||
t.modules.timer = true -- Enable the timer module (boolean), Disabling it will result 0 delta time in love.update
|
|
||||||
t.modules.touch = false -- Enable the touch module (boolean)
|
|
||||||
t.modules.video = false -- Enable the video module (boolean)
|
|
||||||
t.modules.window = false -- Enable the window module (boolean)
|
|
||||||
end
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
assert( assert( require 'socket.http' ).request 'https://api.ipify.org' == '142.162.167.92')
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
--Note, this won't work unless you set up port forwarding!
|
|
||||||
local SERVERTIMEOUT = 30
|
|
||||||
local CLIENTTIMEOUT = 1
|
|
||||||
|
|
||||||
local shared = assert( require '../shared.shared' )
|
|
||||||
local socket = assert( require 'socket' )
|
|
||||||
local packet = assert( shared.packet )
|
|
||||||
local udp = assert( socket.udp() )
|
|
||||||
local msip = assert( require 'getip' )
|
|
||||||
udp:settimeout(0)
|
|
||||||
local localIP = socket.dns.toip(socket.dns.gethostname())
|
|
||||||
print( "Metaserver local IP:", localIP )
|
|
||||||
assert( udp:setsockname( localIP, 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 function serverID( ip, port )
|
|
||||||
return ip..":"..port
|
|
||||||
end
|
|
||||||
|
|
||||||
local handlers = setmetatable({
|
|
||||||
|
|
||||||
serverInfo = function( svInfo, ip, port )
|
|
||||||
print( "Server:", ip, port )
|
|
||||||
local id = serverID(ip, port)
|
|
||||||
local t = socket.gettime()
|
|
||||||
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
|
|
||||||
servers[id].time = t
|
|
||||||
packet.advertised{ time = t, ip = svInfo.ip, port = svInfo.port }
|
|
||||||
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
|
|
||||||
|
|
||||||
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", os.time(), udp:getsockname() )
|
|
||||||
function love.update()
|
|
||||||
read( udp:receivefrom() )
|
|
||||||
prune( socket.gettime() )
|
|
||||||
io.flush()
|
|
||||||
tick = tick + 1
|
|
||||||
end
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
local ffi = assert( require( "ffi" ) )
|
||||||
|
|
||||||
|
local metaServerFormats = setmetatable({}, {__index = {
|
||||||
|
domain = "vision.wan-may.art",
|
||||||
|
port = 10587,
|
||||||
|
}})
|
||||||
|
|
||||||
|
local function instantiate( fmt, ... )
|
||||||
|
return fmt.ct( fmt.header, ... )
|
||||||
|
end
|
||||||
|
|
||||||
|
local formatMetatable = { __call = instantiate }
|
||||||
|
local i = 1
|
||||||
|
|
||||||
|
local function addFormat( name, decl )
|
||||||
|
local fmt = { name = name, header = i, ct = ffi.typeof(decl) }
|
||||||
|
fmt.size = ffi.sizeof( fmt.ct )
|
||||||
|
metaServerFormats[name] = fmt
|
||||||
|
metaServerFormats[i] = fmt
|
||||||
|
setmetatable( fmt, formatMetatable )
|
||||||
|
print( "loading msv protocol", fmt.header, fmt.size, fmt.name )
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
ffi.cdef[[ typedef struct{
|
||||||
|
uint8_t players;
|
||||||
|
uint8_t capacity;
|
||||||
|
uint16_t gameTime;
|
||||||
|
uint32_t serverTime;
|
||||||
|
char svName[32];
|
||||||
|
char mapID[32];
|
||||||
|
} gameInfo;]]
|
||||||
|
|
||||||
|
--sent by server
|
||||||
|
addFormat("addServer", [[struct{
|
||||||
|
uint8_t header;
|
||||||
|
} ]])
|
||||||
|
|
||||||
|
--sent by metaserver
|
||||||
|
addFormat("challenge", [[struct{
|
||||||
|
uint8_t header;
|
||||||
|
uint32_t challenge;
|
||||||
|
} ]])
|
||||||
|
|
||||||
|
--sent by server
|
||||||
|
addFormat("updateServer", [[struct{
|
||||||
|
uint8_t header;
|
||||||
|
uint32_t response;
|
||||||
|
gameInfo info;
|
||||||
|
} ]])
|
||||||
|
|
||||||
|
--sent by client to metaServer
|
||||||
|
addFormat("getServerList", [[struct{
|
||||||
|
uint8_t header;
|
||||||
|
}]])
|
||||||
|
|
||||||
|
--sent by metaserver to client
|
||||||
|
addFormat("serverListing", [[struct{
|
||||||
|
uint8_t header;
|
||||||
|
char ip[39];
|
||||||
|
uint16_t port;
|
||||||
|
gameInfo info;
|
||||||
|
}]])
|
||||||
|
|
||||||
|
--sent by client to metaserver, then by metaserver to server
|
||||||
|
addFormat("requestConnection", [[struct{
|
||||||
|
uint8_t header;
|
||||||
|
char ip[39];
|
||||||
|
uint16_t port;
|
||||||
|
}]])
|
||||||
|
|
||||||
|
return metaServerFormats
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
color 04
|
|
||||||
D:/dev/love/love.exe "./server/"
|
|
||||||
pause
|
|
||||||
Loading…
Reference in New Issue