@axpecter/lync 2.2.1 → 2.3.1

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.
Files changed (62) hide show
  1. package/README.md +95 -143
  2. package/package.json +1 -1
  3. package/src/Types.luau +22 -16
  4. package/src/api/Group.luau +40 -33
  5. package/src/api/Packet.luau +68 -54
  6. package/src/api/Query.luau +103 -65
  7. package/src/api/Scope.luau +26 -10
  8. package/src/api/Signal.luau +43 -52
  9. package/src/codec/Base.luau +21 -14
  10. package/src/codec/composite/Array.luau +56 -134
  11. package/src/codec/composite/Map.luau +103 -72
  12. package/src/codec/composite/Optional.luau +6 -2
  13. package/src/codec/composite/Shared.luau +160 -69
  14. package/src/codec/composite/Struct.luau +283 -42
  15. package/src/codec/composite/Tagged.luau +13 -16
  16. package/src/codec/composite/Tuple.luau +21 -15
  17. package/src/codec/datatype/Buffer.luau +6 -4
  18. package/src/codec/datatype/CFrame.luau +56 -44
  19. package/src/codec/datatype/Color.luau +10 -10
  20. package/src/codec/datatype/Instance.luau +15 -12
  21. package/src/codec/datatype/IntVector.luau +2 -2
  22. package/src/codec/datatype/NumberRange.luau +15 -8
  23. package/src/codec/datatype/Ray.luau +13 -14
  24. package/src/codec/datatype/Rect.luau +12 -12
  25. package/src/codec/datatype/Region.luau +13 -14
  26. package/src/codec/datatype/Sequence.luau +87 -65
  27. package/src/codec/datatype/String.luau +17 -10
  28. package/src/codec/datatype/UDim.luau +10 -8
  29. package/src/codec/datatype/Vector.luau +20 -59
  30. package/src/codec/meta/Auto.luau +94 -126
  31. package/src/codec/meta/Bitfield.luau +12 -14
  32. package/src/codec/meta/Custom.luau +3 -1
  33. package/src/codec/meta/Enum.luau +9 -9
  34. package/src/codec/meta/Float.luau +6 -28
  35. package/src/codec/meta/Nothing.luau +1 -1
  36. package/src/codec/meta/Unknown.luau +10 -7
  37. package/src/codec/primitive/Bool.luau +6 -4
  38. package/src/codec/primitive/Float16.luau +5 -2
  39. package/src/codec/primitive/Int.luau +5 -6
  40. package/src/codec/primitive/Number.luau +6 -4
  41. package/src/codec/primitive/Signed.luau +2 -2
  42. package/src/codec/primitive/Varint.luau +69 -38
  43. package/src/index.d.ts +161 -53
  44. package/src/init.luau +109 -103
  45. package/src/internal/Baseline.luau +9 -1
  46. package/src/internal/Channel.luau +153 -154
  47. package/src/internal/Middleware.luau +22 -6
  48. package/src/internal/Pool.luau +12 -4
  49. package/src/internal/Registry.luau +25 -16
  50. package/src/internal/Transport.luau +1 -1
  51. package/src/transport/Bridge.luau +47 -33
  52. package/src/transport/Client.luau +25 -21
  53. package/src/transport/Gate.luau +227 -172
  54. package/src/transport/Reader.luau +162 -105
  55. package/src/transport/Server.luau +46 -57
  56. package/src/util/Array.luau +18 -0
  57. package/src/util/Buffer.luau +92 -0
  58. package/src/util/Constants.luau +30 -0
  59. package/src/util/Log.luau +68 -0
  60. package/src/util/Player.luau +14 -0
  61. package/src/util/Quantize.luau +60 -0
  62. package/src/internal/Util.luau +0 -26
@@ -1,9 +1,11 @@
1
1
  --!strict
2
2
  --!optimize 2
3
- -- RemoteEvent / UnreliableRemoteEvent thin wrapper.
3
+ -- RemoteEvent / UnreliableRemoteEvent wrapper.
4
4
 
5
5
  local RunService = game:GetService("RunService")
6
6
 
7
+ local Log = require(script.Parent.Parent.util.Log)
8
+
7
9
  -- Constants --------------------------------------------------------------
