@axpecter/lync 1.5.0 → 1.5.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 +5 -5
- package/package.json +1 -1
- package/src/api/Packet.luau +26 -13
- package/src/api/Query.luau +32 -13
- package/src/api/Signal.luau +4 -0
- package/src/index.d.ts +2 -2
- package/src/init.luau +1 -1
- package/src/transport/Reader.luau +2 -2
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
```toml
|
|
15
15
|
[dependencies]
|
|
16
|
-
Lync = "axp3cter/lync@1.5.
|
|
16
|
+
Lync = "axp3cter/lync@1.5.2"
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
**npm (roblox-ts)**
|
|
@@ -85,12 +85,12 @@ local Players = game:GetService("Players")
|
|
|
85
85
|
|
|
86
86
|
local alive = Lync.createGroup("alive")
|
|
87
87
|
|
|
88
|
-
Lync.onSend(function(data, name)
|
|
88
|
+
Lync.onSend(function(data, name, player)
|
|
89
89
|
print("[out]", name)
|
|
90
90
|
return data
|
|
91
91
|
end)
|
|
92
92
|
|
|
93
|
-
Lync.onDrop(function(player, reason, name)
|
|
93
|
+
Lync.onDrop(function(player, reason, name, data)
|
|
94
94
|
warn(player.Name, "dropped", name, reason)
|
|
95
95
|
end)
|
|
96
96
|
|
|
@@ -125,7 +125,7 @@ Net.Hit:listen(function(data, player)
|
|
|
125
125
|
}, Lync.except(target))
|
|
126
126
|
end)
|
|
127
127
|
|
|
128
|
-
Net.Ping:listen(function()
|
|
128
|
+
Net.Ping:listen(function(request, player)
|
|
129
129
|
return os.clock()
|
|
130
130
|
end)
|
|
131
131
|
```
|
|
@@ -163,7 +163,7 @@ end
|
|
|
163
163
|
| | What it does |
|
|
164
164
|
|:---------|:------------|
|
|
165
165
|
| `Lync.start()` | Sets up transport. Server creates remotes, client connects. Call once after all definitions. |
|
|
166
|
-
| `Lync.VERSION` | `"1.5.
|
|
166
|
+
| `Lync.VERSION` | `"1.5.2"` |
|
|
167
167
|
|
|
168
168
|
## Packets
|
|
169
169
|
|
package/package.json
CHANGED
package/src/api/Packet.luau
CHANGED
|
@@ -41,31 +41,28 @@ type PacketFields = {
|
|
|
41
41
|
_signal: Signal.Signal,
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
--
|
|
45
|
-
local
|
|
44
|
+
-- Server-only metatable. Single send() dispatches on target type.
|
|
45
|
+
local ServerImpl = {}
|
|
46
|
+
ServerImpl.__index = ServerImpl
|
|
47
|
+
|
|
48
|
+
export type Packet = typeof(setmetatable({} :: PacketFields, ServerImpl))
|
|
46
49
|
|
|
47
|
-
function
|
|
50
|
+
function ServerImpl.listen(self: Packet, callback: (...any) -> ()): Connection
|
|
48
51
|
return self._signal:connect(callback)
|
|
49
52
|
end
|
|
50
53
|
|
|
51
|
-
function
|
|
54
|
+
function ServerImpl.once(self: Packet, callback: (...any) -> ()): Connection
|
|
52
55
|
return self._signal:once(callback)
|
|
53
56
|
end
|
|
54
57
|
|
|
55
|
-
function
|
|
58
|
+
function ServerImpl.wait(self: Packet): ...any
|
|
56
59
|
return self._signal:wait()
|
|
57
60
|
end
|
|
58
61
|
|
|
59
|
-
function
|
|
62
|
+
function ServerImpl.disconnectAll(self: Packet): ()
|
|
60
63
|
self._signal:disconnectAll()
|
|
61
64
|
end
|
|
62
65
|
|
|
63
|
-
-- Server-only metatable. Single send() dispatches on target type.
|
|
64
|
-
local ServerImpl = setmetatable({}, { __index = SharedImpl })
|
|
65
|
-
ServerImpl.__index = ServerImpl
|
|
66
|
-
|
|
67
|
-
export type Packet = typeof(setmetatable({} :: PacketFields, ServerImpl))
|
|
68
|
-
|
|
69
66
|
local function checkDeltaMode(self: Packet, mode: number): ()
|
|
70
67
|
if not self._isDelta then
|
|
71
68
|
return
|
|
@@ -127,9 +124,25 @@ end
|
|
|
127
124
|
table.freeze(ServerImpl)
|
|
128
125
|
|
|
129
126
|
-- Client-only metatable. Has send(), no target needed.
|
|
130
|
-
local ClientImpl =
|
|
127
|
+
local ClientImpl = {}
|
|
131
128
|
ClientImpl.__index = ClientImpl
|
|
132
129
|
|
|
130
|
+
function ClientImpl.listen(self: Packet, callback: (...any) -> ()): Connection
|
|
131
|
+
return self._signal:connect(callback)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
function ClientImpl.once(self: Packet, callback: (...any) -> ()): Connection
|
|
135
|
+
return self._signal:once(callback)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
function ClientImpl.wait(self: Packet): ...any
|
|
139
|
+
return self._signal:wait()
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
function ClientImpl.disconnectAll(self: Packet): ()
|
|
143
|
+
self._signal:disconnectAll()
|
|
144
|
+
end
|
|
145
|
+
|
|
133
146
|
function ClientImpl.send(self: Packet, data: any): ()
|
|
134
147
|
clientWrite(self._id, self._name, self._codec, data, self._isUnreliable)
|
|
135
148
|
end
|
package/src/api/Query.luau
CHANGED
|
@@ -28,6 +28,7 @@ type PendingQuery = {
|
|
|
28
28
|
thread: thread?,
|
|
29
29
|
callback: ((data: any) -> ())?,
|
|
30
30
|
timeout: thread?,
|
|
31
|
+
source: Player?,
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
local _pending = {} :: { [number]: PendingQuery }
|
|
@@ -60,12 +61,17 @@ local function releaseCorrelation(): ()
|
|
|
60
61
|
_activeCount -= 1
|
|
61
62
|
end
|
|
62
63
|
|
|
63
|
-
local function completeQuery(id: number, data: any): ()
|
|
64
|
+
local function completeQuery(id: number, data: any, source: Player?): ()
|
|
64
65
|
local entry = _pending[id]
|
|
65
66
|
if not entry then
|
|
66
67
|
return
|
|
67
68
|
end
|
|
68
69
|
|
|
70
|
+
-- Reject responses from wrong player (prevents correlation spoofing)
|
|
71
|
+
if source ~= nil and entry.source ~= nil and source ~= entry.source then
|
|
72
|
+
return
|
|
73
|
+
end
|
|
74
|
+
|
|
69
75
|
_pending[id] = nil
|
|
70
76
|
releaseCorrelation()
|
|
71
77
|
|
|
@@ -110,7 +116,7 @@ local function requestMulti(self: Query, players: { Player }, data: any): { [Pla
|
|
|
110
116
|
if count == 1 then
|
|
111
117
|
local correlation = allocCorrelation()
|
|
112
118
|
local thread = coroutine.running()
|
|
113
|
-
local entry: PendingQuery = { thread = thread, timeout = nil }
|
|
119
|
+
local entry: PendingQuery = { thread = thread, timeout = nil, source = players[1] }
|
|
114
120
|
_pending[correlation] = entry
|
|
115
121
|
|
|
116
122
|
Server.writeQuery(
|
|
@@ -154,6 +160,7 @@ local function requestMulti(self: Query, players: { Player }, data: any): { [Pla
|
|
|
154
160
|
end
|
|
155
161
|
end,
|
|
156
162
|
timeout = nil,
|
|
163
|
+
source = player,
|
|
157
164
|
}
|
|
158
165
|
|
|
159
166
|
_pending[correlation] = entry
|
|
@@ -196,12 +203,18 @@ function QueryImpl.listen(self: Query, callback: (...any) -> any): Connection
|
|
|
196
203
|
if IS_SERVER then
|
|
197
204
|
return self._reqReg.signal:connect(
|
|
198
205
|
function(request: any, player: Player, correlation: number): ()
|
|
199
|
-
local
|
|
200
|
-
if not
|
|
201
|
-
warn(`[Lync] Query handler error on "{respName}": {
|
|
206
|
+
local results = table.pack(pcall(callback, request, player))
|
|
207
|
+
if not results[1] then
|
|
208
|
+
warn(`[Lync] Query handler error on "{respName}": {results[2]}`)
|
|
209
|
+
Server.writeQueryNil(player, respId, respName, correlation)
|
|
210
|
+
return
|
|
202
211
|
end
|
|
203
212
|
|
|
204
|
-
|
|
213
|
+
local response = if results.n > 2
|
|
214
|
+
then table.move(results, 2, results.n, 1, table.create(results.n - 1))
|
|
215
|
+
else results[2]
|
|
216
|
+
|
|
217
|
+
if response ~= nil then
|
|
205
218
|
Server.writeQuery(player, respId, respName, correlation, respCodec, response)
|
|
206
219
|
else
|
|
207
220
|
Server.writeQueryNil(player, respId, respName, correlation)
|
|
@@ -211,12 +224,18 @@ function QueryImpl.listen(self: Query, callback: (...any) -> any): Connection
|
|
|
211
224
|
else
|
|
212
225
|
return self._reqReg.signal:connect(
|
|
213
226
|
function(request: any, _player: Player?, correlation: number): ()
|
|
214
|
-
local
|
|
215
|
-
if not
|
|
216
|
-
warn(`[Lync] Query handler error on "{respName}": {
|
|
227
|
+
local results = table.pack(pcall(callback, request))
|
|
228
|
+
if not results[1] then
|
|
229
|
+
warn(`[Lync] Query handler error on "{respName}": {results[2]}`)
|
|
230
|
+
Client.writeQueryNil(respId, respName, correlation)
|
|
231
|
+
return
|
|
217
232
|
end
|
|
218
233
|
|
|
219
|
-
|
|
234
|
+
local response = if results.n > 2
|
|
235
|
+
then table.move(results, 2, results.n, 1, table.create(results.n - 1))
|
|
236
|
+
else results[2]
|
|
237
|
+
|
|
238
|
+
if response ~= nil then
|
|
220
239
|
Client.writeQuery(respId, respName, correlation, respCodec, response)
|
|
221
240
|
else
|
|
222
241
|
Client.writeQueryNil(respId, respName, correlation)
|
|
@@ -251,7 +270,7 @@ function QueryImpl.requestFrom(self: Query, player: Player, data: any): any
|
|
|
251
270
|
|
|
252
271
|
local correlation = allocCorrelation()
|
|
253
272
|
local thread = coroutine.running()
|
|
254
|
-
local entry: PendingQuery = { thread = thread, timeout = nil }
|
|
273
|
+
local entry: PendingQuery = { thread = thread, timeout = nil, source = player }
|
|
255
274
|
_pending[correlation] = entry
|
|
256
275
|
|
|
257
276
|
Server.writeQuery(player, self._reqReg.id, self._name, correlation, self._reqReg.codec, data)
|
|
@@ -307,8 +326,8 @@ function QueryModule.define(name: string, config: QueryConfig<any, any>): Query
|
|
|
307
326
|
config.validate
|
|
308
327
|
)
|
|
309
328
|
|
|
310
|
-
respSignal:connect(function(resp: any, correlation: number): ()
|
|
311
|
-
completeQuery(correlation, resp)
|
|
329
|
+
respSignal:connect(function(resp: any, source: Player?, correlation: number): ()
|
|
330
|
+
completeQuery(correlation, resp, source)
|
|
312
331
|
end)
|
|
313
332
|
|
|
314
333
|
return setmetatable({
|
package/src/api/Signal.luau
CHANGED
|
@@ -91,6 +91,10 @@ SignalImpl.__index = SignalImpl
|
|
|
91
91
|
export type Signal = typeof(setmetatable({} :: SignalFields, SignalImpl))
|
|
92
92
|
|
|
93
93
|
local function addEntry(self: Signal, callback: (...any) -> (), isOnce: boolean): Connection
|
|
94
|
+
if type(callback) ~= "function" then
|
|
95
|
+
error("[Lync] Expected function, got " .. type(callback))
|
|
96
|
+
end
|
|
97
|
+
|
|
94
98
|
local count = self._count + 1
|
|
95
99
|
self._count = count
|
|
96
100
|
|
package/src/index.d.ts
CHANGED
|
@@ -186,11 +186,11 @@ export interface Namespace {
|
|
|
186
186
|
): Connection;
|
|
187
187
|
onSend(
|
|
188
188
|
this: Namespace,
|
|
189
|
-
handler: (data: unknown, name: string, player: Player | undefined) => unknown | undefined,
|
|
189
|
+
handler: (data: unknown, name: string, player: Player | undefined) => unknown | DropSentinel | undefined,
|
|
190
190
|
): () => void;
|
|
191
191
|
onReceive(
|
|
192
192
|
this: Namespace,
|
|
193
|
-
handler: (data: unknown, name: string, player: Player | undefined) => unknown | undefined,
|
|
193
|
+
handler: (data: unknown, name: string, player: Player | undefined) => unknown | DropSentinel | undefined,
|
|
194
194
|
): () => void;
|
|
195
195
|
disconnectAll(this: Namespace): void;
|
|
196
196
|
destroy(this: Namespace): void;
|
package/src/init.luau
CHANGED
|
@@ -141,7 +141,7 @@ function Reader.process(
|
|
|
141
141
|
if kind == KIND_REQUEST then
|
|
142
142
|
querySignal:fire(nil, player, correlationId)
|
|
143
143
|
else
|
|
144
|
-
querySignal:fire(nil, correlationId)
|
|
144
|
+
querySignal:fire(nil, player, correlationId)
|
|
145
145
|
end
|
|
146
146
|
continue
|
|
147
147
|
end
|
|
@@ -166,7 +166,7 @@ function Reader.process(
|
|
|
166
166
|
if kind == KIND_REQUEST then
|
|
167
167
|
querySignal:fire(final, player, correlationId)
|
|
168
168
|
else
|
|
169
|
-
querySignal:fire(final, correlationId)
|
|
169
|
+
querySignal:fire(final, player, correlationId)
|
|
170
170
|
end
|
|
171
171
|
end
|
|
172
172
|
end
|