@axpecter/lync 1.5.1 → 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 CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  ```toml
15
15
  [dependencies]
16
- Lync = "axp3cter/lync@1.5.1"
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.1"` |
166
+ | `Lync.VERSION` | `"1.5.2"` |
167
167
 
168
168
  ## Packets
169
169
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axpecter/lync",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "description": "Buffer networking for Roblox. Delta compression, XOR framing, built-in security.",
5
5
  "main": "src/init.luau",
6
6
  "types": "src/index.d.ts",
@@ -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 ok, response = pcall(callback, request, player)
200
- if not ok then
201
- warn(`[Lync] Query handler error on "{respName}": {response}`)
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
- if ok and response ~= nil then
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 ok, response = pcall(callback, request)
215
- if not ok then
216
- warn(`[Lync] Query handler error on "{respName}": {response}`)
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
- if ok and response ~= nil then
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({
@@ -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/init.luau CHANGED
@@ -104,7 +104,7 @@ end
104
104
  -- Public --------------------------------------------------------------
105
105
 
106
106
  local Lync = {
107
- VERSION = "1.5.1",
107
+ VERSION = "1.5.2",
108
108
 
109
109
  -- Lifecycle
110
110
  start = start,
@@ -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