8
10
 
9
11
  local RELIABLE_NAME = "LyncReliable"
@@ -17,20 +19,41 @@ local _isServer = RunService:IsServer()
17
19
 
18
20
  -- Private ----------------------------------------------------------------
19
21
 
22
+ --[[
23
+ Captured to a local first so Log.error's `never` return narrows the
24
+ optional. Reading the module global directly wouldn't narrow.
25
+ ]]
20
26
  local function ensureReliable(): RemoteEvent
21
- local re = _reliable
22
- if not re then
23
- error("[Lync] Bridge.reliable: not set up; call Lync.start() first")
27
+ local r = _reliable
28
+ if not r then
29
+ Log.error("not set up; call Lync.start() first")
24
30
  end
25
- return re
31
+ return r
26
32
  end
27
33
 
28
34
  local function ensureUnreliable(): UnreliableRemoteEvent
29
- local ure = _unreliable
30
- if not ure then
31
- error("[Lync] Bridge.unreliable: not set up; call Lync.start() first")
35
+ local u = _unreliable
36
+ if not u then
37
+ Log.error("not set up; call Lync.start() first")
38
+ end
39
+ return u
40
+ end
41
+
42
+ -- Drop the trailing arg when refs is empty: Roblox serializes empty tables as several wire bytes.
43
+ local function fireToServer(re: any, data: buffer, refs: { Instance }): ()
44
+ if #refs > 0 then
45
+ re:FireServer(data, refs)
46
+ else
47
+ re:FireServer(data)
48
+ end
49
+ end
50
+
51
+ local function fireToClient(re: any, player: Player, data: buffer, refs: { Instance }): ()
52
+ if #refs > 0 then
53
+ re:FireClient(player, data, refs)
54
+ else
55
+ re:FireClient(player, data)
32
56
  end
33
- return ure
34
57
  end
35
58
 
36
59
  -- Public -----------------------------------------------------------------
@@ -58,39 +81,30 @@ Bridge.reliable = ensureReliable
58
81
  Bridge.unreliable = ensureUnreliable
59
82
 
60
83
  function Bridge.fireServer(data: buffer, refs: { Instance }): ()
61
- local re = ensureReliable()
62
- if #refs > 0 then
63
- re:FireServer(data, refs)
64
- else
65
- re:FireServer(data)
66
- end
84
+ fireToServer(ensureReliable(), data, refs)
67
85
  end
68
86
 
69
87
  function Bridge.fireClient(player: Player, data: buffer, refs: { Instance }): ()
70
- local re = ensureReliable()
71
- if #refs > 0 then
72
- re:FireClient(player, data, refs)
73
- else
74
- re:FireClient(player, data)
75
- end
88
+ fireToClient(ensureReliable(), player, data, refs)
76
89
  end
77
90
 
78
91
  function Bridge.fireServerUnreliable(data: buffer, refs: { Instance }): ()
79
- local ure = ensureUnreliable()
80
- if #refs > 0 then
81
- ure:FireServer(data, refs)
82
- else
83
- ure:FireServer(data)
84
- end
92
+ fireToServer(ensureUnreliable(), data, refs)
85
93
  end
86
94
 
87
95
  function Bridge.fireClientUnreliable(player: Player, data: buffer, refs: { Instance }): ()
88
- local ure = ensureUnreliable()
89
- if #refs > 0 then
90
- ure:FireClient(player, data, refs)
91
- else
92
- ure:FireClient(player, data)
93
- end
96
+ fireToClient(ensureUnreliable(), player, data, refs)
97
+ end
98
+
99
+ -- Test injection point: harnesses substitute fake remotes.
100
+ function Bridge.attach(reliable: any, unreliable: any): ()
101
+ _reliable = reliable
102
+ _unreliable = unreliable
103
+ end
104
+
105
+ function Bridge.reset(): ()
106
+ _reliable = nil
107
+ _unreliable = nil
94
108
  end
95
109
 
96
110
  return table.freeze(Bridge)
@@ -1,6 +1,6 @@
1
1
  --!strict
2
2
  --!optimize 2
