@axpecter/lync 2.1.2 → 2.2.0
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 +241 -349
- package/package.json +1 -1
- package/src/Types.luau +53 -13
- package/src/api/Group.luau +41 -51
- package/src/api/Packet.luau +145 -143
- package/src/api/Query.luau +204 -202
- package/src/api/Scope.luau +36 -38
- package/src/api/Signal.luau +68 -94
- package/src/codec/Base.luau +43 -23
- package/src/codec/composite/Array.luau +161 -152
- package/src/codec/composite/Map.luau +37 -53
- package/src/codec/composite/Optional.luau +15 -21
- package/src/codec/composite/Shared.luau +78 -41
- package/src/codec/composite/Struct.luau +64 -125
- package/src/codec/composite/Tagged.luau +15 -25
- package/src/codec/composite/Tuple.luau +15 -20
- package/src/codec/datatype/Buffer.luau +44 -51
- package/src/codec/datatype/CFrame.luau +72 -104
- package/src/codec/datatype/Color.luau +14 -10
- package/src/codec/datatype/Instance.luau +32 -42
- package/src/codec/datatype/IntVector.luau +24 -22
- package/src/codec/datatype/NumberRange.luau +21 -12
- package/src/codec/datatype/Ray.luau +13 -7
- package/src/codec/datatype/Rect.luau +13 -7
- package/src/codec/datatype/Region.luau +25 -22
- package/src/codec/datatype/Sequence.luau +144 -118
- package/src/codec/datatype/String.luau +29 -59
- package/src/codec/datatype/UDim.luau +29 -30
- package/src/codec/datatype/Vector.luau +89 -105
- package/src/codec/meta/Auto.luau +194 -246
- package/src/codec/meta/Bitfield.luau +37 -36
- package/src/codec/meta/Custom.luau +10 -10
- package/src/codec/meta/Enum.luau +8 -11
- package/src/codec/meta/Float.luau +16 -20
- package/src/codec/meta/Nothing.luau +2 -2
- package/src/codec/meta/Unknown.luau +22 -32
- package/src/codec/primitive/Bool.luau +9 -5
- package/src/codec/primitive/Float16.luau +13 -23
- package/src/codec/primitive/Int.luau +20 -28
- package/src/codec/primitive/Number.luau +6 -10
- package/src/codec/primitive/Signed.luau +32 -0
- package/src/codec/primitive/Varint.luau +59 -28
- package/src/index.d.ts +8 -2
- package/src/init.luau +118 -143
- package/src/internal/Baseline.luau +17 -18
- package/src/internal/Channel.luau +143 -212
- package/src/internal/Middleware.luau +37 -47
- package/src/internal/Pool.luau +10 -10
- package/src/internal/Registry.luau +38 -34
- package/src/internal/Transport.luau +28 -0
- package/src/internal/Util.luau +26 -0
- package/src/transport/Bridge.luau +32 -24
- package/src/transport/Client.luau +51 -53
- package/src/transport/Gate.luau +183 -113
- package/src/transport/Reader.luau +95 -66
- package/src/transport/Server.luau +130 -125
package/src/api/Packet.luau
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
--!strict
|
|
2
2
|
--!optimize 2
|
|
3
|
-
-- Packet definition
|
|
3
|
+
-- Packet definition: send, on, once, wait, stats.
|
|
4
4
|
|
|
5
5
|
local Players = game:GetService("Players")
|
|
6
6
|
local RunService = game:GetService("RunService")
|
|
@@ -9,31 +9,35 @@ local Baseline = require(script.Parent.Parent.internal.Baseline)
|
|
|
9
9
|
local Channel = require(script.Parent.Parent.internal.Channel)
|
|
10
10
|
local Middleware = require(script.Parent.Parent.internal.Middleware)
|
|
11
11
|
local Registry = require(script.Parent.Parent.internal.Registry)
|
|
12
|
+
local Transport = require(script.Parent.Parent.internal.Transport)
|
|
12
13
|
local Types = require(script.Parent.Parent.Types)
|
|
14
|
+
local Util = require(script.Parent.Parent.internal.Util)
|
|
13
15
|
|
|
14
|
-
-- Constants
|
|
16
|
+
-- Constants --------------------------------------------------------------
|
|
15
17
|
|
|
16
18
|
local IS_SERVER = RunService:IsServer()
|
|
17
19
|
|
|
18
|
-
-- Private
|
|
20
|
+
-- Private ----------------------------------------------------------------
|
|
19
21
|
|
|
20
|
-
local
|
|
22
|
+
local isPlayer = Util.isPlayer
|
|
23
|
+
|
|
24
|
+
local function resolveTimestampMode(ts: ("frame" | "offset" | "full")?): (number, number)
|
|
21
25
|
if ts == "frame" then
|
|
22
26
|
Channel.enableTimestamps()
|
|
23
27
|
return Channel.TS_FRAME, 2
|
|
24
|
-
|
|
28
|
+
end
|
|
29
|
+
if ts == "offset" then
|
|
25
30
|
Channel.enableTimestamps()
|
|
26
31
|
return Channel.TS_OFFSET, 3
|
|
27
|
-
|
|
32
|
+
end
|
|
33
|
+
if ts == "full" then
|
|
28
34
|
Channel.enableTimestamps()
|
|
29
35
|
return Channel.TS_FULL, 9
|
|
30
36
|
end
|
|
31
37
|
return Channel.TS_NONE, 1
|
|
32
38
|
end
|
|
33
39
|
|
|
34
|
-
-- Public
|
|
35
|
-
|
|
36
|
-
local Packet = {}
|
|
40
|
+
-- Public types -----------------------------------------------------------
|
|
37
41
|
|
|
38
42
|
export type PacketHandle = {
|
|
39
43
|
send: (self: PacketHandle, data: any, target: any?) -> (),
|
|
@@ -44,191 +48,189 @@ export type PacketHandle = {
|
|
|
44
48
|
stats: (self: PacketHandle) -> Types.PacketStats,
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
-- Public -----------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
local Packet = {}
|
|
54
|
+
|
|
47
55
|
function Packet.define(
|
|
48
56
|
name: string,
|
|
49
57
|
codec: Types.InternalCodec<any>,
|
|
50
58
|
options: Types.PacketOptions?
|
|
51
59
|
): PacketHandle
|
|
52
|
-
local opts = options or {} :: Types.PacketOptions
|
|
60
|
+
local opts = options or ({} :: Types.PacketOptions)
|
|
53
61
|
local isUnreliable = opts.unreliable or false
|
|
54
62
|
|
|
55
|
-
if isUnreliable and
|
|
63
|
+
if isUnreliable and codec._isDelta then
|
|
56
64
|
error(`[Lync] Lync.packet: "{name}" cannot use delta codecs with unreliable transport`)
|
|
57
65
|
end
|
|
58
66
|
|
|
59
|
-
if
|
|
67
|
+
if codec._hasUnknown and not opts.validate then
|
|
60
68
|
warn(
|
|
61
|
-
`[Lync] Lync.packet: "{name}" uses unknown codec without validate
|
|
69
|
+
`[Lync] Lync.packet: "{name}" uses unknown codec without validate; data bypasses schema validation`
|
|
62
70
|
)
|
|
63
71
|
end
|
|
64
72
|
|
|
65
|
-
if
|
|
73
|
+
if codec._isDelta then
|
|
66
74
|
Baseline.markHasDelta()
|
|
67
75
|
end
|
|
68
76
|
|
|
69
77
|
local tsMode, headerSize = resolveTimestampMode(opts.timestamp)
|
|
70
|
-
local needsGate = IS_SERVER
|
|
71
|
-
|
|
72
78
|
local openFn = Channel.resolveOpenFn(tsMode, name)
|
|
73
79
|
|
|
74
|
-
local reg = Registry.register(
|
|
75
|
-
name,
|
|
76
|
-
Registry.KIND_PACKET,
|
|
77
|
-
codec,
|
|
78
|
-
isUnreliable,
|
|
79
|
-
nil,
|
|
80
|
-
needsGate,
|
|
81
|
-
headerSize,
|
|
82
|
-
tsMode,
|
|
83
|
-
openFn,
|
|
84
|
-
opts.rateLimit,
|
|
85
|
-
opts.validate,
|
|
86
|
-
opts.maxPayloadBytes
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
80
|
+
local reg = Registry.register({
|
|
81
|
+
name = name,
|
|
82
|
+
kind = Registry.KIND_PACKET,
|
|
83
|
+
codec = codec,
|
|
84
|
+
isUnreliable = isUnreliable,
|
|
85
|
+
partner = nil,
|
|
86
|
+
needsGate = IS_SERVER,
|
|
87
|
+
headerSize = headerSize,
|
|
88
|
+
timestampMode = tsMode,
|
|
89
|
+
openFn = openFn,
|
|
90
|
+
rateLimit = opts.rateLimit,
|
|
91
|
+
validate = opts.validate,
|
|
92
|
+
maxPayloadBytes = opts.maxPayloadBytes,
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
local function sendToPlayer(player: Player, data: any): ()
|
|
96
|
+
local ch = Transport.server().getChannel(player, isUnreliable)
|
|
97
|
+
Channel.writeBatch(ch, reg, data)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
local function bumpFires(): ()
|
|
101
|
+
if Channel.statsEnabled() then
|
|
102
|
+
reg.fires += 1
|
|
96
103
|
end
|
|
97
|
-
return _server
|
|
98
104
|
end
|
|
99
105
|
|
|
100
|
-
local function
|
|
101
|
-
if not
|
|
102
|
-
|
|
106
|
+
local function applySend(data: any, player: Player?): any?
|
|
107
|
+
if not Middleware.hasSendHooks() then
|
|
108
|
+
return data
|
|
103
109
|
end
|
|
104
|
-
|
|
110
|
+
|
|
111
|
+
local sendData = Middleware.runSend(data, name, player)
|
|
112
|
+
if typeof(sendData) == "table" and sendData._lyncDrop then
|
|
113
|
+
return nil
|
|
114
|
+
end
|
|
115
|
+
return sendData
|
|
105
116
|
end
|
|
106
117
|
|
|
107
|
-
local
|
|
118
|
+
local function sendFromServer(data: any, target: any): ()
|
|
119
|
+
if target == nil then
|
|
120
|
+
error(`[Lync] Packet.send: "{name}" server send requires a target`)
|
|
121
|
+
end
|
|
108
122
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if typeof(data) == "table" and (data :: any)._lyncDrop then
|
|
123
|
+
if isPlayer(target) then
|
|
124
|
+
local sendData = applySend(data, target :: Player)
|
|
125
|
+
if sendData == nil then
|
|
113
126
|
return
|
|
114
127
|
end
|
|
128
|
+
sendToPlayer(target :: Player, sendData)
|
|
129
|
+
bumpFires()
|
|
130
|
+
return
|
|
115
131
|
end
|
|
116
132
|
|
|
117
|
-
if
|
|
118
|
-
|
|
119
|
-
|
|
133
|
+
if typeof(target) == "table" then
|
|
134
|
+
local sendData = applySend(data, nil)
|
|
135
|
+
if sendData == nil then
|
|
136
|
+
return
|
|
120
137
|
end
|
|
121
138
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
local ch = Server.getChannel(target :: Player, isUnreliable)
|
|
126
|
-
Channel.writeBatch(ch, reg, data)
|
|
127
|
-
if Channel.statsEnabled() then
|
|
128
|
-
reg.fires += 1
|
|
139
|
+
if target._lyncAll then
|
|
140
|
+
for _, player in Players:GetPlayers() do
|
|
141
|
+
sendToPlayer(player, sendData)
|
|
129
142
|
end
|
|
143
|
+
bumpFires()
|
|
130
144
|
return
|
|
131
145
|
end
|
|
132
146
|
|
|
133
|
-
if
|
|
134
|
-
local
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
local ch = Server.getChannel(player, isUnreliable)
|
|
139
|
-
Channel.writeBatch(ch, reg, data)
|
|
140
|
-
end
|
|
141
|
-
if Channel.statsEnabled() then
|
|
142
|
-
reg.fires += 1
|
|
147
|
+
if target._lyncExcept then
|
|
148
|
+
local excluded = target._excluded :: { [Player]: boolean }
|
|
149
|
+
for _, player in Players:GetPlayers() do
|
|
150
|
+
if not excluded[player] then
|
|
151
|
+
sendToPlayer(player, sendData)
|
|
143
152
|
end
|
|
144
|
-
return
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
if tbl._lyncExcept then
|
|
148
|
-
local excluded = tbl._excluded :: { [Player]: boolean }
|
|
149
|
-
for _, player in Players:GetPlayers() do
|
|
150
|
-
if not excluded[player] then
|
|
151
|
-
local ch = Server.getChannel(player, isUnreliable)
|
|
152
|
-
Channel.writeBatch(ch, reg, data)
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
if Channel.statsEnabled() then
|
|
156
|
-
reg.fires += 1
|
|
157
|
-
end
|
|
158
|
-
return
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
if tbl._lyncGroup then
|
|
162
|
-
local members = tbl._members :: { [Player]: boolean }
|
|
163
|
-
for player in members do
|
|
164
|
-
local ch = Server.getChannel(player, isUnreliable)
|
|
165
|
-
Channel.writeBatch(ch, reg, data)
|
|
166
|
-
end
|
|
167
|
-
if Channel.statsEnabled() then
|
|
168
|
-
reg.fires += 1
|
|
169
|
-
end
|
|
170
|
-
return
|
|
171
153
|
end
|
|
154
|
+
bumpFires()
|
|
155
|
+
return
|
|
156
|
+
end
|
|
172
157
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
Channel.writeBatch(ch, reg, data)
|
|
177
|
-
end
|
|
178
|
-
end
|
|
179
|
-
if Channel.statsEnabled() then
|
|
180
|
-
reg.fires += 1
|
|
158
|
+
if target._lyncGroup then
|
|
159
|
+
for player in target._members :: { [Player]: boolean } do
|
|
160
|
+
sendToPlayer(player, sendData)
|
|
181
161
|
end
|
|
162
|
+
bumpFires()
|
|
182
163
|
return
|
|
183
164
|
end
|
|
184
165
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
)
|
|
190
|
-
else
|
|
191
|
-
local Client = getClient()
|
|
192
|
-
local ch = Client.getChannel(isUnreliable)
|
|
193
|
-
Channel.writeBatch(ch, reg, data)
|
|
194
|
-
if Channel.statsEnabled() then
|
|
195
|
-
reg.fires += 1
|
|
166
|
+
for _, player in target do
|
|
167
|
+
if isPlayer(player) then
|
|
168
|
+
sendToPlayer(player :: Player, sendData)
|
|
169
|
+
end
|
|
196
170
|
end
|
|
171
|
+
bumpFires()
|
|
172
|
+
return
|
|
197
173
|
end
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
function handle.on(_self: PacketHandle, fn: (...any) -> ()): Types.Connection
|
|
201
|
-
return reg.signal:connect(fn)
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
function handle.once(_self: PacketHandle, fn: (...any) -> ()): Types.Connection
|
|
205
|
-
local conn: Types.Connection
|
|
206
|
-
conn = reg.signal:connect(function(...: any)
|
|
207
|
-
conn:disconnect()
|
|
208
|
-
fn(...)
|
|
209
|
-
end)
|
|
210
|
-
return conn
|
|
211
|
-
end
|
|
212
174
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return reg.name
|
|
175
|
+
error(
|
|
176
|
+
`[Lync] Packet.send: "{name}" expected Player, table, Group, or Lync.all as target, got {typeof(
|
|
177
|
+
target
|
|
178
|
+
)}`
|
|
179
|
+
)
|
|
219
180
|
end
|
|
220
181
|
|
|
221
|
-
function
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
182
|
+
local function sendFromClient(data: any): ()
|
|
183
|
+
local sendData = applySend(data, nil)
|
|
184
|
+
if sendData == nil then
|
|
185
|
+
return
|
|
186
|
+
end
|
|
187
|
+
local ch = Transport.client().getChannel(isUnreliable)
|
|
188
|
+
Channel.writeBatch(ch, reg, sendData)
|
|
189
|
+
bumpFires()
|
|
229
190
|
end
|
|
230
191
|
|
|
231
|
-
|
|
192
|
+
local handle = {
|
|
193
|
+
send = function(_self: PacketHandle, data: any, target: any?): ()
|
|
194
|
+
if IS_SERVER then
|
|
195
|
+
sendFromServer(data, target)
|
|
196
|
+
else
|
|
197
|
+
sendFromClient(data)
|
|
198
|
+
end
|
|
199
|
+
end,
|
|
200
|
+
|
|
201
|
+
on = function(_self: PacketHandle, fn: (...any) -> ()): Types.Connection
|
|
202
|
+
return reg.signal:connect(fn)
|
|
203
|
+
end,
|
|
204
|
+
|
|
205
|
+
once = function(_self: PacketHandle, fn: (...any) -> ()): Types.Connection
|
|
206
|
+
local conn: Types.Connection
|
|
207
|
+
conn = reg.signal:connect(function(...: any)
|
|
208
|
+
conn:disconnect()
|
|
209
|
+
fn(...)
|
|
210
|
+
end)
|
|
211
|
+
return conn
|
|
212
|
+
end,
|
|
213
|
+
|
|
214
|
+
wait = function(_self: PacketHandle): ...any
|
|
215
|
+
return reg.signal:wait()
|
|
216
|
+
end,
|
|
217
|
+
|
|
218
|
+
name = function(_self: PacketHandle): string
|
|
219
|
+
return reg.name
|
|
220
|
+
end,
|
|
221
|
+
|
|
222
|
+
stats = function(_self: PacketHandle): Types.PacketStats
|
|
223
|
+
return {
|
|
224
|
+
bytesSent = reg.bytesSent,
|
|
225
|
+
bytesReceived = reg.bytesReceived,
|
|
226
|
+
fires = reg.fires,
|
|
227
|
+
recvFires = reg.recvFires,
|
|
228
|
+
drops = reg.drops,
|
|
229
|
+
}
|
|
230
|
+
end,
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return table.freeze(handle) :: PacketHandle
|
|
232
234
|
end
|
|
233
235
|
|
|
234
236
|
return table.freeze(Packet)
|