summaryrefslogtreecommitdiff
path: root/server.lua
diff options
context:
space:
mode:
Diffstat (limited to 'server.lua')
-rw-r--r--server.lua110
1 files changed, 110 insertions, 0 deletions
diff --git a/server.lua b/server.lua
new file mode 100644
index 0000000..4ae4c87
--- /dev/null
+++ b/server.lua
@@ -0,0 +1,110 @@
+local enet = require("enet")
+local json = require("json")
+local socket = require("socket")
+local base64 = require("base64")
+local common = require("common")
+
+local server = {}
+
+function server.create(match_addr)
+ local srv = {}
+
+ srv.host = enet.host_create()
+ srv.secret = common.rand_string(common.secret_len)
+ srv.clients = {}
+
+ srv.match = srv.host:connect(match_addr or common.default_match_addr)
+ srv.match_req = socket.gettime()
+
+ return srv
+end
+
+local function handle_match(srv, pkt)
+ if pkt.type == "server_match" then
+ if type(pkt.game_id) ~= "string" then
+ print("[server] server_match: invalid game_id")
+ return
+ end
+
+ if srv.game_id then
+ print("[server] server_match: received while game already running")
+ return
+ end
+
+ srv.game_id = pkt.game_id
+ srv.invite = base64.encode(srv.game_id .. srv.secret)
+ elseif pkt.type == "server_join" then
+ if type(pkt.peer_addr) ~= "string" then
+ print("[server] server_join: invalid peer_addr")
+ return
+ end
+ srv.host:connect(pkt.peer_addr)
+ end
+end
+
+local function handle_client(srv, peer, pkt)
+ if pkt.type == "server_hi" then
+ if type(pkt.secret) ~= "string" then
+ print("[server] server_hi: invalid secret")
+ return
+ end
+
+ if srv.clients[peer] then
+ print("[server] server_hi: client already connected")
+ return
+ end
+
+ if pkt.secret == srv.secret then
+ print("[server] auth success " .. tostring(peer))
+ srv.clients[peer] = { peer = peer }
+ peer:send(json.encode({ type = "client_hi" }))
+ else
+ print("[server] auth failure " .. tostring(peer))
+ peer:send(json.encode({ type = "client_reject" }))
+ peer:disconnect()
+ end
+ end
+end
+
+function server.update(srv)
+ local event = srv.host:service(20)
+ while event do
+ if event.type == "receive" then
+ local pkt = json.decode(event.data)
+ if event.peer == srv.match then
+ handle_match(srv, pkt)
+ else
+ handle_client(srv, event.peer, pkt)
+ end
+ elseif event.type == "connect" then
+ if event.peer == srv.match then
+ srv.match:send(json.encode({ type = "match_register" }))
+ end
+ print("[server] connect " .. tostring(event.peer))
+ elseif event.type == "disconnect" then
+ print("[server] disconnect " .. tostring(event.peer))
+ if event.peer == srv.match then
+ -- TODO
+ else
+ srv.clients[event.peer] = nil
+ end
+ end
+ event = srv.host:service()
+ end
+end
+
+function server.match_status(srv)
+ if srv.game_id then
+ return "active", srv.invite
+ elseif srv.match_req + 3 >= socket.gettime() then
+ return "wait"
+ else
+ return "fail"
+ end
+end
+
+function server.close(srv)
+ srv.host:destroy()
+end
+
+return server