@rbxts/tether 1.4.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/out/emitters/client-emitter.d.ts +49 -0
- package/out/emitters/client-emitter.luau +156 -0
- package/out/emitters/contextual-emitter.d.ts +26 -0
- package/out/emitters/contextual-emitter.luau +49 -0
- package/out/emitters/message-emitter.d.ts +41 -0
- package/out/emitters/message-emitter.luau +222 -0
- package/out/emitters/server-emitter.d.ts +30 -0
- package/out/emitters/server-emitter.luau +107 -0
- package/out/index.d.ts +1 -1
- package/out/init.luau +1 -1
- package/out/logging.d.ts +15 -0
- package/out/logging.luau +4 -0
- package/out/relayer.d.ts +16 -0
- package/out/relayer.luau +214 -0
- package/out/serdes.d.ts +13 -0
- package/out/serdes.luau +58 -0
- package/out/structs.d.ts +3 -2
- package/out/utility.d.ts +12 -0
- package/out/utility.luau +74 -0
- package/package.json +1 -1
- package/out/message-emitter.d.ts +0 -128
- package/out/message-emitter.luau +0 -792
package/out/message-emitter.luau
DELETED
|
@@ -1,792 +0,0 @@
|
|
|
1
|
-
-- Compiled with roblox-ts v3.0.0
|
|
2
|
-
local TS = _G[script]
|
|
3
|
-
local _services = TS.import(script, TS.getModule(script, "@rbxts", "services"))
|
|
4
|
-
local Players = _services.Players
|
|
5
|
-
local ReplicatedStorage = _services.ReplicatedStorage
|
|
6
|
-
local RunService = _services.RunService
|
|
7
|
-
local Destroyable = TS.import(script, TS.getModule(script, "@rbxts", "destroyable").out).default
|
|
8
|
-
local Object = TS.import(script, TS.getModule(script, "@rbxts", "object-utils"))
|
|
9
|
-
local createSerializer = TS.import(script, TS.getModule(script, "@rbxts", "serio").out).default
|
|
10
|
-
local repr = TS.import(script, TS.getModule(script, "@rbxts", "repr").out)
|
|
11
|
-
local _middleware = TS.import(script, script.Parent, "middleware")
|
|
12
|
-
local DropRequest = _middleware.DropRequest
|
|
13
|
-
local MiddlewareProvider = _middleware.MiddlewareProvider
|
|
14
|
-
local IS_LUNE = string.sub(_VERSION, 1, 4) == "Lune"
|
|
15
|
-
if setLuneContext == nil then
|
|
16
|
-
setLuneContext = function() end
|
|
17
|
-
end
|
|
18
|
-
setLuneContext("both")
|
|
19
|
-
local noServerListen = "[@rbxts/tether]: Cannot listen to server message from client"
|
|
20
|
-
local noClientListen = "[@rbxts/tether]: Cannot listen to client message from server"
|
|
21
|
-
local metaGenerationFailed = "[@rbxts/tether]: Failed to generate message metadata - make sure you have the Flamework transformer and are using Flamework macro-friendly types in your schemas"
|
|
22
|
-
local guardFailed = function(message, data)
|
|
23
|
-
return `[@rbxts/tether]: Type validation guard failed for message '{message}' - check your sent data\nSent data: {repr(data)}`
|
|
24
|
-
end
|
|
25
|
-
local defaultMesssageEmitterOptions = {
|
|
26
|
-
batchRemotes = true,
|
|
27
|
-
batchRate = 1 / 24,
|
|
28
|
-
}
|
|
29
|
-
local sendMessage
|
|
30
|
-
do
|
|
31
|
-
local name = "sendMessage"
|
|
32
|
-
local existing = ReplicatedStorage:FindFirstChild(name)
|
|
33
|
-
local remote = (existing or Instance.new("RemoteEvent", ReplicatedStorage))
|
|
34
|
-
if existing == nil then
|
|
35
|
-
remote.Name = name
|
|
36
|
-
end
|
|
37
|
-
sendMessage = remote
|
|
38
|
-
end
|
|
39
|
-
local sendUnreliableMessage
|
|
40
|
-
do
|
|
41
|
-
local name = "unreliableMessage"
|
|
42
|
-
local existing = ReplicatedStorage:FindFirstChild(name)
|
|
43
|
-
local remote = (existing or Instance.new("UnreliableRemoteEvent", ReplicatedStorage))
|
|
44
|
-
if existing == nil then
|
|
45
|
-
remote.Name = name
|
|
46
|
-
end
|
|
47
|
-
sendUnreliableMessage = remote
|
|
48
|
-
end
|
|
49
|
-
local MessageEmitter
|
|
50
|
-
do
|
|
51
|
-
local super = Destroyable
|
|
52
|
-
MessageEmitter = setmetatable({}, {
|
|
53
|
-
__tostring = function()
|
|
54
|
-
return "MessageEmitter"
|
|
55
|
-
end,
|
|
56
|
-
__index = super,
|
|
57
|
-
})
|
|
58
|
-
MessageEmitter.__index = MessageEmitter
|
|
59
|
-
function MessageEmitter.new(...)
|
|
60
|
-
local self = setmetatable({}, MessageEmitter)
|
|
61
|
-
return self:constructor(...) or self
|
|
62
|
-
end
|
|
63
|
-
function MessageEmitter:constructor(options)
|
|
64
|
-
if options == nil then
|
|
65
|
-
options = defaultMesssageEmitterOptions
|
|
66
|
-
end
|
|
67
|
-
super.constructor(self)
|
|
68
|
-
self.options = options
|
|
69
|
-
self.middleware = MiddlewareProvider.new()
|
|
70
|
-
self.guards = {}
|
|
71
|
-
self.serializers = {}
|
|
72
|
-
self.clientCallbacks = {}
|
|
73
|
-
self.clientFunctions = {}
|
|
74
|
-
self.serverCallbacks = {}
|
|
75
|
-
self.serverFunctions = {}
|
|
76
|
-
self.serverQueue = {}
|
|
77
|
-
self.clientBroadcastQueue = {}
|
|
78
|
-
self.clientQueue = {}
|
|
79
|
-
self.server = {
|
|
80
|
-
on = function(message, callback)
|
|
81
|
-
if RunService:IsClient() then
|
|
82
|
-
error(noServerListen)
|
|
83
|
-
end
|
|
84
|
-
return self:on(message, callback, self.serverCallbacks)
|
|
85
|
-
end,
|
|
86
|
-
once = function(message, callback)
|
|
87
|
-
if RunService:IsClient() then
|
|
88
|
-
error(noServerListen)
|
|
89
|
-
end
|
|
90
|
-
return self:once(message, callback, self.serverCallbacks)
|
|
91
|
-
end,
|
|
92
|
-
emit = function(message, data, unreliable)
|
|
93
|
-
if unreliable == nil then
|
|
94
|
-
unreliable = false
|
|
95
|
-
end
|
|
96
|
-
if RunService:IsServer() then
|
|
97
|
-
error("[@rbxts/tether]: Cannot emit message to server from server")
|
|
98
|
-
end
|
|
99
|
-
task.spawn(function()
|
|
100
|
-
local _binding = self:runServerMiddlewares(message, data)
|
|
101
|
-
local dropRequest = _binding[1]
|
|
102
|
-
local newData = _binding[2]
|
|
103
|
-
if dropRequest then
|
|
104
|
-
return nil
|
|
105
|
-
end
|
|
106
|
-
local _serverQueue = self.serverQueue
|
|
107
|
-
local _arg0 = { message, newData, unreliable }
|
|
108
|
-
table.insert(_serverQueue, _arg0)
|
|
109
|
-
if not self.options.batchRemotes then
|
|
110
|
-
self:update()
|
|
111
|
-
end
|
|
112
|
-
end)
|
|
113
|
-
end,
|
|
114
|
-
invoke = TS.async(function(message, returnMessage, data, unreliable)
|
|
115
|
-
if unreliable == nil then
|
|
116
|
-
unreliable = false
|
|
117
|
-
end
|
|
118
|
-
if RunService:IsServer() then
|
|
119
|
-
error("[@rbxts/tether]: Cannot invoke server function from server")
|
|
120
|
-
end
|
|
121
|
-
local _clientFunctions = self.clientFunctions
|
|
122
|
-
local _returnMessage = returnMessage
|
|
123
|
-
if not (_clientFunctions[_returnMessage] ~= nil) then
|
|
124
|
-
local _clientFunctions_1 = self.clientFunctions
|
|
125
|
-
local _returnMessage_1 = returnMessage
|
|
126
|
-
_clientFunctions_1[_returnMessage_1] = {}
|
|
127
|
-
end
|
|
128
|
-
local _clientFunctions_1 = self.clientFunctions
|
|
129
|
-
local _returnMessage_1 = returnMessage
|
|
130
|
-
local functions = _clientFunctions_1[_returnMessage_1]
|
|
131
|
-
local returnValue
|
|
132
|
-
local responseCallback = function(data)
|
|
133
|
-
returnValue = data
|
|
134
|
-
return returnValue
|
|
135
|
-
end
|
|
136
|
-
functions[responseCallback] = true
|
|
137
|
-
self.server.emit(message, data, unreliable)
|
|
138
|
-
while returnValue == nil do
|
|
139
|
-
RunService.Heartbeat:Wait()
|
|
140
|
-
end
|
|
141
|
-
-- Clean up the callback after receiving the response
|
|
142
|
-
functions[responseCallback] = nil
|
|
143
|
-
return returnValue
|
|
144
|
-
end),
|
|
145
|
-
setCallback = function(message, returnMessage, callback)
|
|
146
|
-
if RunService:IsClient() then
|
|
147
|
-
error(noServerListen)
|
|
148
|
-
end
|
|
149
|
-
return self.server.on(message, function(player, data)
|
|
150
|
-
local returnValue = callback(player, data)
|
|
151
|
-
-- Defer the response emission to end of frame and swap context to avoid context check issues
|
|
152
|
-
-- task.defer guarantees response is sent by end of current frame, ensuring predictable timing in production
|
|
153
|
-
task.defer(function()
|
|
154
|
-
setLuneContext("server")
|
|
155
|
-
self.client.emit(player, returnMessage, returnValue)
|
|
156
|
-
setLuneContext("both")
|
|
157
|
-
end)
|
|
158
|
-
end)
|
|
159
|
-
end,
|
|
160
|
-
}
|
|
161
|
-
self.client = {
|
|
162
|
-
on = function(message, callback)
|
|
163
|
-
if RunService:IsServer() then
|
|
164
|
-
error(noClientListen)
|
|
165
|
-
end
|
|
166
|
-
return self:on(message, callback, self.clientCallbacks)
|
|
167
|
-
end,
|
|
168
|
-
once = function(message, callback)
|
|
169
|
-
if RunService:IsServer() then
|
|
170
|
-
error(noClientListen)
|
|
171
|
-
end
|
|
172
|
-
return self:once(message, callback, self.clientCallbacks)
|
|
173
|
-
end,
|
|
174
|
-
emit = function(player, message, data, unreliable)
|
|
175
|
-
if unreliable == nil then
|
|
176
|
-
unreliable = false
|
|
177
|
-
end
|
|
178
|
-
if RunService:IsClient() then
|
|
179
|
-
error("[@rbxts/tether]: Cannot emit message to client from client")
|
|
180
|
-
end
|
|
181
|
-
task.spawn(function()
|
|
182
|
-
local _binding = self:runClientMiddlewares(message, data)
|
|
183
|
-
local dropRequest = _binding[1]
|
|
184
|
-
local newData = _binding[2]
|
|
185
|
-
if dropRequest then
|
|
186
|
-
return nil
|
|
187
|
-
end
|
|
188
|
-
local _clientQueue = self.clientQueue
|
|
189
|
-
local _arg0 = { player, message, newData, unreliable }
|
|
190
|
-
table.insert(_clientQueue, _arg0)
|
|
191
|
-
if not self.options.batchRemotes then
|
|
192
|
-
self:update()
|
|
193
|
-
end
|
|
194
|
-
end)
|
|
195
|
-
end,
|
|
196
|
-
emitExcept = function(player, message, data, unreliable)
|
|
197
|
-
if unreliable == nil then
|
|
198
|
-
unreliable = false
|
|
199
|
-
end
|
|
200
|
-
local shouldSendTo = function(p)
|
|
201
|
-
local _player = player
|
|
202
|
-
local _result
|
|
203
|
-
if typeof(_player) == "Instance" then
|
|
204
|
-
_result = p ~= player
|
|
205
|
-
else
|
|
206
|
-
local _player_1 = player
|
|
207
|
-
local _p = p
|
|
208
|
-
_result = not (table.find(_player_1, _p) ~= nil)
|
|
209
|
-
end
|
|
210
|
-
return _result
|
|
211
|
-
end
|
|
212
|
-
local _client = self.client
|
|
213
|
-
local _exp = Players:GetPlayers()
|
|
214
|
-
-- ▼ ReadonlyArray.filter ▼
|
|
215
|
-
local _newValue = {}
|
|
216
|
-
local _length = 0
|
|
217
|
-
for _k, _v in _exp do
|
|
218
|
-
if shouldSendTo(_v, _k - 1, _exp) == true then
|
|
219
|
-
_length += 1
|
|
220
|
-
_newValue[_length] = _v
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
-- ▲ ReadonlyArray.filter ▲
|
|
224
|
-
_client.emit(_newValue, message, data, unreliable)
|
|
225
|
-
end,
|
|
226
|
-
emitAll = function(message, data, unreliable)
|
|
227
|
-
if unreliable == nil then
|
|
228
|
-
unreliable = false
|
|
229
|
-
end
|
|
230
|
-
if RunService:IsClient() then
|
|
231
|
-
error("[@rbxts/tether]: Cannot emit message to all clients from client")
|
|
232
|
-
end
|
|
233
|
-
task.spawn(function()
|
|
234
|
-
local _binding = self:runClientMiddlewares(message, data)
|
|
235
|
-
local dropRequest = _binding[1]
|
|
236
|
-
local newData = _binding[2]
|
|
237
|
-
if dropRequest then
|
|
238
|
-
return nil
|
|
239
|
-
end
|
|
240
|
-
local _clientBroadcastQueue = self.clientBroadcastQueue
|
|
241
|
-
local _arg0 = { message, newData, unreliable }
|
|
242
|
-
table.insert(_clientBroadcastQueue, _arg0)
|
|
243
|
-
if not self.options.batchRemotes then
|
|
244
|
-
self:update()
|
|
245
|
-
end
|
|
246
|
-
end)
|
|
247
|
-
end,
|
|
248
|
-
invoke = TS.async(function(message, returnMessage, player, data, unreliable)
|
|
249
|
-
if unreliable == nil then
|
|
250
|
-
unreliable = false
|
|
251
|
-
end
|
|
252
|
-
if RunService:IsClient() then
|
|
253
|
-
error("[@rbxts/tether]: Cannot invoke client function from client")
|
|
254
|
-
end
|
|
255
|
-
local _serverFunctions = self.serverFunctions
|
|
256
|
-
local _returnMessage = returnMessage
|
|
257
|
-
if not (_serverFunctions[_returnMessage] ~= nil) then
|
|
258
|
-
local _serverFunctions_1 = self.serverFunctions
|
|
259
|
-
local _returnMessage_1 = returnMessage
|
|
260
|
-
_serverFunctions_1[_returnMessage_1] = {}
|
|
261
|
-
end
|
|
262
|
-
local _serverFunctions_1 = self.serverFunctions
|
|
263
|
-
local _returnMessage_1 = returnMessage
|
|
264
|
-
local functions = _serverFunctions_1[_returnMessage_1]
|
|
265
|
-
local returnValue
|
|
266
|
-
local responseCallback = function(data)
|
|
267
|
-
returnValue = data
|
|
268
|
-
return returnValue
|
|
269
|
-
end
|
|
270
|
-
functions[responseCallback] = true
|
|
271
|
-
self.client.emit(player, message, data, unreliable)
|
|
272
|
-
while returnValue == nil do
|
|
273
|
-
RunService.Heartbeat:Wait()
|
|
274
|
-
end
|
|
275
|
-
-- Clean up the callback after receiving the response
|
|
276
|
-
functions[responseCallback] = nil
|
|
277
|
-
return returnValue
|
|
278
|
-
end),
|
|
279
|
-
setCallback = function(message, returnMessage, callback)
|
|
280
|
-
if RunService:IsServer() then
|
|
281
|
-
error(noClientListen)
|
|
282
|
-
end
|
|
283
|
-
return self.client.on(message, function(data)
|
|
284
|
-
local returnValue = callback(data)
|
|
285
|
-
-- Defer the response emission to end of frame and swap context to avoid context check issues
|
|
286
|
-
-- task.defer guarantees response is sent by end of current frame, ensuring predictable timing in production
|
|
287
|
-
task.defer(function()
|
|
288
|
-
setLuneContext("client")
|
|
289
|
-
self.server.emit(returnMessage, returnValue)
|
|
290
|
-
setLuneContext("both")
|
|
291
|
-
end)
|
|
292
|
-
end)
|
|
293
|
-
end,
|
|
294
|
-
}
|
|
295
|
-
self.trash:add(function()
|
|
296
|
-
self.clientCallbacks = {}
|
|
297
|
-
self.serverCallbacks = {}
|
|
298
|
-
self.clientFunctions = {}
|
|
299
|
-
self.clientCallbacks = {}
|
|
300
|
-
self.serializers = {}
|
|
301
|
-
setmetatable(self, nil)
|
|
302
|
-
end)
|
|
303
|
-
end
|
|
304
|
-
function MessageEmitter:create(options, meta)
|
|
305
|
-
local emitter = MessageEmitter.new(Object.assign({}, defaultMesssageEmitterOptions, options))
|
|
306
|
-
if meta == nil then
|
|
307
|
-
warn(metaGenerationFailed)
|
|
308
|
-
return emitter:initialize()
|
|
309
|
-
end
|
|
310
|
-
for kind, _binding in pairs(meta) do
|
|
311
|
-
local guard = _binding.guard
|
|
312
|
-
local serializerMetadata = _binding.serializerMetadata
|
|
313
|
-
local numberKind = tonumber(kind)
|
|
314
|
-
emitter.guards[numberKind] = guard
|
|
315
|
-
if serializerMetadata == nil then
|
|
316
|
-
continue
|
|
317
|
-
end
|
|
318
|
-
emitter:addSerializer(numberKind, serializerMetadata)
|
|
319
|
-
end
|
|
320
|
-
return emitter:initialize()
|
|
321
|
-
end
|
|
322
|
-
function MessageEmitter:initialize()
|
|
323
|
-
setLuneContext("client")
|
|
324
|
-
if RunService:IsClient() then
|
|
325
|
-
self.trash:add(sendMessage.OnClientEvent:Connect(function(...)
|
|
326
|
-
local serializedPacket = { ... }
|
|
327
|
-
return self:onRemoteFire(false, serializedPacket)
|
|
328
|
-
end))
|
|
329
|
-
self.trash:add(sendUnreliableMessage.OnClientEvent:Connect(function(...)
|
|
330
|
-
local serializedPacket = { ... }
|
|
331
|
-
return self:onRemoteFire(false, serializedPacket)
|
|
332
|
-
end))
|
|
333
|
-
end
|
|
334
|
-
setLuneContext("server")
|
|
335
|
-
if RunService:IsServer() then
|
|
336
|
-
self.trash:add(sendMessage.OnServerEvent:Connect(function(player, ...)
|
|
337
|
-
local serializedPacket = { ... }
|
|
338
|
-
return self:onRemoteFire(true, serializedPacket, player)
|
|
339
|
-
end))
|
|
340
|
-
self.trash:add(sendUnreliableMessage.OnServerEvent:Connect(function(player, ...)
|
|
341
|
-
local serializedPacket = { ... }
|
|
342
|
-
return self:onRemoteFire(true, serializedPacket, player)
|
|
343
|
-
end))
|
|
344
|
-
end
|
|
345
|
-
local elapsed = 0
|
|
346
|
-
local _binding = self.options
|
|
347
|
-
local batchRemotes = _binding.batchRemotes
|
|
348
|
-
local batchRate = _binding.batchRate
|
|
349
|
-
if not batchRemotes then
|
|
350
|
-
return self
|
|
351
|
-
end
|
|
352
|
-
self.trash:add(RunService.Heartbeat:Connect(function(dt)
|
|
353
|
-
elapsed += dt
|
|
354
|
-
if elapsed < batchRate then
|
|
355
|
-
return nil
|
|
356
|
-
end
|
|
357
|
-
elapsed -= batchRate
|
|
358
|
-
self:update()
|
|
359
|
-
end))
|
|
360
|
-
return self
|
|
361
|
-
end
|
|
362
|
-
function MessageEmitter:update()
|
|
363
|
-
local getPacket = function(info)
|
|
364
|
-
return info.packet
|
|
365
|
-
end
|
|
366
|
-
if RunService:IsClient() then
|
|
367
|
-
if #self.serverQueue == 0 then
|
|
368
|
-
return nil
|
|
369
|
-
end
|
|
370
|
-
local _exp = self.serverQueue
|
|
371
|
-
-- ▼ ReadonlyArray.map ▼
|
|
372
|
-
local _newValue = table.create(#_exp)
|
|
373
|
-
local _callback = function(_param)
|
|
374
|
-
local message = _param[1]
|
|
375
|
-
local data = _param[2]
|
|
376
|
-
local unreliable = _param[3]
|
|
377
|
-
local packet = self:getPacket(message, data)
|
|
378
|
-
return {
|
|
379
|
-
packet = packet,
|
|
380
|
-
unreliable = unreliable,
|
|
381
|
-
}
|
|
382
|
-
end
|
|
383
|
-
for _k, _v in _exp do
|
|
384
|
-
_newValue[_k] = _callback(_v, _k - 1, _exp)
|
|
385
|
-
end
|
|
386
|
-
-- ▲ ReadonlyArray.map ▲
|
|
387
|
-
local serverPacketInfos = _newValue
|
|
388
|
-
-- ▼ ReadonlyArray.filter ▼
|
|
389
|
-
local _newValue_1 = {}
|
|
390
|
-
local _callback_1 = function(info)
|
|
391
|
-
return info.unreliable
|
|
392
|
-
end
|
|
393
|
-
local _length = 0
|
|
394
|
-
for _k, _v in serverPacketInfos do
|
|
395
|
-
if _callback_1(_v, _k - 1, serverPacketInfos) == true then
|
|
396
|
-
_length += 1
|
|
397
|
-
_newValue_1[_length] = _v
|
|
398
|
-
end
|
|
399
|
-
end
|
|
400
|
-
-- ▲ ReadonlyArray.filter ▲
|
|
401
|
-
-- ▼ ReadonlyArray.map ▼
|
|
402
|
-
local _newValue_2 = table.create(#_newValue_1)
|
|
403
|
-
for _k, _v in _newValue_1 do
|
|
404
|
-
_newValue_2[_k] = getPacket(_v, _k - 1, _newValue_1)
|
|
405
|
-
end
|
|
406
|
-
-- ▲ ReadonlyArray.map ▲
|
|
407
|
-
local unreliableServerPackets = _newValue_2
|
|
408
|
-
-- ▼ ReadonlyArray.filter ▼
|
|
409
|
-
local _newValue_3 = {}
|
|
410
|
-
local _callback_2 = function(info)
|
|
411
|
-
return not info.unreliable
|
|
412
|
-
end
|
|
413
|
-
local _length_1 = 0
|
|
414
|
-
for _k, _v in serverPacketInfos do
|
|
415
|
-
if _callback_2(_v, _k - 1, serverPacketInfos) == true then
|
|
416
|
-
_length_1 += 1
|
|
417
|
-
_newValue_3[_length_1] = _v
|
|
418
|
-
end
|
|
419
|
-
end
|
|
420
|
-
-- ▲ ReadonlyArray.filter ▲
|
|
421
|
-
-- ▼ ReadonlyArray.map ▼
|
|
422
|
-
local _newValue_4 = table.create(#_newValue_3)
|
|
423
|
-
for _k, _v in _newValue_3 do
|
|
424
|
-
_newValue_4[_k] = getPacket(_v, _k - 1, _newValue_3)
|
|
425
|
-
end
|
|
426
|
-
-- ▲ ReadonlyArray.map ▲
|
|
427
|
-
local serverPackets = _newValue_4
|
|
428
|
-
if not (#unreliableServerPackets == 0) then
|
|
429
|
-
sendUnreliableMessage:FireServer(unpack(unreliableServerPackets))
|
|
430
|
-
end
|
|
431
|
-
if not (#serverPackets == 0) then
|
|
432
|
-
sendMessage:FireServer(unpack(serverPackets))
|
|
433
|
-
end
|
|
434
|
-
self.serverQueue = {}
|
|
435
|
-
return nil
|
|
436
|
-
end
|
|
437
|
-
local clientPackets = {}
|
|
438
|
-
local addClientPacket = function(player, packetInfo)
|
|
439
|
-
local _player = player
|
|
440
|
-
local _condition = clientPackets[_player]
|
|
441
|
-
if _condition == nil then
|
|
442
|
-
_condition = {}
|
|
443
|
-
end
|
|
444
|
-
local packetList = _condition
|
|
445
|
-
local _packetInfo = packetInfo
|
|
446
|
-
table.insert(packetList, _packetInfo)
|
|
447
|
-
local _player_1 = player
|
|
448
|
-
clientPackets[_player_1] = packetList
|
|
449
|
-
end
|
|
450
|
-
for _, _binding in self.clientQueue do
|
|
451
|
-
local player = _binding[1]
|
|
452
|
-
local message = _binding[2]
|
|
453
|
-
local data = _binding[3]
|
|
454
|
-
local unreliable = _binding[4]
|
|
455
|
-
local packet = self:getPacket(message, data)
|
|
456
|
-
local info = {
|
|
457
|
-
packet = packet,
|
|
458
|
-
unreliable = unreliable,
|
|
459
|
-
}
|
|
460
|
-
if typeof(player) == "Instance" then
|
|
461
|
-
addClientPacket(player, info)
|
|
462
|
-
else
|
|
463
|
-
for _1, p in player do
|
|
464
|
-
addClientPacket(p, info)
|
|
465
|
-
end
|
|
466
|
-
end
|
|
467
|
-
end
|
|
468
|
-
if not (#self.clientBroadcastQueue == 0) then
|
|
469
|
-
local _exp = self.clientBroadcastQueue
|
|
470
|
-
-- ▼ ReadonlyArray.map ▼
|
|
471
|
-
local _newValue = table.create(#_exp)
|
|
472
|
-
local _callback = function(_param)
|
|
473
|
-
local message = _param[1]
|
|
474
|
-
local data = _param[2]
|
|
475
|
-
local unreliable = _param[3]
|
|
476
|
-
local packet = self:getPacket(message, data)
|
|
477
|
-
return {
|
|
478
|
-
packet = packet,
|
|
479
|
-
unreliable = unreliable,
|
|
480
|
-
}
|
|
481
|
-
end
|
|
482
|
-
for _k, _v in _exp do
|
|
483
|
-
_newValue[_k] = _callback(_v, _k - 1, _exp)
|
|
484
|
-
end
|
|
485
|
-
-- ▲ ReadonlyArray.map ▲
|
|
486
|
-
local clientBroadcastPackets = _newValue
|
|
487
|
-
-- ▼ ReadonlyArray.filter ▼
|
|
488
|
-
local _newValue_1 = {}
|
|
489
|
-
local _callback_1 = function(info)
|
|
490
|
-
return info.unreliable
|
|
491
|
-
end
|
|
492
|
-
local _length = 0
|
|
493
|
-
for _k, _v in clientBroadcastPackets do
|
|
494
|
-
if _callback_1(_v, _k - 1, clientBroadcastPackets) == true then
|
|
495
|
-
_length += 1
|
|
496
|
-
_newValue_1[_length] = _v
|
|
497
|
-
end
|
|
498
|
-
end
|
|
499
|
-
-- ▲ ReadonlyArray.filter ▲
|
|
500
|
-
-- ▼ ReadonlyArray.map ▼
|
|
501
|
-
local _newValue_2 = table.create(#_newValue_1)
|
|
502
|
-
for _k, _v in _newValue_1 do
|
|
503
|
-
_newValue_2[_k] = getPacket(_v, _k - 1, _newValue_1)
|
|
504
|
-
end
|
|
505
|
-
-- ▲ ReadonlyArray.map ▲
|
|
506
|
-
local unreliableBroadcastPackets = _newValue_2
|
|
507
|
-
-- ▼ ReadonlyArray.filter ▼
|
|
508
|
-
local _newValue_3 = {}
|
|
509
|
-
local _callback_2 = function(info)
|
|
510
|
-
return not info.unreliable
|
|
511
|
-
end
|
|
512
|
-
local _length_1 = 0
|
|
513
|
-
for _k, _v in clientBroadcastPackets do
|
|
514
|
-
if _callback_2(_v, _k - 1, clientBroadcastPackets) == true then
|
|
515
|
-
_length_1 += 1
|
|
516
|
-
_newValue_3[_length_1] = _v
|
|
517
|
-
end
|
|
518
|
-
end
|
|
519
|
-
-- ▲ ReadonlyArray.filter ▲
|
|
520
|
-
-- ▼ ReadonlyArray.map ▼
|
|
521
|
-
local _newValue_4 = table.create(#_newValue_3)
|
|
522
|
-
for _k, _v in _newValue_3 do
|
|
523
|
-
_newValue_4[_k] = getPacket(_v, _k - 1, _newValue_3)
|
|
524
|
-
end
|
|
525
|
-
-- ▲ ReadonlyArray.map ▲
|
|
526
|
-
local broadcastPackets = _newValue_4
|
|
527
|
-
if not (#unreliableBroadcastPackets == 0) then
|
|
528
|
-
sendUnreliableMessage:FireAllClients(unpack(unreliableBroadcastPackets))
|
|
529
|
-
end
|
|
530
|
-
if not (#broadcastPackets == 0) then
|
|
531
|
-
sendMessage:FireAllClients(unpack(broadcastPackets))
|
|
532
|
-
end
|
|
533
|
-
self.clientBroadcastQueue = {}
|
|
534
|
-
end
|
|
535
|
-
if not (#self.clientQueue == 0) then
|
|
536
|
-
for player, packetInfo in clientPackets do
|
|
537
|
-
if #packetInfo == 0 then
|
|
538
|
-
continue
|
|
539
|
-
end
|
|
540
|
-
if #packetInfo == 0 then
|
|
541
|
-
continue
|
|
542
|
-
end
|
|
543
|
-
-- ▼ ReadonlyArray.filter ▼
|
|
544
|
-
local _newValue = {}
|
|
545
|
-
local _callback = function(info)
|
|
546
|
-
return info.unreliable
|
|
547
|
-
end
|
|
548
|
-
local _length = 0
|
|
549
|
-
for _k, _v in packetInfo do
|
|
550
|
-
if _callback(_v, _k - 1, packetInfo) == true then
|
|
551
|
-
_length += 1
|
|
552
|
-
_newValue[_length] = _v
|
|
553
|
-
end
|
|
554
|
-
end
|
|
555
|
-
-- ▲ ReadonlyArray.filter ▲
|
|
556
|
-
-- ▼ ReadonlyArray.map ▼
|
|
557
|
-
local _newValue_1 = table.create(#_newValue)
|
|
558
|
-
for _k, _v in _newValue do
|
|
559
|
-
_newValue_1[_k] = getPacket(_v, _k - 1, _newValue)
|
|
560
|
-
end
|
|
561
|
-
-- ▲ ReadonlyArray.map ▲
|
|
562
|
-
local unreliablePackets = _newValue_1
|
|
563
|
-
-- ▼ ReadonlyArray.filter ▼
|
|
564
|
-
local _newValue_2 = {}
|
|
565
|
-
local _callback_1 = function(info)
|
|
566
|
-
return not info.unreliable
|
|
567
|
-
end
|
|
568
|
-
local _length_1 = 0
|
|
569
|
-
for _k, _v in packetInfo do
|
|
570
|
-
if _callback_1(_v, _k - 1, packetInfo) == true then
|
|
571
|
-
_length_1 += 1
|
|
572
|
-
_newValue_2[_length_1] = _v
|
|
573
|
-
end
|
|
574
|
-
end
|
|
575
|
-
-- ▲ ReadonlyArray.filter ▲
|
|
576
|
-
-- ▼ ReadonlyArray.map ▼
|
|
577
|
-
local _newValue_3 = table.create(#_newValue_2)
|
|
578
|
-
for _k, _v in _newValue_2 do
|
|
579
|
-
_newValue_3[_k] = getPacket(_v, _k - 1, _newValue_2)
|
|
580
|
-
end
|
|
581
|
-
-- ▲ ReadonlyArray.map ▲
|
|
582
|
-
local packets = _newValue_3
|
|
583
|
-
if not (#unreliablePackets == 0) then
|
|
584
|
-
sendUnreliableMessage:FireClient(player, unpack(unreliablePackets))
|
|
585
|
-
end
|
|
586
|
-
if not (#packets == 0) then
|
|
587
|
-
sendMessage:FireClient(player, unpack(packets))
|
|
588
|
-
end
|
|
589
|
-
end
|
|
590
|
-
self.clientQueue = {}
|
|
591
|
-
end
|
|
592
|
-
end
|
|
593
|
-
function MessageEmitter:runClientMiddlewares(message, data, player)
|
|
594
|
-
if not self:validateData(message, data) then
|
|
595
|
-
return { true, data }
|
|
596
|
-
end
|
|
597
|
-
local players = player or Players:GetPlayers()
|
|
598
|
-
local ctx = {
|
|
599
|
-
message = message,
|
|
600
|
-
data = data,
|
|
601
|
-
getRawData = function()
|
|
602
|
-
return self:getPacket(message, data)
|
|
603
|
-
end,
|
|
604
|
-
}
|
|
605
|
-
for _, globalMiddleware in self.middleware:getClientGlobal() do
|
|
606
|
-
local result = globalMiddleware(players, ctx)
|
|
607
|
-
if not self:validateData(message, ctx.data, "Invalid data after global client middleware") then
|
|
608
|
-
return { false, ctx.data }
|
|
609
|
-
end
|
|
610
|
-
if result == DropRequest then
|
|
611
|
-
self.middleware:notifyRequestDropped(message, "Global client middleware")
|
|
612
|
-
return { true, ctx.data }
|
|
613
|
-
end
|
|
614
|
-
end
|
|
615
|
-
for _, middleware in self.middleware:getClient(message) do
|
|
616
|
-
local result = middleware(players, ctx)
|
|
617
|
-
if not self:validateData(message, ctx.data, "Invalid data after client middleware") then
|
|
618
|
-
return { false, ctx.data }
|
|
619
|
-
end
|
|
620
|
-
if result == DropRequest then
|
|
621
|
-
self.middleware:notifyRequestDropped(message, "Client middleware")
|
|
622
|
-
return { true, ctx.data }
|
|
623
|
-
end
|
|
624
|
-
end
|
|
625
|
-
if not self:validateData(message, ctx.data) then
|
|
626
|
-
return { true, ctx.data }
|
|
627
|
-
end
|
|
628
|
-
return { false, ctx.data }
|
|
629
|
-
end
|
|
630
|
-
function MessageEmitter:runServerMiddlewares(message, data)
|
|
631
|
-
if not self:validateData(message, data) then
|
|
632
|
-
return { true, data }
|
|
633
|
-
end
|
|
634
|
-
local ctx = {
|
|
635
|
-
message = message,
|
|
636
|
-
data = data,
|
|
637
|
-
getRawData = function()
|
|
638
|
-
return self:getPacket(message, data)
|
|
639
|
-
end,
|
|
640
|
-
}
|
|
641
|
-
for _, globalMiddleware in self.middleware:getServerGlobal() do
|
|
642
|
-
if not self:validateData(message, ctx.data, "Invalid data after global server middleware") then
|
|
643
|
-
return { false, ctx.data }
|
|
644
|
-
end
|
|
645
|
-
local result = globalMiddleware(ctx)
|
|
646
|
-
if result == DropRequest then
|
|
647
|
-
self.middleware:notifyRequestDropped(message, "Global server middleware")
|
|
648
|
-
return { true, ctx.data }
|
|
649
|
-
end
|
|
650
|
-
end
|
|
651
|
-
for _, middleware in self.middleware:getServer(message) do
|
|
652
|
-
if not self:validateData(message, ctx.data, "Invalid data after server middleware") then
|
|
653
|
-
return { false, ctx.data }
|
|
654
|
-
end
|
|
655
|
-
local result = middleware(ctx)
|
|
656
|
-
if result == DropRequest then
|
|
657
|
-
self.middleware:notifyRequestDropped(message, "Server middleware")
|
|
658
|
-
return { true, ctx.data }
|
|
659
|
-
end
|
|
660
|
-
end
|
|
661
|
-
if not self:validateData(message, ctx.data) then
|
|
662
|
-
return { true, ctx.data }
|
|
663
|
-
end
|
|
664
|
-
return { false, ctx.data }
|
|
665
|
-
end
|
|
666
|
-
function MessageEmitter:validateData(message, data, requestDropReason)
|
|
667
|
-
if requestDropReason == nil then
|
|
668
|
-
requestDropReason = "Invalid data"
|
|
669
|
-
end
|
|
670
|
-
local _guards = self.guards
|
|
671
|
-
local _message = message
|
|
672
|
-
local guard = _guards[_message]
|
|
673
|
-
local guardPassed = guard(data)
|
|
674
|
-
if not guardPassed then
|
|
675
|
-
warn(guardFailed(message, data))
|
|
676
|
-
self.middleware:notifyRequestDropped(message, requestDropReason)
|
|
677
|
-
end
|
|
678
|
-
return guardPassed
|
|
679
|
-
end
|
|
680
|
-
function MessageEmitter:onRemoteFire(isServer, serializedPackets, player)
|
|
681
|
-
for _, packet in serializedPackets do
|
|
682
|
-
if buffer.len(packet.messageBuf) > 1 then
|
|
683
|
-
return warn("[@rbxts/tether]: Rejected packet because message buffer was larger than one byte")
|
|
684
|
-
end
|
|
685
|
-
local message = buffer.readu8(packet.messageBuf, 0)
|
|
686
|
-
self:executeEventCallbacks(isServer, message, packet, player)
|
|
687
|
-
self:executeFunctions(isServer, message, packet)
|
|
688
|
-
end
|
|
689
|
-
end
|
|
690
|
-
function MessageEmitter:executeFunctions(isServer, message, serializedPacket)
|
|
691
|
-
local functionsMap = if isServer then self.serverFunctions else self.clientFunctions
|
|
692
|
-
local _message = message
|
|
693
|
-
local functions = functionsMap[_message]
|
|
694
|
-
if functions == nil then
|
|
695
|
-
return nil
|
|
696
|
-
end
|
|
697
|
-
local packet = self:deserializeAndValidate(message, serializedPacket)
|
|
698
|
-
for callback in functions do
|
|
699
|
-
callback(packet)
|
|
700
|
-
end
|
|
701
|
-
end
|
|
702
|
-
function MessageEmitter:executeEventCallbacks(isServer, message, serializedPacket, player)
|
|
703
|
-
local callbacksMap = if isServer then self.serverCallbacks else self.clientCallbacks
|
|
704
|
-
local _message = message
|
|
705
|
-
local callbacks = callbacksMap[_message]
|
|
706
|
-
if callbacks == nil then
|
|
707
|
-
return nil
|
|
708
|
-
end
|
|
709
|
-
local packet = self:deserializeAndValidate(message, serializedPacket)
|
|
710
|
-
for callback in callbacks do
|
|
711
|
-
if isServer then
|
|
712
|
-
callback(player, packet)
|
|
713
|
-
else
|
|
714
|
-
callback(packet)
|
|
715
|
-
end
|
|
716
|
-
end
|
|
717
|
-
end
|
|
718
|
-
function MessageEmitter:deserializeAndValidate(message, serializedPacket)
|
|
719
|
-
local serializer = self:getSerializer(message)
|
|
720
|
-
local _packet = serializer
|
|
721
|
-
if _packet ~= nil then
|
|
722
|
-
_packet = _packet.deserialize(serializedPacket)
|
|
723
|
-
end
|
|
724
|
-
local packet = _packet
|
|
725
|
-
self:validateData(message, packet)
|
|
726
|
-
return packet
|
|
727
|
-
end
|
|
728
|
-
function MessageEmitter:once(message, callback, callbacksMap)
|
|
729
|
-
local destructor
|
|
730
|
-
destructor = self:on(message, function(player, data)
|
|
731
|
-
destructor()
|
|
732
|
-
callback(player, data)
|
|
733
|
-
end, callbacksMap)
|
|
734
|
-
return destructor
|
|
735
|
-
end
|
|
736
|
-
function MessageEmitter:on(message, callback, callbacksMap)
|
|
737
|
-
local _callbacksMap = callbacksMap
|
|
738
|
-
local _message = message
|
|
739
|
-
if not (_callbacksMap[_message] ~= nil) then
|
|
740
|
-
local _callbacksMap_1 = callbacksMap
|
|
741
|
-
local _message_1 = message
|
|
742
|
-
_callbacksMap_1[_message_1] = {}
|
|
743
|
-
end
|
|
744
|
-
local _callbacksMap_1 = callbacksMap
|
|
745
|
-
local _message_1 = message
|
|
746
|
-
local callbacks = _callbacksMap_1[_message_1]
|
|
747
|
-
local _callback = callback
|
|
748
|
-
callbacks[_callback] = true
|
|
749
|
-
local _callbacksMap_2 = callbacksMap
|
|
750
|
-
local _message_2 = message
|
|
751
|
-
_callbacksMap_2[_message_2] = callbacks
|
|
752
|
-
return function()
|
|
753
|
-
local _callback_1 = callback
|
|
754
|
-
-- ▼ Set.delete ▼
|
|
755
|
-
local _valueExisted = callbacks[_callback_1] ~= nil
|
|
756
|
-
callbacks[_callback_1] = nil
|
|
757
|
-
-- ▲ Set.delete ▲
|
|
758
|
-
return _valueExisted
|
|
759
|
-
end
|
|
760
|
-
end
|
|
761
|
-
function MessageEmitter:getPacket(message, data)
|
|
762
|
-
local serializer = self:getSerializer(message)
|
|
763
|
-
local messageBuf = buffer.create(1)
|
|
764
|
-
buffer.writeu8(messageBuf, 0, message)
|
|
765
|
-
if serializer == nil then
|
|
766
|
-
return {
|
|
767
|
-
messageBuf = messageBuf,
|
|
768
|
-
buf = buffer.create(0),
|
|
769
|
-
blobs = {},
|
|
770
|
-
}
|
|
771
|
-
end
|
|
772
|
-
local _object = {
|
|
773
|
-
messageBuf = messageBuf,
|
|
774
|
-
}
|
|
775
|
-
for _k, _v in serializer.serialize(data) do
|
|
776
|
-
_object[_k] = _v
|
|
777
|
-
end
|
|
778
|
-
return _object
|
|
779
|
-
end
|
|
780
|
-
function MessageEmitter:addSerializer(message, meta)
|
|
781
|
-
self.serializers[message] = self:createMessageSerializer(meta)
|
|
782
|
-
end
|
|
783
|
-
function MessageEmitter:createMessageSerializer(meta)
|
|
784
|
-
return createSerializer(meta)
|
|
785
|
-
end
|
|
786
|
-
function MessageEmitter:getSerializer(message)
|
|
787
|
-
return self.serializers[message]
|
|
788
|
-
end
|
|
789
|
-
end
|
|
790
|
-
return {
|
|
791
|
-
MessageEmitter = MessageEmitter,
|
|
792
|
-
}
|