@axpecter/lync 2.2.0 β 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.
- package/README.md +95 -143
- package/package.json +1 -1
- package/src/Types.luau +22 -16
- package/src/api/Group.luau +40 -33
- package/src/api/Packet.luau +95 -72
- package/src/api/Query.luau +128 -79
- package/src/api/Scope.luau +26 -10
- package/src/api/Signal.luau +43 -52
- package/src/codec/Base.luau +21 -14
- package/src/codec/composite/Array.luau +56 -134
- package/src/codec/composite/Map.luau +103 -72
- package/src/codec/composite/Optional.luau +6 -2
- package/src/codec/composite/Shared.luau +160 -69
- package/src/codec/composite/Struct.luau +283 -42
- package/src/codec/composite/Tagged.luau +13 -16
- package/src/codec/composite/Tuple.luau +21 -15
- package/src/codec/datatype/Buffer.luau +6 -4
- package/src/codec/datatype/CFrame.luau +56 -44
- package/src/codec/datatype/Color.luau +10 -10
- package/src/codec/datatype/Instance.luau +15 -12
- package/src/codec/datatype/IntVector.luau +2 -2
- package/src/codec/datatype/NumberRange.luau +15 -8
- package/src/codec/datatype/Ray.luau +13 -14
- package/src/codec/datatype/Rect.luau +12 -12
- package/src/codec/datatype/Region.luau +13 -14
- package/src/codec/datatype/Sequence.luau +87 -65
- package/src/codec/datatype/String.luau +17 -10
- package/src/codec/datatype/UDim.luau +10 -8
- package/src/codec/datatype/Vector.luau +20 -59
- package/src/codec/meta/Auto.luau +94 -126
- package/src/codec/meta/Bitfield.luau +12 -14
- package/src/codec/meta/Custom.luau +3 -1
- package/src/codec/meta/Enum.luau +9 -9
- package/src/codec/meta/Float.luau +6 -28
- package/src/codec/meta/Nothing.luau +1 -1
- package/src/codec/meta/Unknown.luau +10 -7
- package/src/codec/primitive/Bool.luau +6 -4
- package/src/codec/primitive/Float16.luau +5 -2
- package/src/codec/primitive/Int.luau +5 -6
- package/src/codec/primitive/Number.luau +6 -4
- package/src/codec/primitive/Signed.luau +2 -2
- package/src/codec/primitive/Varint.luau +69 -38
- package/src/index.d.ts +161 -53
- package/src/init.luau +123 -102
- package/src/internal/Baseline.luau +9 -1
- package/src/internal/Channel.luau +153 -154
- package/src/internal/Middleware.luau +22 -6
- package/src/internal/Pool.luau +12 -4
- package/src/internal/Registry.luau +25 -16
- package/src/internal/Transport.luau +1 -1
- package/src/transport/Bridge.luau +47 -33
- package/src/transport/Client.luau +25 -21
- package/src/transport/Gate.luau +227 -172
- package/src/transport/Reader.luau +162 -105
- package/src/transport/Server.luau +46 -57
- package/src/util/Array.luau +18 -0
- package/src/util/Buffer.luau +92 -0
- package/src/util/Constants.luau +30 -0
- package/src/util/Log.luau +68 -0
- package/src/util/Player.luau +14 -0
- package/src/util/Quantize.luau +60 -0
- package/src/internal/Util.luau +0 -26
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
--!strict
|
|
2
2
|
--!native
|
|
3
|
-
-- Signed integer
|
|
4
|
-
-- emulate via writeu* + two's complement (writei* is not FASTCALL).
|
|
3
|
+
-- Signed integer writers via writeu* + two's complement (writei* is not FASTCALL).
|
|
5
4
|
|
|
6
5
|
-- Private ----------------------------------------------------------------
|
|
7
6
|
|
|
@@ -25,6 +24,7 @@ function Signed.writeI32(b: buffer, off: number, value: number): ()
|
|
|
25
24
|
writeu32(b, off, if value < 0 then value + 0x100000000 else value)
|
|
26
25
|
end
|
|
27
26
|
|
|
27
|
+
-- Reads stay on buffer.readi* (already FASTCALL).
|
|
28
28
|
Signed.readI8 = buffer.readi8
|
|
29
29
|
Signed.readI16 = buffer.readi16
|
|
30
30
|
Signed.readI32 = buffer.readi32
|
|
@@ -1,25 +1,38 @@
|
|
|
1
1
|
--!strict
|
|
2
2
|
--!native
|
|
3
|
-
-- Dense prefix varint
|
|
3
|
+
-- Dense prefix varint over [0, 2^32 - 1]. Single-branch decode.
|
|
4
4
|
|
|
5
5
|
local Base = require(script.Parent.Parent.Base)
|
|
6
|
+
local Constants = require(script.Parent.Parent.Parent.util.Constants)
|
|
7
|
+
local Log = require(script.Parent.Parent.Parent.util.Log)
|
|
6
8
|
local Types = require(script.Parent.Parent.Parent.Types)
|
|
7
9
|
|
|
8
10
|
-- Constants --------------------------------------------------------------
|
|
9
11
|
|
|
10
12
|
--[[
|
|
11
|
-
Wire layout (first byte
|
|
12
|
-
0x00..0xBF 1 byte value = b0
|
|
13
|
-
0xC0..0xDF 2 bytes value = (b0 & 0x1F)<<8 | b1 + 192
|
|
14
|
-
0xE0..0xEF 3 bytes value = (b0 & 0x0F)<<16 | u16 + 8384
|
|
15
|
-
0xF0..0xFF 5 bytes value = u32
|
|
13
|
+
Wire layout (first byte tag selects length):
|
|
14
|
+
0x00..0xBF 1 byte value = b0 [0..191]
|
|
15
|
+
0xC0..0xDF 2 bytes value = (b0 & 0x1F)<<8 | b1 + 192 [192..8383]
|
|
16
|
+
0xE0..0xEF 3 bytes value = (b0 & 0x0F)<<16 | u16 + 8384 [8384..1056959]
|
|
17
|
+
0xF0..0xFF 5 bytes value = u32 [..0xFFFFFFFF]
|
|
16
18
|
]]
|
|
17
19
|
local INLINE_MAX = 0xBF
|
|
20
|
+
local TWO_TAG = 0xC0
|
|
21
|
+
local TWO_END = 0xDF
|
|
22
|
+
local TWO_MASK = 0x1F
|
|
23
|
+
local THREE_TAG = 0xE0
|
|
24
|
+
local THREE_END = 0xEF
|
|
25
|
+
local THREE_MASK = 0x0F
|
|
26
|
+
local FIVE_TAG = 0xF0
|
|
18
27
|
local TWO_MAX = 8383
|
|
19
28
|
local THREE_MAX = 1056959
|
|
20
29
|
local TWO_BIAS = 192
|
|
21
30
|
local THREE_BIAS = 8384
|
|
22
31
|
|
|
32
|
+
local U8_MAX = Constants.U8_MAX
|
|
33
|
+
local U16_MAX = Constants.U16_MAX
|
|
34
|
+
local U32_MAX = Constants.U32_MAX
|
|
35
|
+
|
|
23
36
|
-- Private ----------------------------------------------------------------
|
|
24
37
|
|
|
25
38
|
local alloc = Base.alloc
|
|
@@ -33,6 +46,12 @@ local readu8 = buffer.readu8
|
|
|
33
46
|
local readu16 = buffer.readu16
|
|
34
47
|
local readu32 = buffer.readu32
|
|
35
48
|
|
|
49
|
+
local function ensure(ch: Types.ChannelState, n: number): ()
|
|
50
|
+
if ch.cursor + n > ch.size then
|
|
51
|
+
alloc(ch, n)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
36
55
|
-- Public -----------------------------------------------------------------
|
|
37
56
|
|
|
38
57
|
local Varint = {}
|
|
@@ -40,84 +59,96 @@ local Varint = {}
|
|
|
40
59
|
Varint.INLINE_MAX = INLINE_MAX
|
|
41
60
|
|
|
42
61
|
function Varint.write(ch: Types.ChannelState, value: number): ()
|
|
43
|
-
if value < 0 or value >
|
|
44
|
-
error(`
|
|
62
|
+
if value < 0 or value > U32_MAX or value % 1 ~= 0 then
|
|
63
|
+
Log.error(`value must be an integer in [0, {U32_MAX}], got {value}`)
|
|
45
64
|
end
|
|
46
65
|
|
|
47
|
-
local cursor = ch.cursor
|
|
48
|
-
|
|
49
66
|
if value <= INLINE_MAX then
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
end
|
|
67
|
+
ensure(ch, 1)
|
|
68
|
+
local cursor = ch.cursor
|
|
53
69
|
writeu8(ch.buff, cursor, value)
|
|
54
70
|
ch.cursor = cursor + 1
|
|
55
71
|
return
|
|
56
72
|
end
|
|
57
73
|
|
|
58
74
|
if value <= TWO_MAX then
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
end
|
|
75
|
+
ensure(ch, 2)
|
|
76
|
+
local cursor = ch.cursor
|
|
62
77
|
local adjusted = value - TWO_BIAS
|
|
63
78
|
local b = ch.buff
|
|
64
|
-
writeu8(b, cursor, bor(
|
|
65
|
-
writeu8(b, cursor + 1, band(adjusted,
|
|
79
|
+
writeu8(b, cursor, bor(TWO_TAG, rshift(adjusted, 8)))
|
|
80
|
+
writeu8(b, cursor + 1, band(adjusted, U8_MAX))
|
|
66
81
|
ch.cursor = cursor + 2
|
|
67
82
|
return
|
|
68
83
|
end
|
|
69
84
|
|
|
70
85
|
if value <= THREE_MAX then
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
end
|
|
86
|
+
ensure(ch, 3)
|
|
87
|
+
local cursor = ch.cursor
|
|
74
88
|
local adjusted = value - THREE_BIAS
|
|
75
89
|
local b = ch.buff
|
|
76
|
-
writeu8(b, cursor, bor(
|
|
77
|
-
writeu16(b, cursor + 1, band(adjusted,
|
|
90
|
+
writeu8(b, cursor, bor(THREE_TAG, rshift(adjusted, 16)))
|
|
91
|
+
writeu16(b, cursor + 1, band(adjusted, U16_MAX))
|
|
78
92
|
ch.cursor = cursor + 3
|
|
79
93
|
return
|
|
80
94
|
end
|
|
81
95
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
end
|
|
96
|
+
ensure(ch, 5)
|
|
97
|
+
local cursor = ch.cursor
|
|
85
98
|
local b = ch.buff
|
|
86
|
-
writeu8(b, cursor,
|
|
99
|
+
writeu8(b, cursor, FIVE_TAG)
|
|
87
100
|
writeu32(b, cursor + 1, value)
|
|
88
101
|
ch.cursor = cursor + 5
|
|
89
102
|
end
|
|
90
103
|
|
|
104
|
+
--[[
|
|
105
|
+
Returns (value, bytesConsumed). On insufficient bytes returns (0, 0) so
|
|
106
|
+
the transport can abort the frame instead of letting the buffer access
|
|
107
|
+
raise β required for recovery from truncated/desynced incoming buffers.
|
|
108
|
+
]]
|
|
91
109
|
function Varint.read(src: buffer, pos: number): (number, number)
|
|
110
|
+
local available = buffer.len(src) - pos
|
|
111
|
+
if available < 1 then
|
|
112
|
+
return 0, 0
|
|
113
|
+
end
|
|
92
114
|
local b0 = readu8(src, pos)
|
|
93
115
|
if b0 <= INLINE_MAX then
|
|
94
116
|
return b0, 1
|
|
95
117
|
end
|
|
96
|
-
if b0 <=
|
|
97
|
-
|
|
118
|
+
if b0 <= TWO_END then
|
|
119
|
+
if available < 2 then
|
|
120
|
+
return 0, 0
|
|
121
|
+
end
|
|
122
|
+
return band(b0, TWO_MASK) * 256 + readu8(src, pos + 1) + TWO_BIAS, 2
|
|
98
123
|
end
|
|
99
|
-
if b0 <=
|
|
100
|
-
|
|
124
|
+
if b0 <= THREE_END then
|
|
125
|
+
if available < 3 then
|
|
126
|
+
return 0, 0
|
|
127
|
+
end
|
|
128
|
+
return band(b0, THREE_MASK) * 65536 + readu16(src, pos + 1) + THREE_BIAS, 3
|
|
129
|
+
end
|
|
130
|
+
if available < 5 then
|
|
131
|
+
return 0, 0
|
|
101
132
|
end
|
|
102
133
|
return readu32(src, pos + 1), 5
|
|
103
134
|
end
|
|
104
135
|
|
|
105
|
-
--
|
|
136
|
+
-- Caller-asserted: value is known to fit in INLINE_MAX.
|
|
106
137
|
function Varint.writeInline(ch: Types.ChannelState, value: number): ()
|
|
138
|
+
ensure(ch, 1)
|
|
107
139
|
local cursor = ch.cursor
|
|
108
|
-
if cursor + 1 > ch.size then
|
|
109
|
-
alloc(ch, 1)
|
|
110
|
-
end
|
|
111
140
|
writeu8(ch.buff, cursor, value)
|
|
112
141
|
ch.cursor = cursor + 1
|
|
113
142
|
end
|
|
114
143
|
|
|
115
144
|
--[[
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
Used by Buffer, String, and Auto's string branch.
|
|
145
|
+
Length-prefix decode that fast-paths the [0, INLINE_MAX] single-byte form
|
|
146
|
+
before falling through to full varint. Used by Buffer, String, and Auto.
|
|
119
147
|
]]
|
|
120
148
|
function Varint.readLengthPrefix(src: buffer, pos: number): (number, number)
|
|
149
|
+
if buffer.len(src) - pos < 1 then
|
|
150
|
+
return 0, 0
|
|
151
|
+
end
|
|
121
152
|
local b0 = readu8(src, pos)
|
|
122
153
|
if b0 <= INLINE_MAX then
|
|
123
154
|
return b0, 1
|
package/src/index.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
/// <reference types="@rbxts/types" />
|
|
2
2
|
|
|
3
3
|
declare namespace Lync {
|
|
4
|
-
// ββ Core
|
|
4
|
+
// ββ Core types ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Opaque codec brand. The `_nominal_codec` field never exists at
|
|
8
|
+
* runtime; it ties the generic parameter to a unique nominal type so
|
|
9
|
+
* `Codec<number>` and `Codec<string>` can't be assigned to each other.
|
|
10
|
+
*/
|
|
6
11
|
interface Codec<T> {
|
|
7
12
|
/** @hidden */ readonly _nominal_codec: T;
|
|
8
13
|
}
|
|
@@ -25,17 +30,26 @@ declare namespace Lync {
|
|
|
25
30
|
bytesReceived: number;
|
|
26
31
|
}
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
type RateLimitConfig =
|
|
34
|
+
| { maxPerSecond: number; burst?: number }
|
|
35
|
+
| { cooldown: number };
|
|
36
|
+
|
|
37
|
+
// ββ Packet ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
29
38
|
|
|
30
39
|
interface PacketOptions<T> {
|
|
31
40
|
unreliable?: boolean;
|
|
32
|
-
rateLimit?:
|
|
41
|
+
rateLimit?: RateLimitConfig;
|
|
33
42
|
validate?: (data: T, player: Player) => LuaTuple<[boolean, string?]>;
|
|
34
43
|
maxPayloadBytes?: number;
|
|
35
44
|
timestamp?: "frame" | "offset" | "full";
|
|
36
45
|
}
|
|
37
46
|
|
|
38
47
|
interface Packet<T> {
|
|
48
|
+
/**
|
|
49
|
+
* Server: target is required (single Player, array, Group, or sentinel).
|
|
50
|
+
* Client: target is omitted; the second arg is ignored at runtime.
|
|
51
|
+
* The signature unions both forms.
|
|
52
|
+
*/
|
|
39
53
|
send(this: Packet<T>, data: T, target?: Target): void;
|
|
40
54
|
on(this: Packet<T>, fn: (data: T, sender?: Player, timestamp?: number) => void): Connection;
|
|
41
55
|
once(this: Packet<T>, fn: (data: T, sender?: Player, timestamp?: number) => void): Connection;
|
|
@@ -44,55 +58,80 @@ declare namespace Lync {
|
|
|
44
58
|
stats(this: Packet<T>): PacketStats;
|
|
45
59
|
}
|
|
46
60
|
|
|
47
|
-
// ββ Query
|
|
61
|
+
// ββ Query βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
48
62
|
|
|
49
63
|
interface QueryOptions<Req> {
|
|
50
64
|
timeout?: number;
|
|
51
|
-
rateLimit?:
|
|
65
|
+
rateLimit?: RateLimitConfig;
|
|
52
66
|
validate?: (data: Req, player: Player) => LuaTuple<[boolean, string?]>;
|
|
53
67
|
}
|
|
54
68
|
|
|
55
69
|
interface Query<Req, Resp> {
|
|
56
|
-
handle(
|
|
70
|
+
handle(
|
|
71
|
+
this: Query<Req, Resp>,
|
|
72
|
+
fn: (request: Req, player?: Player) => Resp | undefined,
|
|
73
|
+
): Connection;
|
|
74
|
+
|
|
75
|
+
/** Client: yields until reply or timeout; nil on timeout. */
|
|
57
76
|
request(this: Query<Req, Resp>, data: Req): Resp | undefined;
|
|
77
|
+
/** Server, single-Player target. */
|
|
58
78
|
request(this: Query<Req, Resp>, data: Req, target: Player): Resp | undefined;
|
|
79
|
+
/** Server, multi-target (Group, array, all, except). */
|
|
59
80
|
request(this: Query<Req, Resp>, data: Req, target: Target): Map<Player, Resp | undefined>;
|
|
81
|
+
|
|
60
82
|
name(this: Query<Req, Resp>): string;
|
|
61
83
|
stats(this: Query<Req, Resp>): PacketStats;
|
|
62
84
|
}
|
|
63
85
|
|
|
64
|
-
// ββ Group
|
|
86
|
+
// ββ Group βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
65
87
|
|
|
66
88
|
interface Group extends Iterable<Player> {
|
|
89
|
+
/** Returns true if membership changed (idempotent). */
|
|
67
90
|
add(this: Group, player: Player): boolean;
|
|
68
91
|
remove(this: Group, player: Player): boolean;
|
|
69
92
|
has(this: Group, player: Player): boolean;
|
|
70
93
|
count(this: Group): number;
|
|
94
|
+
/** Clear members and free the name. */
|
|
71
95
|
destroy(this: Group): void;
|
|
72
96
|
}
|
|
73
97
|
|
|
74
|
-
// ββ Scope
|
|
98
|
+
// ββ Scope βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
75
99
|
|
|
76
100
|
interface Scope {
|
|
77
|
-
on<T>(
|
|
78
|
-
|
|
101
|
+
on<T>(
|
|
102
|
+
this: Scope,
|
|
103
|
+
source: Packet<T>,
|
|
104
|
+
fn: (data: T, sender?: Player, timestamp?: number) => void,
|
|
105
|
+
): Connection;
|
|
106
|
+
once<T>(
|
|
107
|
+
this: Scope,
|
|
108
|
+
source: Packet<T>,
|
|
109
|
+
fn: (data: T, sender?: Player, timestamp?: number) => void,
|
|
110
|
+
): Connection;
|
|
79
111
|
add(this: Scope, connection: Connection | RBXScriptConnection): void;
|
|
80
112
|
destroy(this: Scope): void;
|
|
81
113
|
}
|
|
82
114
|
|
|
83
|
-
// ββ Targets
|
|
115
|
+
// ββ Targets βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
84
116
|
|
|
85
117
|
type Target = Player | Player[] | Group | AllTarget | ExceptTarget;
|
|
86
118
|
|
|
119
|
+
/** Branded sentinel returned by `Lync.all`. */
|
|
87
120
|
interface AllTarget {
|
|
88
|
-
/** @hidden */ readonly
|
|
121
|
+
/** @hidden */ readonly _lyncKind: "all";
|
|
89
122
|
}
|
|
90
123
|
|
|
124
|
+
/** Branded sentinel returned by `Lync.except(...)`. */
|
|
91
125
|
interface ExceptTarget {
|
|
92
|
-
/** @hidden */ readonly
|
|
126
|
+
/** @hidden */ readonly _lyncKind: "except";
|
|
93
127
|
}
|
|
94
128
|
|
|
95
|
-
|
|
129
|
+
/** Branded sentinel exposed as `Lync.DROP`. Return from `onSend` to discard. */
|
|
130
|
+
interface DropSentinel {
|
|
131
|
+
/** @hidden */ readonly _lyncKind: "drop";
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ββ Codec inference βββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
96
135
|
|
|
97
136
|
type InferCodec<C> = C extends Codec<infer T> ? T : never;
|
|
98
137
|
|
|
@@ -100,25 +139,36 @@ declare namespace Lync {
|
|
|
100
139
|
[K in keyof S]: InferCodec<S[K]>;
|
|
101
140
|
};
|
|
102
141
|
|
|
103
|
-
// ββ Callable
|
|
142
|
+
// ββ Callable codec brands (function-call form for variants) βββββββββ
|
|
104
143
|
|
|
105
144
|
interface StringCodec extends Codec<string> {
|
|
145
|
+
/** Bounded variant; rejects on read if length exceeds maxLength. */
|
|
106
146
|
(maxLength: number): Codec<string>;
|
|
107
147
|
}
|
|
108
148
|
|
|
109
149
|
interface Vec2Codec extends Codec<Vector2> {
|
|
150
|
+
/** Quantized per-component variant. 2/4/8 bytes. */
|
|
110
151
|
(min: number, max: number, precision: number): Codec<Vector2>;
|
|
111
152
|
}
|
|
112
153
|
|
|
113
154
|
interface Vec3Codec extends Codec<Vector3> {
|
|
155
|
+
/** Quantized per-component variant. 3/6/12 bytes. */
|
|
114
156
|
(min: number, max: number, precision: number): Codec<Vector3>;
|
|
115
157
|
}
|
|
116
158
|
|
|
117
159
|
interface CFrameCodec extends Codec<CFrame> {
|
|
160
|
+
/** Smallest-three-quaternion variant. 16 bytes; β€ 0.16Β° rotation error. */
|
|
118
161
|
(): Codec<CFrame>;
|
|
119
162
|
}
|
|
120
163
|
|
|
121
|
-
// ββ
|
|
164
|
+
// ββ Bitfield schema βββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
165
|
+
|
|
166
|
+
type BitfieldField =
|
|
167
|
+
| { type: "bool" }
|
|
168
|
+
| { type: "uint"; width: number }
|
|
169
|
+
| { type: "int"; width: number };
|
|
170
|
+
|
|
171
|
+
// ββ Configure βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
122
172
|
|
|
123
173
|
interface ConfigureOptions {
|
|
124
174
|
channelMaxSize?: number;
|
|
@@ -129,23 +179,35 @@ declare namespace Lync {
|
|
|
129
179
|
stats?: boolean;
|
|
130
180
|
}
|
|
131
181
|
|
|
132
|
-
// ββ
|
|
182
|
+
// ββ Registration debug shape ββββββββββββββββββββββββββββββββββββββββ
|
|
133
183
|
|
|
134
|
-
interface
|
|
135
|
-
|
|
184
|
+
interface RegistrationInfo {
|
|
185
|
+
name: string;
|
|
186
|
+
id: number;
|
|
187
|
+
kind: number;
|
|
188
|
+
isUnreliable: boolean;
|
|
136
189
|
}
|
|
137
190
|
}
|
|
138
191
|
|
|
139
192
|
interface LyncModule {
|
|
140
|
-
// ββ Lifecycle
|
|
193
|
+
// ββ Lifecycle βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
141
194
|
|
|
142
195
|
configure(this: void, options: Lync.ConfigureOptions): void;
|
|
143
196
|
start(this: void): void;
|
|
144
197
|
isStarted(this: void): boolean;
|
|
198
|
+
flush(this: void): void;
|
|
199
|
+
flushRate(this: void, hz: number): void;
|
|
200
|
+
/** Restore module state to post-require defaults. For tests / hot reload. */
|
|
201
|
+
reset(this: void): void;
|
|
145
202
|
|
|
146
|
-
// ββ Definitions
|
|
203
|
+
// ββ Definitions βββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
147
204
|
|
|
148
|
-
packet<T>(
|
|
205
|
+
packet<T>(
|
|
206
|
+
this: void,
|
|
207
|
+
name: string,
|
|
208
|
+
codec: Lync.Codec<T>,
|
|
209
|
+
options?: Lync.PacketOptions<T>,
|
|
210
|
+
): Lync.Packet<T>;
|
|
149
211
|
|
|
150
212
|
query<Req, Resp>(
|
|
151
213
|
this: void,
|
|
@@ -158,46 +220,49 @@ interface LyncModule {
|
|
|
158
220
|
group(this: void, name: string): Lync.Group;
|
|
159
221
|
scope(this: void): Lync.Scope;
|
|
160
222
|
|
|
161
|
-
// ββ Targeting
|
|
223
|
+
// ββ Targeting βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
162
224
|
|
|
163
225
|
readonly all: Lync.AllTarget;
|
|
164
226
|
except(this: void, ...args: Array<Player | Lync.Group>): Lync.ExceptTarget;
|
|
165
227
|
readonly DROP: Lync.DropSentinel;
|
|
166
228
|
|
|
167
|
-
// ββ Middleware
|
|
168
|
-
|
|
169
|
-
onSend(this: void, fn: (data: unknown, name: string, player?: Player) => unknown): Lync.Connection;
|
|
170
|
-
onReceive(this: void, fn: (data: unknown, name: string, player?: Player) => unknown): Lync.Connection;
|
|
171
|
-
onDrop(this: void, fn: (player: Player, reason: string, name: string, data?: unknown) => void): Lync.Connection;
|
|
229
|
+
// ββ Middleware ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
172
230
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
231
|
+
onSend(
|
|
232
|
+
this: void,
|
|
233
|
+
fn: (data: unknown, name: string, player?: Player) => unknown,
|
|
234
|
+
): Lync.Connection;
|
|
235
|
+
onReceive(
|
|
236
|
+
this: void,
|
|
237
|
+
fn: (data: unknown, name: string, player?: Player) => unknown,
|
|
238
|
+
): Lync.Connection;
|
|
239
|
+
onDrop(
|
|
240
|
+
this: void,
|
|
241
|
+
fn: (player: Player, reason: string, name: string, data?: unknown) => void,
|
|
242
|
+
): Lync.Connection;
|
|
177
243
|
|
|
178
|
-
// ββ Stats
|
|
244
|
+
// ββ Stats βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
179
245
|
|
|
180
246
|
readonly stats: {
|
|
247
|
+
/** Server-only; returns undefined on client or before stats=true. */
|
|
181
248
|
player(this: void, player: Player): Lync.PlayerStats | undefined;
|
|
182
249
|
reset(this: void): void;
|
|
183
250
|
};
|
|
184
251
|
|
|
185
|
-
// ββ Debug
|
|
252
|
+
// ββ Debug βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
186
253
|
|
|
187
254
|
readonly debug: {
|
|
255
|
+
/** Reserved no-op for capture/replay tooling. */
|
|
188
256
|
capture(this: void, label?: string): void;
|
|
257
|
+
/** Reserved no-op for capture/replay tooling. */
|
|
189
258
|
stop(this: void): void;
|
|
259
|
+
/** Reserved no-op for capture/replay tooling. */
|
|
190
260
|
dump(this: void): void;
|
|
191
261
|
pending(this: void): number;
|
|
192
|
-
registrations(this: void): ReadonlyArray<
|
|
193
|
-
name: string;
|
|
194
|
-
id: number;
|
|
195
|
-
kind: number;
|
|
196
|
-
isUnreliable: boolean;
|
|
197
|
-
}>;
|
|
262
|
+
registrations(this: void): ReadonlyArray<Lync.RegistrationInfo>;
|
|
198
263
|
};
|
|
199
264
|
|
|
200
|
-
// ββ Number
|
|
265
|
+
// ββ Number codecs βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
201
266
|
|
|
202
267
|
int(this: void, min: number, max: number): Lync.Codec<number>;
|
|
203
268
|
float(this: void, min: number, max: number, precision: number): Lync.Codec<number>;
|
|
@@ -206,12 +271,12 @@ interface LyncModule {
|
|
|
206
271
|
readonly f64: Lync.Codec<number>;
|
|
207
272
|
readonly bool: Lync.Codec<boolean>;
|
|
208
273
|
|
|
209
|
-
// ββ String &
|
|
274
|
+
// ββ String & buffer βββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
210
275
|
|
|
211
276
|
readonly string: Lync.StringCodec;
|
|
212
277
|
readonly buff: Lync.Codec<buffer>;
|
|
213
278
|
|
|
214
|
-
// ββ Vectors &
|
|
279
|
+
// ββ Vectors & spatial βββββββββββββββββββββββββββββββββββββββββββββββ
|
|
215
280
|
|
|
216
281
|
readonly vec2: Lync.Vec2Codec;
|
|
217
282
|
readonly vec3: Lync.Vec3Codec;
|
|
@@ -223,7 +288,7 @@ interface LyncModule {
|
|
|
223
288
|
readonly vec2int16: Lync.Codec<Vector2int16>;
|
|
224
289
|
readonly vec3int16: Lync.Codec<Vector3int16>;
|
|
225
290
|
|
|
226
|
-
// ββ Roblox
|
|
291
|
+
// ββ Roblox types ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
227
292
|
|
|
228
293
|
readonly color3: Lync.Codec<Color3>;
|
|
229
294
|
readonly inst: Lync.Codec<Instance>;
|
|
@@ -233,26 +298,65 @@ interface LyncModule {
|
|
|
233
298
|
readonly numberSequence: Lync.Codec<NumberSequence>;
|
|
234
299
|
readonly colorSequence: Lync.Codec<ColorSequence>;
|
|
235
300
|
|
|
236
|
-
// ββ Composites
|
|
301
|
+
// ββ Composites ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
302
|
+
|
|
303
|
+
struct<S extends Record<string, Lync.Codec<unknown>>>(
|
|
304
|
+
this: void,
|
|
305
|
+
schema: S,
|
|
306
|
+
): Lync.Codec<Lync.InferSchema<S>>;
|
|
307
|
+
|
|
308
|
+
/** Reliable transport only; rejected at definition time on `unreliable`. */
|
|
309
|
+
deltaStruct<S extends Record<string, Lync.Codec<unknown>>>(
|
|
310
|
+
this: void,
|
|
311
|
+
schema: S,
|
|
312
|
+
): Lync.Codec<Lync.InferSchema<S>>;
|
|
237
313
|
|
|
238
|
-
struct<S extends Record<string, Lync.Codec<unknown>>>(this: void, schema: S): Lync.Codec<Lync.InferSchema<S>>;
|
|
239
|
-
deltaStruct<S extends Record<string, Lync.Codec<unknown>>>(this: void, schema: S): Lync.Codec<Lync.InferSchema<S>>;
|
|
240
314
|
array<T>(this: void, element: Lync.Codec<T>, maxCount?: number): Lync.Codec<T[]>;
|
|
315
|
+
/** Reliable transport only. */
|
|
241
316
|
deltaArray<T>(this: void, element: Lync.Codec<T>, maxCount?: number): Lync.Codec<T[]>;
|
|
242
|
-
|
|
243
|
-
|
|
317
|
+
|
|
318
|
+
map<K, V>(
|
|
319
|
+
this: void,
|
|
320
|
+
keyCodec: Lync.Codec<K>,
|
|
321
|
+
valueCodec: Lync.Codec<V>,
|
|
322
|
+
maxCount?: number,
|
|
323
|
+
): Lync.Codec<Map<K, V>>;
|
|
324
|
+
/** Reliable transport only. */
|
|
325
|
+
deltaMap<K, V>(
|
|
326
|
+
this: void,
|
|
327
|
+
keyCodec: Lync.Codec<K>,
|
|
328
|
+
valueCodec: Lync.Codec<V>,
|
|
329
|
+
maxCount?: number,
|
|
330
|
+
): Lync.Codec<Map<K, V>>;
|
|
331
|
+
|
|
244
332
|
optional<T>(this: void, codec: Lync.Codec<T>): Lync.Codec<T | undefined>;
|
|
245
|
-
|
|
333
|
+
|
|
334
|
+
tuple<T extends Lync.Codec<unknown>[]>(
|
|
335
|
+
this: void,
|
|
336
|
+
...codecs: T
|
|
337
|
+
): Lync.Codec<{ [K in keyof T]: Lync.InferCodec<T[K]> }>;
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Discriminated union with a string tag field. Up to 256 variants;
|
|
341
|
+
* each variant is a struct codec keyed by name.
|
|
342
|
+
*/
|
|
246
343
|
tagged<Tag extends string, V extends Record<string, Lync.Codec<unknown>>>(
|
|
247
344
|
this: void,
|
|
248
345
|
tagField: Tag,
|
|
249
346
|
variants: V,
|
|
250
|
-
): Lync.Codec<
|
|
347
|
+
): Lync.Codec<
|
|
348
|
+
{ [K in keyof V & string]: { [F in Tag]: K } & Lync.InferCodec<V[K]> }[keyof V & string]
|
|
349
|
+
>;
|
|
251
350
|
|
|
252
|
-
// ββ Meta
|
|
351
|
+
// ββ Meta ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
253
352
|
|
|
254
353
|
enum<T extends string[]>(this: void, ...values: T): Lync.Codec<T[number]>;
|
|
255
|
-
|
|
354
|
+
|
|
355
|
+
bitfield(
|
|
356
|
+
this: void,
|
|
357
|
+
schema: Record<string, Lync.BitfieldField>,
|
|
358
|
+
): Lync.Codec<Record<string, boolean | number>>;
|
|
359
|
+
|
|
256
360
|
custom<T>(
|
|
257
361
|
this: void,
|
|
258
362
|
size: number,
|
|
@@ -260,8 +364,12 @@ interface LyncModule {
|
|
|
260
364
|
read: (b: buffer, offset: number) => T,
|
|
261
365
|
typeCheck?: string,
|
|
262
366
|
): Lync.Codec<T>;
|
|
367
|
+
|
|
368
|
+
/** 0-byte codec; reads `undefined`. Use for fire-and-forget signals. */
|
|
263
369
|
readonly nothing: Lync.Codec<undefined>;
|
|
370
|
+
/** Bypasses serialization through the channel sidecar. Pair with `validate`. */
|
|
264
371
|
readonly unknown: Lync.Codec<unknown>;
|
|
372
|
+
/** Self-describing; nil/bool/numbers/strings/buffers/Roblox datatypes. */
|
|
265
373
|
readonly auto: Lync.Codec<unknown>;
|
|
266
374
|
}
|
|
267
375
|
|