summaryrefslogtreecommitdiff
path: root/client.lua
diff options
context:
space:
mode:
Diffstat (limited to 'client.lua')
-rw-r--r--client.lua119
1 files changed, 119 insertions, 0 deletions
diff --git a/client.lua b/client.lua
new file mode 100644
index 0000000..43ddda0
--- /dev/null
+++ b/client.lua
@@ -0,0 +1,119 @@
+local enet = require("enet")
+local json = require("json")
+local socket = require("socket")
+local base64 = require("base64")
+local common = require("common")
+
+local client = {}
+
+local function create_client(secret)
+ local clt = {}
+ clt.host = enet.host_create() -- enet.host_create("10.75.98.51:58901")
+ clt.secret = secret
+ return clt
+end
+
+local function connect(clt, addr)
+ clt.server = clt.host:connect(addr)
+ clt.server_req = socket.gettime()
+ clt.status = "wait_server"
+end
+
+function client.join(invite, match_addr)
+ local invite_dec = base64.decode(invite)
+ local game_id = invite_dec:sub(1, common.gameid_len)
+ local secret = invite_dec:sub(common.gameid_len+1)
+
+ local clt = create_client(secret)
+ clt.match = clt.host:connect(match_addr or common.default_match_addr)
+ clt.match:send(json.encode({ type = "match_join", game_id = game_id }))
+ clt.match_req = socket.gettime()
+ clt.game_id = game_id
+ clt.status = "wait_match"
+ return clt
+end
+
+function client.connect(addr, secret)
+ local clt = create_client(secret)
+ connect(clt, addr)
+ return clt
+end
+
+local function handle_match(clt, pkt)
+ if pkt.type == "client_join" then
+ if type(pkt.peer_addr) ~= "string" then
+ print("[client] client_join: invalid peer_addr")
+ return
+ end
+ connect(clt, pkt.peer_addr)
+ elseif pkt.type == "client_join_fail" then
+ clt.status = "fail_match"
+ end
+end
+
+local function handle_server(clt, pkt)
+ if pkt.type == "client_hi" then
+ clt.status = "active"
+ elseif pkt.type == "client_reject" then
+ clt.status = "fail_server"
+ end
+end
+
+function client.update(clt)
+ local event = clt.host:service(20)
+ while event do
+ if event.type == "receive" then
+ local pkt = json.decode(event.data)
+ if event.peer == clt.match and clt.status == "wait_match" then
+ handle_match(clt, pkt)
+ clt.match:disconnect()
+ clt.match = nil
+ elseif event.peer == clt.server then
+ handle_server(clt, pkt)
+ end
+ elseif event.type == "connect" then
+ if event.peer == clt.match and clt.status == "wait_match" then
+ clt.match:send(json.encode({ type = "match_join", game_id = clt.game_id }))
+ elseif event.peer == clt.server and clt.status == "wait_server" then
+ clt.server:send(json.encode({ type = "server_hi", secret = clt.secret }))
+ else
+ event.peer:disconnect_now()
+ end
+ print("[client] connect " .. tostring(event.peer))
+ elseif event.type == "disconnect" then
+ print("[client] disconnect " .. tostring(event.peer))
+ if event.peer == clt.server and clt.status == "active" then
+ clt.status = "disco"
+ end
+ end
+ event = clt.host:service()
+ end
+end
+
+function client.status(clt)
+ if clt.status == "wait_match" and clt.match_req+3 < socket.gettime() then
+ clt.status = "timeout_match"
+ elseif clt.status == "wait_server" and clt.match_req+5 < socket.gettime() then
+ clt.status = "timeout_server"
+ end
+
+ return clt.status
+
+
+ -- wait_match
+ -- wait_server
+
+ -- timeout_match
+ -- fail_match
+ -- timeout_server
+ -- fail_server
+
+ -- active
+ -- disco
+end
+
+function client.close(clt)
+ clt.host:destroy()
+end
+
+return client