-
Notifications
You must be signed in to change notification settings - Fork 0
/
client_test.lua
180 lines (139 loc) · 4.21 KB
/
client_test.lua
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package.cpath = "skynet/luaclib/?.so;lib/?.so;"
local socket = require "client.socket"
local crypt = require "client.crypt"
if _VERSION ~= "Lua 5.3" then
error "Use lua 5.3"
end
local fd = assert(socket.connect("127.0.0.1", 8001))
local function writeline(fd, text)
socket.send(fd, text .. "\n")
end
local function unpack_line(text)
local from = text:find("\n", 1, true)
if from then
return text:sub(1, from-1), text:sub(from+1)
end
return nil, text
end
local last = ""
local function unpack_f(f)
local function try_recv(fd, last)
local result
result, last = f(last)
if result then
return result, last
end
local r = socket.recv(fd)
if not r then
return nil, last
end
if r == "" then
error "Server closed"
end
return f(last .. r)
end
return function()
while true do
local result
result, last = try_recv(fd, last)
if result then
return result
end
socket.usleep(100)
end
end
end
local readline = unpack_f(unpack_line)
local challenge = crypt.base64decode(readline())
local clientkey = crypt.randomkey()
writeline(fd, crypt.base64encode(crypt.dhexchange(clientkey)))
local secret = crypt.dhsecret(crypt.base64decode(readline()), clientkey)
print("sceret is ", crypt.hexencode(secret))
local hmac = crypt.hmac64(challenge, secret)
writeline(fd, crypt.base64encode(hmac))
local token = {
server = "GATE_GAME",
user = "hello",
pass = "password",
}
local function encode_token(token)
return string.format("%s@%s:%s",
crypt.base64encode(token.user),
crypt.base64encode(token.server),
crypt.base64encode(token.pass))
end
local etoken = crypt.desencode(secret, encode_token(token))
local b = crypt.base64encode(etoken)
writeline(fd, crypt.base64encode(etoken))
local result = readline()
print(result)
local code = tonumber(string.sub(result, 1, 3))
assert(code == 200)
socket.close(fd)
local cjson = require("cjson")
local serverInfo = crypt.base64decode(string.sub(result, 5))
serverInfo = cjson.decode(serverInfo)
local uid = serverInfo.uid
token.user = uid
local gateName = serverInfo.gateName
token.server = gateName
local subid = serverInfo.subid
local gateAddress = serverInfo.gateAddress
local gatePort = serverInfo.gatePort
print("login ok, subid=", uid, subid, gateName, gateAddress, gatePort)
----- connect to game server
local function send_request(v, session)
local size = #v + 4
local package = string.pack(">I2", size)..v..string.pack(">I4", session)
socket.send(fd, package)
return v, session
end
local function recv_response(v)
local size = #v - 5
local content, ok, session = string.unpack("c"..tostring(size).."B>I4", v)
return ok ~=0 , content, session
end
local function unpack_package(text)
local size = #text
if size < 2 then
return nil, text
end
local s = text:byte(1) * 256 + text:byte(2)
if size < s+2 then
return nil, text
end
return text:sub(3,2+s), text:sub(3+s)
end
local readpackage = unpack_f(unpack_package)
local function send_package(fd, pack)
local package = string.pack(">s2", pack)
socket.send(fd, package)
end
local text = "echo"
local index = 1
print("connect")
fd = assert(socket.connect(gateAddress, gatePort))
last = ""
local handshake = string.format("%s@%s#%s:%d", crypt.base64encode(token.user), crypt.base64encode(token.server),crypt.base64encode(subid) , index)
local hmac = crypt.hmac64(crypt.hashkey(handshake), secret)
send_package(fd, handshake .. ":" .. crypt.base64encode(hmac))
print(readpackage())
print("===>",send_request(text,0))
-- don't recv response
-- print("<===",recv_response(readpackage()))
print("disconnect")
socket.close(fd)
index = index + 1
print("connect again")
fd = assert(socket.connect(gateAddress, gatePort))
last = ""
local handshake = string.format("%s@%s#%s:%d", crypt.base64encode(token.user), crypt.base64encode(token.server),crypt.base64encode(subid) , index)
local hmac = crypt.hmac64(crypt.hashkey(handshake), secret)
send_package(fd, handshake .. ":" .. crypt.base64encode(hmac))
print(readpackage())
print("===>",send_request("fake",0)) -- request again (use last session 0, so the request message is fake)
print("===>",send_request("again",1)) -- request again (use new session)
print("<===",recv_response(readpackage()))
print("<===",recv_response(readpackage()))
print("disconnect")
socket.close(fd)