3
- -- Client-side transport: single channel pair, flush, with outbound XOR delta.
3
+ -- Client transport: single channel pair with outbound XOR delta.
4
4
 
5
5
  local ReplicatedStorage = game:GetService("ReplicatedStorage")
6
6
 
@@ -18,10 +18,14 @@ local CONTAINER_NAME = "LyncRemotes"
18
18
  local _reliable: Types.ChannelState = Channel.create()
19
19
  local _unreliable: Types.ChannelState = Channel.create()
20
20
  local _prevIncoming: buffer? = nil
21
- local _prevIncomingLen = 0
21
+ local _prevIncomingLen: number = 0
22
22
 
23
23
  -- Private ----------------------------------------------------------------
24
24
 
25
+ local xorApply = Channel.xorApply
26
+ local sealAndDump = Channel.sealAndDump
27
+ local resetCh = Channel.reset
28
+
25
29
  local function handleIncomingReliable(data: any, refs: any?): ()
26
30
  local incoming = Reader.decodeIncoming(data)
27
31
  if not incoming then
@@ -29,15 +33,19 @@ local function handleIncomingReliable(data: any, refs: any?): ()
29
33
  end
30
34
 
31
35
  local incomingLen = buffer.len(incoming)
32
- local decoded = if _prevIncoming
33
- then Channel.xorApply(incoming, incomingLen, _prevIncoming, _prevIncomingLen)
34
- else incoming
35
- _prevIncoming = decoded
36
- _prevIncomingLen = incomingLen
37
-
38
- local ok, err = pcall(Reader.process, decoded, incomingLen, refs, nil, false)
39
- if not ok then
40
- warn(`[Lync] Client.receive: {err}`)
36
+ local decoded = xorApply(incoming, incomingLen, _prevIncoming, _prevIncomingLen)
37
+
38
+ --[[
39
+ Mirror Server: only adopt `decoded` as the next baseline on success.
40
+ A failed parse means the wire is suspect; reusing it would poison
41
+ every subsequent packet.
42
+ ]]
43
+ if Reader.process(decoded, incomingLen, refs, nil, false) then
44
+ _prevIncoming = decoded
45
+ _prevIncomingLen = incomingLen
46
+ else
47
+ _prevIncoming = nil
48
+ _prevIncomingLen = 0
41
49
  end
42
50
  end
43
51
 
@@ -46,11 +54,7 @@ local function handleIncomingUnreliable(data: any, refs: any?): ()
46
54
  if not incoming then
47
55
  return
48
56
  end
49
-
50
- local ok, err = pcall(Reader.process, incoming, buffer.len(incoming), refs, nil, false)
51
- if not ok then
52
- warn(`[Lync] Client.receiveUnreliable: {err}`)
53
- end
57
+ Reader.process(incoming, buffer.len(incoming), refs, nil, false)
54
58
  end
55
59
 
56
60
  -- Public -----------------------------------------------------------------
@@ -67,18 +71,18 @@ function Client.flush(): ()
67
71
  end
68
72
 
69
73
  if _reliable.cursor > 0 then
70
- local snapshot, refs, byteLen = Channel.sealAndDump(_reliable)
71
- local xored = Channel.xorApply(snapshot, byteLen, _reliable.prevDump, _reliable.prevDumpLen)
74
+ local snapshot, refs, byteLen = sealAndDump(_reliable)
75
+ local xored = xorApply(snapshot, byteLen, _reliable.prevDump, _reliable.prevDumpLen)
72
76
  _reliable.prevDump = snapshot
73
77
  _reliable.prevDumpLen = byteLen
74
78
  Bridge.fireServer(xored, refs)
75
- Channel.reset(_reliable)
79
+ resetCh(_reliable)
76
80
  end
77
81
 
78
82
  if _unreliable.cursor > 0 then
79
- local snapshot, refs = Channel.sealAndDump(_unreliable)
83
+ local snapshot, refs = sealAndDump(_unreliable)
80
84
  Bridge.fireServerUnreliable(snapshot, refs)
81
- Channel.reset(_unreliable)
85
+ resetCh(_unreliable)
82
86
  end
83
87
  end
84
88