forked from heroiclabs/nakama
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmatch.lua
328 lines (282 loc) · 12.7 KB
/
match.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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
--[[
Copyright 2018 The Nakama Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--]]
local du = require("debug_utils")
--[[
Called when a match is created as a result of nk.match_create().
Context represents information about the match and server, for information purposes. Format:
{
env = {}, -- key-value data set in the runtime.env server configuration.
execution_mode = "Match",
match_id = "client-friendly match ID, can be shared with clients and used in match join operations",
match_node = "name of the Nakama node hosting this match"
}
Params is the optional arbitrary second argument passed to `nk.match_create()`, or `nil` if none was used.
Expected return these values (all required) in order:
1. The initial in-memory state of the match. May be any non-nil Lua term, or nil to end the match.
2. Tick rate representing the desired number of match loop calls per second. Must be between 1 and 30, inclusive.
3. A string label that can be used to filter matches in listing operations. Must be between 0 and 256 characters long.
--]]
local function match_init(context, params)
local state = {
debug = (params and params.debug) or false,
foo = function()
return "bar"
end
}
if state.debug then
print("match init context:\n" .. du.print_r(context) .. "match init params:\n" .. du.print_r(params))
end
local tick_rate = 1
local label = (params and params.label) or "skill=100-150"
return state, tick_rate, label
end
--[[
Called when a user attempts to join the match using the client's match join operation.
Context represents information about the match and server, for information purposes. Format:
{
env = {}, -- key-value data set in the runtime.env server configuration.
execution_mode = "Match",
match_id = "client-friendly match ID, can be shared with clients and used in match join operations",
match_node = "name of the Nakama node hosting this match",
match_label = "the label string returned from match_init",
match_tick_rate = 1 -- the tick rate returned by match_init
}
Dispatcher exposes useful functions to the match. Format:
{
broadcast_message = function(op_code, data, presences, sender),
-- numeric message op code
-- a data payload string, or nil
-- list of presences (a subset of match participants) to use as message targets, or nil to send to the whole match
-- a presence to tag on the message as the 'sender', or nil
match_kick = function(presences)
-- a list of presences to remove from the match
match_label_update = function(label)
-- a new label to set for the match
}
Tick is the current match tick number, starts at 0 and increments after every match_loop call. Does not increment with
calls to match_join_attempt, match_join, or match_leave.
State is the current in-memory match state, may be any Lua term except nil.
Presence is the user attempting to join the match. Format:
{
user_id: "user unique ID",
session_id: "session ID of the user's current connection",
username: "user's unique username",
node: "name of the Nakama node the user is connected to"
}
Metadata is an optional set of arbitrary key-value pairs received from the client. These may contain information
the client wishes to supply to the match handler in order to process the join attempt, for example: authentication or
match passwords, client version information, preferences etc. Format:
{
key: "value"
}
Expected return these values (all required) in order:
1. An (optionally) updated state. May be any non-nil Lua term, or nil to end the match.
2. Boolean true if the join attempt should be allowed, false otherwise.
--]]
local function match_join_attempt(context, dispatcher, tick, state, presence, metadata)
if state.debug then
print("match join attempt:\n" .. du.print_r(presence))
print("match join attempt metadata:\n" .. du.print_r(metadata))
end
return state, true
end
--[[
Called when one or more users have successfully completed the match join process after their match_join_attempt returns
`true`. When their presences are sent to this function the users are ready to receive match data messages and can be
targets for the dispatcher's `broadcast_message` function.
Context represents information about the match and server, for information purposes. Format:
{
env = {}, -- key-value data set in the runtime.env server configuration.
execution_mode = "Match",
match_id = "client-friendly match ID, can be shared with clients and used in match join operations",
match_node = "name of the Nakama node hosting this match",
match_label = "the label string returned from match_init",
match_tick_rate = 1 -- the tick rate returned by match_init
}
Dispatcher exposes useful functions to the match. Format:
{
broadcast_message = function(op_code, data, presences, sender),
-- numeric message op code
-- a data payload string, or nil
-- list of presences (a subset of match participants) to use as message targets, or nil to send to the whole match
-- a presence to tag on the message as the 'sender', or nil
match_kick = function(presences)
-- a list of presences to remove from the match
match_label_update = function(label)
-- a new label to set for the match
}
Tick is the current match tick number, starts at 0 and increments after every match_loop call. Does not increment with
calls to match_join_attempt, match_join, or match_leave.
State is the current in-memory match state, may be any Lua term except nil.
Presences is a list of users that have joined the match. Format:
{
{
user_id: "user unique ID",
session_id: "session ID of the user's current connection",
username: "user's unique username",
node: "name of the Nakama node the user is connected to"
},
...
}
Expected return these values (all required) in order:
1. An (optionally) updated state. May be any non-nil Lua term, or nil to end the match.
--]]
local function match_join(context, dispatcher, tick, state, presences)
if state.debug then
print("match join:\n" .. du.print_r(presences))
end
return state
end
--[[
Called when one or more users have left the match for any reason, including connection loss.
Context represents information about the match and server, for information purposes. Format:
{
env = {}, -- key-value data set in the runtime.env server configuration.
execution_mode = "Match",
match_id = "client-friendly match ID, can be shared with clients and used in match join operations",
match_node = "name of the Nakama node hosting this match",
match_label = "the label string returned from match_init",
match_tick_rate = 1 -- the tick rate returned by match_init
}
Dispatcher exposes useful functions to the match. Format:
{
broadcast_message = function(op_code, data, presences, sender),
-- numeric message op code
-- a data payload string, or nil
-- list of presences (a subset of match participants) to use as message targets, or nil to send to the whole match
-- a presence to tag on the message as the 'sender', or nil
match_kick = function(presences)
-- a list of presences to remove from the match
match_label_update = function(label)
-- a new label to set for the match
}
Tick is the current match tick number, starts at 0 and increments after every match_loop call. Does not increment with
calls to match_join_attempt, match_join, or match_leave.
State is the current in-memory match state, may be any Lua term except nil.
Presences is a list of users that have left the match. Format:
{
{
user_id: "user unique ID",
session_id: "session ID of the user's current connection",
username: "user's unique username",
node: "name of the Nakama node the user is connected to"
},
...
}
Expected return these values (all required) in order:
1. An (optionally) updated state. May be any non-nil Lua term, or nil to end the match.
--]]
local function match_leave(context, dispatcher, tick, state, presences)
if state.debug then
print("match leave:\n" .. du.print_r(presences))
end
return state
end
--[[
Called on an interval based on the tick rate returned by match_init.
Context represents information about the match and server, for information purposes. Format:
{
env = {}, -- key-value data set in the runtime.env server configuration.
executionMode = "Match",
match_id = "client-friendly match ID, can be shared with clients and used in match join operations",
match_node = "name of the Nakama node hosting this match",
match_label = "the label string returned from match_init",
match_tick_rate = 1 -- the tick rate returned by match_init
}
Dispatcher exposes useful functions to the match. Format:
{
broadcast_message = function(op_code, data, presences, sender),
-- numeric message op code
-- a data payload string, or nil
-- list of presences (a subset of match participants) to use as message targets, or nil to send to the whole match
-- a presence to tag on the message as the 'sender', or nil
match_kick = function(presences)
-- a list of presences to remove from the match
match_label_update = function(label)
-- a new label to set for the match
}
Tick is the current match tick number, starts at 0 and increments after every match_loop call. Does not increment with
calls to match_join_attempt, match_join, or match_leave.
State is the current in-memory match state, may be any Lua term except nil.
Messages is a list of data messages received from users between the previous and current ticks. Format:
{
{
sender = {
user_id: "user unique ID",
session_id: "session ID of the user's current connection",
username: "user's unique username",
node: "name of the Nakama node the user is connected to"
},
op_code = 1, -- numeric op code set by the sender.
data = "any string data set by the sender" -- may be nil.
},
...
}
Expected return these values (all required) in order:
1. An (optionally) updated state. May be any non-nil Lua term, or nil to end the match.
--]]
local function match_loop(context, dispatcher, tick, state, messages)
if state.debug then
print("match " .. context.match_id .. " tick " .. tick)
print("match " .. context.match_id .. " messages:\n" .. du.print_r(messages))
end
if tick < 10 then
return state
end
end
--[[
Called when the server begins a graceful shutdown process. Will not be called if graceful shutdown is disabled.
Context represents information about the match and server, for information purposes. Format:
{
env = {}, -- key-value data set in the runtime.env server configuration.
executionMode = "Match",
match_id = "client-friendly match ID, can be shared with clients and used in match join operations",
match_node = "name of the Nakama node hosting this match",
match_label = "the label string returned from match_init",
match_tick_rate = 1 -- the tick rate returned by match_init
}
Dispatcher exposes useful functions to the match. Format:
{
broadcast_message = function(op_code, data, presences, sender),
-- numeric message op code
-- a data payload string, or nil
-- list of presences (a subset of match participants) to use as message targets, or nil to send to the whole match
-- a presence to tag on the message as the 'sender', or nil
match_kick = function(presences)
-- a list of presences to remove from the match
match_label_update = function(label)
-- a new label to set for the match
}
Tick is the current match tick number, starts at 0 and increments after every match_loop call. Does not increment with
calls to match_join_attempt, match_join, or match_leave.
State is the current in-memory match state, may be any Lua term except nil.
Grace Seconds is the number of seconds remaining until the server will shut down.
Expected return these values (all required) in order:
1. An (optionally) updated state. May be any non-nil Lua term, or nil to end the match.
--]]
local function match_terminate(context, dispatcher, tick, state, grace_seconds)
if state.debug then
print("match " .. context.match_id .. " tick " .. tick)
print("match " .. context.match_id .. " grace_seconds " .. grace_seconds)
end
return state
end
-- Match modules must return a table with these functions defined. All functions are required.
return {
match_init = match_init,
match_join_attempt = match_join_attempt,
match_join = match_join,
match_leave = match_leave,
match_loop = match_loop,
match_terminate = match_terminate
}