@axpecter/lync 2.0.0 → 2.1.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 +475 -426
- package/package.json +1 -1
- package/src/Types.luau +63 -31
- package/src/api/Group.luau +101 -106
- package/src/api/Packet.luau +187 -186
- package/src/api/Query.luau +223 -284
- package/src/api/Scope.luau +46 -57
- package/src/api/Signal.luau +104 -137
- package/src/codec/Base.luau +69 -20
- package/src/codec/composite/Array.luau +179 -270
- package/src/codec/composite/Map.luau +97 -347
- package/src/codec/composite/Optional.luau +27 -24
- package/src/codec/composite/Shared.luau +96 -65
- package/src/codec/composite/Struct.luau +200 -360
- package/src/codec/composite/Tagged.luau +62 -187
- package/src/codec/composite/Tuple.luau +79 -103
- package/src/codec/datatype/Buffer.luau +49 -21
- package/src/codec/datatype/CFrame.luau +207 -30
- package/src/codec/datatype/Color.luau +21 -11
- package/src/codec/datatype/Instance.luau +28 -21
- package/src/codec/datatype/IntVector.luau +33 -21
- package/src/codec/datatype/NumberRange.luau +19 -10
- package/src/codec/datatype/Ray.luau +26 -22
- package/src/codec/datatype/Rect.luau +20 -16
- package/src/codec/datatype/Region.luau +51 -45
- package/src/codec/datatype/Sequence.luau +64 -56
- package/src/codec/datatype/String.luau +89 -56
- package/src/codec/datatype/UDim.luau +40 -22
- package/src/codec/datatype/Vector.luau +181 -17
- package/src/codec/meta/Auto.luau +295 -253
- package/src/codec/meta/Bitfield.luau +104 -148
- package/src/codec/meta/Custom.luau +8 -4
- package/src/codec/meta/Enum.luau +29 -57
- package/src/codec/meta/Float.luau +64 -0
- package/src/codec/meta/Nothing.luau +9 -5
- package/src/codec/meta/Unknown.luau +44 -36
- package/src/codec/primitive/Bool.luau +16 -26
- package/src/codec/primitive/Float16.luau +58 -64
- package/src/codec/primitive/Int.luau +68 -0
- package/src/codec/primitive/Number.luau +21 -43
- package/src/codec/primitive/Varint.luau +67 -46
- package/src/index.d.ts +249 -335
- package/src/init.luau +319 -207
- package/src/internal/Baseline.luau +29 -24
- package/src/internal/Channel.luau +333 -278
- package/src/internal/Middleware.luau +60 -85
- package/src/internal/Pool.luau +19 -30
- package/src/internal/Registry.luau +56 -113
- package/src/transport/Bridge.luau +64 -43
- package/src/transport/Client.luau +59 -170
- package/src/transport/Gate.luau +282 -142
- package/src/transport/Reader.luau +148 -140
- package/src/transport/Server.luau +138 -488
- package/src/api/Namespace.luau +0 -256
- package/src/codec/meta/Quantized.luau +0 -174
|
@@ -1,54 +1,60 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
3
|
-
-- Region3(
|
|
2
|
+
--!optimize 2
|
|
3
|
+
-- Region3 (24 bytes) and Region3int16 (12 bytes) codecs.
|
|
4
4
|
|
|
5
5
|
local Base = require(script.Parent.Parent.Base)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
local pos = cf.Position
|
|
12
|
-
local minV = pos - halfSize
|
|
13
|
-
local maxV = pos + halfSize
|
|
14
|
-
buffer.writef32(b, o, minV.X)
|
|
15
|
-
buffer.writef32(b, o + 4, minV.Y)
|
|
16
|
-
buffer.writef32(b, o + 8, minV.Z)
|
|
17
|
-
buffer.writef32(b, o + 12, maxV.X)
|
|
18
|
-
buffer.writef32(b, o + 16, maxV.Y)
|
|
19
|
-
buffer.writef32(b, o + 20, maxV.Z)
|
|
7
|
+
-- Private -------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
local function writeI16(b: buffer, off: number, v: number): ()
|
|
10
|
+
buffer.writeu16(b, off, if v < 0 then v + 0x10000 else v)
|
|
20
11
|
end
|
|
21
12
|
|
|
22
|
-
local function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Vector3.new(buffer.readf32(b, o + 12), buffer.readf32(b, o + 16), buffer.readf32(b, o + 20))
|
|
26
|
-
)
|
|
13
|
+
local function readI16(b: buffer, off: number): number
|
|
14
|
+
local raw = buffer.readu16(b, off)
|
|
15
|
+
return if raw >= 0x8000 then raw - 0x10000 else raw
|
|
27
16
|
end
|
|
28
17
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
18
|
+
-- Public --------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
local RegionCodec = {}
|
|
21
|
+
|
|
22
|
+
RegionCodec.region3 = Base.define(24, function(b: buffer, off: number, value: Region3): ()
|
|
23
|
+
local pos = value.CFrame.Position
|
|
24
|
+
local half = value.Size * 0.5
|
|
25
|
+
local minV = pos - half
|
|
26
|
+
local maxV = pos + half
|
|
27
|
+
buffer.writef32(b, off, minV.X)
|
|
28
|
+
buffer.writef32(b, off + 4, minV.Y)
|
|
29
|
+
buffer.writef32(b, off + 8, minV.Z)
|
|
30
|
+
buffer.writef32(b, off + 12, maxV.X)
|
|
31
|
+
buffer.writef32(b, off + 16, maxV.Y)
|
|
32
|
+
buffer.writef32(b, off + 20, maxV.Z)
|
|
33
|
+
end, function(b: buffer, off: number): Region3
|
|
34
|
+
return Region3.new(
|
|
35
|
+
Vector3.new(buffer.readf32(b, off), buffer.readf32(b, off + 4), buffer.readf32(b, off + 8)),
|
|
36
|
+
Vector3.new(
|
|
37
|
+
buffer.readf32(b, off + 12),
|
|
38
|
+
buffer.readf32(b, off + 16),
|
|
39
|
+
buffer.readf32(b, off + 20)
|
|
52
40
|
)
|
|
53
|
-
|
|
54
|
-
})
|
|
41
|
+
)
|
|
42
|
+
end, { _typeCheck = "Region3" })
|
|
43
|
+
|
|
44
|
+
RegionCodec.region3int16 = Base.define(12, function(b: buffer, off: number, value: Region3int16): ()
|
|
45
|
+
local minV = value.Min
|
|
46
|
+
local maxV = value.Max
|
|
47
|
+
writeI16(b, off, minV.X)
|
|
48
|
+
writeI16(b, off + 2, minV.Y)
|
|
49
|
+
writeI16(b, off + 4, minV.Z)
|
|
50
|
+
writeI16(b, off + 6, maxV.X)
|
|
51
|
+
writeI16(b, off + 8, maxV.Y)
|
|
52
|
+
writeI16(b, off + 10, maxV.Z)
|
|
53
|
+
end, function(b: buffer, off: number): Region3int16
|
|
54
|
+
return Region3int16.new(
|
|
55
|
+
Vector3int16.new(readI16(b, off), readI16(b, off + 2), readI16(b, off + 4)),
|
|
56
|
+
Vector3int16.new(readI16(b, off + 6), readI16(b, off + 8), readI16(b, off + 10))
|
|
57
|
+
)
|
|
58
|
+
end, { _typeCheck = "Region3int16" })
|
|
59
|
+
|
|
60
|
+
return table.freeze(RegionCodec)
|
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
3
|
-
-- NumberSequence and ColorSequence codecs with varint
|
|
2
|
+
--!optimize 2
|
|
3
|
+
-- NumberSequence and ColorSequence codecs with varint count.
|
|
4
4
|
|
|
5
|
-
local
|
|
5
|
+
local Base = require(script.Parent.Parent.Base)
|
|
6
6
|
local Types = require(script.Parent.Parent.Parent.Types)
|
|
7
7
|
local Varint = require(script.Parent.Parent.primitive.Varint)
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
local alloc = Channel.alloc
|
|
12
|
-
|
|
13
|
-
-- Constants -----------------------------------------------------------
|
|
14
|
-
|
|
15
|
-
local NS_STRIDE = 12
|
|
16
|
-
local CS_STRIDE = 7
|
|
9
|
+
-- Private -------------------------------------------------------------
|
|
17
10
|
|
|
11
|
+
local alloc = Base.alloc
|
|
18
12
|
local round = math.round
|
|
19
13
|
local clamp = math.clamp
|
|
20
14
|
|
|
21
15
|
-- Public --------------------------------------------------------------
|
|
22
16
|
|
|
23
|
-
local
|
|
17
|
+
local SequenceCodec = {}
|
|
24
18
|
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
SequenceCodec.numberSequence = table.freeze({
|
|
20
|
+
_typeCheck = "NumberSequence",
|
|
21
|
+
|
|
22
|
+
write = function(ch: Types.ChannelState, value: NumberSequence): ()
|
|
27
23
|
local keypoints = value.Keypoints
|
|
28
24
|
local count = #keypoints
|
|
29
25
|
Varint.write(ch, count)
|
|
@@ -32,47 +28,54 @@ Sequence.numberSequence = table.freeze({
|
|
|
32
28
|
return
|
|
33
29
|
end
|
|
34
30
|
|
|
35
|
-
local
|
|
36
|
-
local
|
|
37
|
-
if
|
|
38
|
-
alloc(ch,
|
|
31
|
+
local bytes = count * 12
|
|
32
|
+
local cursor = ch.cursor
|
|
33
|
+
if cursor + bytes > ch.size then
|
|
34
|
+
alloc(ch, bytes)
|
|
39
35
|
end
|
|
40
|
-
|
|
41
36
|
local b = ch.buff
|
|
37
|
+
|
|
42
38
|
for i = 1, count do
|
|
43
39
|
local kp = keypoints[i]
|
|
44
|
-
|
|
45
|
-
buffer.writef32(b,
|
|
46
|
-
buffer.writef32(b,
|
|
47
|
-
|
|
40
|
+
local off = cursor + (i - 1) * 12
|
|
41
|
+
buffer.writef32(b, off, kp.Time)
|
|
42
|
+
buffer.writef32(b, off + 4, kp.Value)
|
|
43
|
+
buffer.writef32(b, off + 8, kp.Envelope)
|
|
48
44
|
end
|
|
49
45
|
|
|
50
|
-
ch.cursor =
|
|
46
|
+
ch.cursor = cursor + bytes
|
|
51
47
|
end,
|
|
48
|
+
|
|
52
49
|
read = function(src: buffer, pos: number, _refs: { Instance }?): (NumberSequence, number)
|
|
53
50
|
local count, lenBytes = Varint.read(src, pos)
|
|
54
|
-
local absPos = pos + lenBytes
|
|
55
|
-
|
|
56
51
|
if count == 0 then
|
|
57
52
|
return NumberSequence.new(0), lenBytes
|
|
58
53
|
end
|
|
59
54
|
|
|
55
|
+
local bytes = count * 12
|
|
56
|
+
local dataStart = pos + lenBytes
|
|
57
|
+
if dataStart + bytes > buffer.len(src) then
|
|
58
|
+
error("[Lync] NumberSequence: data exceeds buffer")
|
|
59
|
+
end
|
|
60
|
+
|
|
60
61
|
local keypoints = table.create(count)
|
|
61
62
|
for i = 1, count do
|
|
63
|
+
local off = dataStart + (i - 1) * 12
|
|
62
64
|
keypoints[i] = NumberSequenceKeypoint.new(
|
|
63
|
-
buffer.readf32(src,
|
|
64
|
-
buffer.readf32(src,
|
|
65
|
-
buffer.readf32(src,
|
|
65
|
+
buffer.readf32(src, off),
|
|
66
|
+
buffer.readf32(src, off + 4),
|
|
67
|
+
buffer.readf32(src, off + 8)
|
|
66
68
|
)
|
|
67
|
-
absPos += NS_STRIDE
|
|
68
69
|
end
|
|
69
70
|
|
|
70
|
-
return NumberSequence.new(keypoints),
|
|
71
|
+
return NumberSequence.new(keypoints), lenBytes + bytes
|
|
71
72
|
end,
|
|
72
|
-
})
|
|
73
|
+
} :: any)
|
|
74
|
+
|
|
75
|
+
SequenceCodec.colorSequence = table.freeze({
|
|
76
|
+
_typeCheck = "ColorSequence",
|
|
73
77
|
|
|
74
|
-
|
|
75
|
-
write = function(ch: ChannelState, value: ColorSequence): ()
|
|
78
|
+
write = function(ch: Types.ChannelState, value: ColorSequence): ()
|
|
76
79
|
local keypoints = value.Keypoints
|
|
77
80
|
local count = #keypoints
|
|
78
81
|
Varint.write(ch, count)
|
|
@@ -81,48 +84,53 @@ Sequence.colorSequence = table.freeze({
|
|
|
81
84
|
return
|
|
82
85
|
end
|
|
83
86
|
|
|
84
|
-
local
|
|
85
|
-
local
|
|
86
|
-
if
|
|
87
|
-
alloc(ch,
|
|
87
|
+
local bytes = count * 7
|
|
88
|
+
local cursor = ch.cursor
|
|
89
|
+
if cursor + bytes > ch.size then
|
|
90
|
+
alloc(ch, bytes)
|
|
88
91
|
end
|
|
89
|
-
|
|
90
92
|
local b = ch.buff
|
|
93
|
+
|
|
91
94
|
for i = 1, count do
|
|
92
95
|
local kp = keypoints[i]
|
|
93
|
-
local
|
|
94
|
-
|
|
95
|
-
buffer.
|
|
96
|
-
buffer.writeu8(b,
|
|
97
|
-
buffer.writeu8(b,
|
|
98
|
-
c
|
|
96
|
+
local off = cursor + (i - 1) * 7
|
|
97
|
+
local c = kp.Value
|
|
98
|
+
buffer.writef32(b, off, kp.Time)
|
|
99
|
+
buffer.writeu8(b, off + 4, round(clamp(c.R, 0, 1) * 255))
|
|
100
|
+
buffer.writeu8(b, off + 5, round(clamp(c.G, 0, 1) * 255))
|
|
101
|
+
buffer.writeu8(b, off + 6, round(clamp(c.B, 0, 1) * 255))
|
|
99
102
|
end
|
|
100
103
|
|
|
101
|
-
ch.cursor =
|
|
104
|
+
ch.cursor = cursor + bytes
|
|
102
105
|
end,
|
|
106
|
+
|
|
103
107
|
read = function(src: buffer, pos: number, _refs: { Instance }?): (ColorSequence, number)
|
|
104
108
|
local count, lenBytes = Varint.read(src, pos)
|
|
105
|
-
local absPos = pos + lenBytes
|
|
106
|
-
|
|
107
109
|
if count == 0 then
|
|
108
110
|
return ColorSequence.new(Color3.new()), lenBytes
|
|
109
111
|
end
|
|
110
112
|
|
|
113
|
+
local bytes = count * 7
|
|
114
|
+
local dataStart = pos + lenBytes
|
|
115
|
+
if dataStart + bytes > buffer.len(src) then
|
|
116
|
+
error("[Lync] ColorSequence: data exceeds buffer")
|
|
117
|
+
end
|
|
118
|
+
|
|
111
119
|
local keypoints = table.create(count)
|
|
112
120
|
for i = 1, count do
|
|
121
|
+
local off = dataStart + (i - 1) * 7
|
|
113
122
|
keypoints[i] = ColorSequenceKeypoint.new(
|
|
114
|
-
buffer.readf32(src,
|
|
123
|
+
buffer.readf32(src, off),
|
|
115
124
|
Color3.fromRGB(
|
|
116
|
-
buffer.readu8(src,
|
|
117
|
-
buffer.readu8(src,
|
|
118
|
-
buffer.readu8(src,
|
|
125
|
+
buffer.readu8(src, off + 4),
|
|
126
|
+
buffer.readu8(src, off + 5),
|
|
127
|
+
buffer.readu8(src, off + 6)
|
|
119
128
|
)
|
|
120
129
|
)
|
|
121
|
-
absPos += CS_STRIDE
|
|
122
130
|
end
|
|
123
131
|
|
|
124
|
-
return ColorSequence.new(keypoints),
|
|
132
|
+
return ColorSequence.new(keypoints), lenBytes + bytes
|
|
125
133
|
end,
|
|
126
|
-
})
|
|
134
|
+
} :: any)
|
|
127
135
|
|
|
128
|
-
return table.freeze(
|
|
136
|
+
return table.freeze(SequenceCodec)
|
|
@@ -1,84 +1,117 @@
|
|
|
1
1
|
--!strict
|
|
2
2
|
--!native
|
|
3
|
-
-- Variable-length string codec with
|
|
3
|
+
-- Variable-length string codec with __call for bounded variant.
|
|
4
4
|
|
|
5
|
-
local
|
|
5
|
+
local Base = require(script.Parent.Parent.Base)
|
|
6
6
|
local Types = require(script.Parent.Parent.Parent.Types)
|
|
7
7
|
local Varint = require(script.Parent.Parent.primitive.Varint)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
-- Private -------------------------------------------------------------
|
|
10
10
|
|
|
11
|
-
local alloc =
|
|
11
|
+
local alloc = Base.alloc
|
|
12
|
+
local writeu8 = buffer.writeu8
|
|
13
|
+
local readu8 = buffer.readu8
|
|
14
|
+
local INLINE = Varint.INLINE_MAX
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
local
|
|
16
|
+
local function writeString(ch: Types.ChannelState, value: string): ()
|
|
17
|
+
local len = #value
|
|
18
|
+
local cursor = ch.cursor
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if len < 128 then
|
|
22
|
-
local total = 1 + len
|
|
23
|
-
local c = ch.cursor
|
|
24
|
-
if c + total > ch.size then
|
|
25
|
-
alloc(ch, total)
|
|
26
|
-
end
|
|
27
|
-
local b = ch.buff
|
|
28
|
-
buffer.writeu8(b, c, len)
|
|
29
|
-
if len > 0 then
|
|
30
|
-
buffer.writestring(b, c + 1, value)
|
|
31
|
-
end
|
|
32
|
-
ch.cursor = c + total
|
|
33
|
-
else
|
|
34
|
-
Varint.write(ch, len)
|
|
35
|
-
local c = ch.cursor
|
|
36
|
-
if c + len > ch.size then
|
|
37
|
-
alloc(ch, len)
|
|
38
|
-
end
|
|
39
|
-
buffer.writestring(ch.buff, c, value)
|
|
40
|
-
ch.cursor = c + len
|
|
20
|
+
if len <= INLINE then
|
|
21
|
+
-- Short strings (<= 191 bytes) use a single-byte prefix, avoiding Varint.write overhead
|
|
22
|
+
if cursor + 1 + len > ch.size then
|
|
23
|
+
alloc(ch, 1 + len)
|
|
41
24
|
end
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return "", lenBytes
|
|
25
|
+
local b = ch.buff
|
|
26
|
+
writeu8(b, cursor, len)
|
|
27
|
+
if len > 0 then
|
|
28
|
+
buffer.writestring(b, cursor + 1, value)
|
|
47
29
|
end
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
30
|
+
ch.cursor = cursor + 1 + len
|
|
31
|
+
else
|
|
32
|
+
-- Long strings need multi-byte length encoding
|
|
33
|
+
Varint.write(ch, len)
|
|
34
|
+
cursor = ch.cursor
|
|
35
|
+
if cursor + len > ch.size then
|
|
36
|
+
alloc(ch, len)
|
|
52
37
|
end
|
|
38
|
+
buffer.writestring(ch.buff, cursor, value)
|
|
39
|
+
ch.cursor = cursor + len
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
local function readString(src: buffer, pos: number, _refs: { Instance }?): (string, number)
|
|
44
|
+
local b0 = readu8(src, pos)
|
|
45
|
+
local len: number
|
|
46
|
+
local lenBytes: number
|
|
53
47
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
if b0 <= INLINE then
|
|
49
|
+
len = b0
|
|
50
|
+
lenBytes = 1
|
|
51
|
+
else
|
|
52
|
+
len, lenBytes = Varint.read(src, pos)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
if len == 0 then
|
|
56
|
+
return "", lenBytes
|
|
57
|
+
end
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
if
|
|
60
|
-
error(
|
|
59
|
+
local dataStart = pos + lenBytes
|
|
60
|
+
if dataStart + len > buffer.len(src) then
|
|
61
|
+
error("[Lync] String: length exceeds remaining buffer")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
return buffer.readstring(src, dataStart, len), lenBytes + len
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
-- Bounded variant shares the write function to avoid per-call closure allocation
|
|
68
|
+
local function boundedFactory(_self: any, maxLength: number): Types.InternalCodec<string>
|
|
69
|
+
if maxLength <= 0 then
|
|
70
|
+
error("[Lync] Lync.string: maxLength must be positive")
|
|
61
71
|
end
|
|
62
72
|
|
|
63
73
|
return table.freeze({
|
|
64
|
-
write =
|
|
65
|
-
|
|
66
|
-
|
|
74
|
+
write = writeString,
|
|
75
|
+
|
|
76
|
+
read = function(src: buffer, pos: number, refs: { Instance }?): (string, number)
|
|
77
|
+
local b0 = readu8(src, pos)
|
|
78
|
+
local len: number
|
|
79
|
+
local lenBytes: number
|
|
80
|
+
|
|
81
|
+
if b0 <= INLINE then
|
|
82
|
+
len = b0
|
|
83
|
+
lenBytes = 1
|
|
84
|
+
else
|
|
85
|
+
len, lenBytes = Varint.read(src, pos)
|
|
86
|
+
end
|
|
87
|
+
|
|
67
88
|
if len > maxLength then
|
|
68
|
-
error(`[Lync] String length {len} exceeds max {maxLength}`)
|
|
89
|
+
error(`[Lync] String: length {len} exceeds max {maxLength}`)
|
|
69
90
|
end
|
|
91
|
+
|
|
70
92
|
if len == 0 then
|
|
71
93
|
return "", lenBytes
|
|
72
94
|
end
|
|
73
95
|
|
|
74
|
-
local
|
|
75
|
-
if len >
|
|
76
|
-
error(
|
|
96
|
+
local dataStart = pos + lenBytes
|
|
97
|
+
if dataStart + len > buffer.len(src) then
|
|
98
|
+
error("[Lync] String: length exceeds remaining buffer")
|
|
77
99
|
end
|
|
78
100
|
|
|
79
|
-
return buffer.readstring(src,
|
|
101
|
+
return buffer.readstring(src, dataStart, len), lenBytes + len
|
|
80
102
|
end,
|
|
81
|
-
})
|
|
103
|
+
} :: any)
|
|
82
104
|
end
|
|
83
105
|
|
|
84
|
-
|
|
106
|
+
-- Public --------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
local StringCodec = setmetatable(
|
|
109
|
+
{
|
|
110
|
+
write = writeString,
|
|
111
|
+
read = readString,
|
|
112
|
+
_typeCheck = "string",
|
|
113
|
+
} :: any,
|
|
114
|
+
{ __call = boundedFactory }
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
return StringCodec
|
|
@@ -1,27 +1,45 @@
|
|
|
1
1
|
--!strict
|
|
2
|
-
--!
|
|
3
|
-
-- UDim(
|
|
2
|
+
--!optimize 2
|
|
3
|
+
-- UDim (8 bytes) and UDim2 (16 bytes) codecs.
|
|
4
4
|
|
|
5
5
|
local Base = require(script.Parent.Parent.Base)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
7
|
+
-- Public --------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
local UDimCodec = {}
|
|
10
|
+
|
|
11
|
+
UDimCodec.udim = Base.define(8, function(b: buffer, off: number, value: UDim): ()
|
|
12
|
+
buffer.writef32(b, off, value.Scale)
|
|
13
|
+
buffer.writeu32(
|
|
14
|
+
b,
|
|
15
|
+
off + 4,
|
|
16
|
+
if value.Offset < 0 then value.Offset + 0x100000000 else value.Offset
|
|
17
|
+
)
|
|
18
|
+
end, function(b: buffer, off: number): UDim
|
|
19
|
+
local rawOff = buffer.readu32(b, off + 4)
|
|
20
|
+
return UDim.new(
|
|
21
|
+
buffer.readf32(b, off),
|
|
22
|
+
if rawOff >= 0x80000000 then rawOff - 0x100000000 else rawOff
|
|
23
|
+
)
|
|
24
|
+
end, { _typeCheck = "UDim" })
|
|
25
|
+
|
|
26
|
+
UDimCodec.udim2 = Base.define(16, function(b: buffer, off: number, value: UDim2): ()
|
|
27
|
+
local x = value.X
|
|
28
|
+
local y = value.Y
|
|
29
|
+
buffer.writef32(b, off, x.Scale)
|
|
30
|
+
buffer.writeu32(b, off + 4, if x.Offset < 0 then x.Offset + 0x100000000 else x.Offset)
|
|
31
|
+
buffer.writef32(b, off + 8, y.Scale)
|
|
32
|
+
buffer.writeu32(b, off + 12, if y.Offset < 0 then y.Offset + 0x100000000 else y.Offset)
|
|
33
|
+
end, function(b: buffer, off: number): UDim2
|
|
34
|
+
local xOff = buffer.readu32(b, off + 4)
|
|
35
|
+
local yOff = buffer.readu32(b, off + 12)
|
|
36
|
+
return UDim2.new(
|
|
37
|
+
UDim.new(buffer.readf32(b, off), if xOff >= 0x80000000 then xOff - 0x100000000 else xOff),
|
|
38
|
+
UDim.new(
|
|
39
|
+
buffer.readf32(b, off + 8),
|
|
40
|
+
if yOff >= 0x80000000 then yOff - 0x100000000 else yOff
|
|
25
41
|
)
|
|
26
|
-
|
|
27
|
-
})
|
|
42
|
+
)
|
|
43
|
+
end, { _typeCheck = "UDim2" })
|
|
44
|
+
|
|
45
|
+
return table.freeze(UDimCodec)
|