blob: 4ae4c871de9e6ff883c0203a3387cdf7d59df24a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
|