@axpecter/lync 1.4.3 → 1.5.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 +41 -2
- package/package.json +1 -1
- package/src/Types.luau +13 -1
- package/src/api/Group.luau +35 -28
- package/src/api/Namespace.luau +107 -89
- package/src/api/Packet.luau +69 -51
- package/src/api/Query.luau +101 -95
- package/src/api/Scope.luau +32 -18
- package/src/api/Signal.luau +78 -56
- package/src/codec/Base.luau +17 -17
- package/src/codec/composite/Array.luau +74 -74
- package/src/codec/composite/Map.luau +80 -80
- package/src/codec/composite/Optional.luau +14 -14
- package/src/codec/composite/Shared.luau +35 -35
- package/src/codec/composite/Struct.luau +108 -108
- package/src/codec/composite/Tagged.luau +71 -71
- package/src/codec/composite/Tuple.luau +35 -35
- package/src/codec/datatype/Buffer.luau +18 -18
- package/src/codec/datatype/CFrame.luau +24 -24
- package/src/codec/datatype/Color.luau +8 -12
- package/src/codec/datatype/Instance.luau +13 -13
- package/src/codec/datatype/IntVector.luau +17 -17
- package/src/codec/datatype/NumberRange.luau +7 -7
- package/src/codec/datatype/Ray.luau +16 -16
- package/src/codec/datatype/Rect.luau +13 -13
- package/src/codec/datatype/Region.luau +32 -36
- package/src/codec/datatype/Sequence.luau +41 -41
- package/src/codec/datatype/String.luau +28 -28
- package/src/codec/datatype/UDim.luau +17 -17
- package/src/codec/datatype/Vector.luau +14 -18
- package/src/codec/meta/Auto.luau +75 -73
- package/src/codec/meta/Bitfield.luau +46 -46
- package/src/codec/meta/Custom.luau +7 -7
- package/src/codec/meta/Enum.luau +25 -25
- package/src/codec/meta/Nothing.luau +3 -3
- package/src/codec/meta/Quantized.luau +63 -60
- package/src/codec/meta/Unknown.luau +11 -11
- package/src/codec/primitive/Bool.luau +12 -12
- package/src/codec/primitive/Float16.luau +28 -28
- package/src/codec/primitive/Number.luau +41 -41
- package/src/codec/primitive/Varint.luau +19 -19
- package/src/init.luau +81 -61
- package/src/internal/Baseline.luau +7 -7
- package/src/internal/Channel.luau +56 -56
- package/src/internal/Middleware.luau +29 -29
- package/src/internal/Pool.luau +15 -15
- package/src/internal/Registry.luau +19 -19
- package/src/transport/Bridge.luau +17 -17
- package/src/transport/Client.luau +46 -46
- package/src/transport/Gate.luau +56 -64
- package/src/transport/Reader.luau +34 -34
- package/src/transport/Server.luau +89 -89
|
@@ -9,21 +9,21 @@ type Chain = {
|
|
|
9
9
|
snapshot: { Handler }?,
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
-- Constants
|
|
12
|
+
-- Constants -----------------------------------------------------------
|
|
13
13
|
|
|
14
|
-
local DROP = table.freeze
|
|
14
|
+
local DROP = table.freeze({ _tag = "drop" })
|
|
15
15
|
|
|
16
|
-
-- State
|
|
16
|
+
-- State ---------------------------------------------------------------
|
|
17
17
|
|
|
18
18
|
local _send: Chain = { handlers = {}, snapshot = nil }
|
|
19
19
|
local _receive: Chain = { handlers = {}, snapshot = nil }
|
|
20
20
|
|
|
21
|
-
-- Private
|
|
21
|
+
-- Private -------------------------------------------------------------
|
|
22
22
|
|
|
23
|
-
local function runChain
|
|
23
|
+
local function runChain(chain: { Handler }, data: any, name: string, player: Player?): any?
|
|
24
24
|
local current = data
|
|
25
25
|
for i = 1, #chain do
|
|
26
|
-
local result = chain[i]
|
|
26
|
+
local result = chain[i](current, name, player)
|
|
27
27
|
if result == nil or result == DROP then
|
|
28
28
|
return nil
|
|
29
29
|
end
|
|
@@ -32,7 +32,7 @@ local function runChain (chain: { Handler }, data: any, name: string, player: Pl
|
|
|
32
32
|
return current
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
local function run
|
|
35
|
+
local function run(chain: Chain, data: any, name: string, player: Player?): any?
|
|
36
36
|
local handlers = chain.handlers
|
|
37
37
|
local count = #handlers
|
|
38
38
|
if count == 0 then
|
|
@@ -41,7 +41,7 @@ local function run (chain: Chain, data: any, name: string, player: Player?): any
|
|
|
41
41
|
|
|
42
42
|
local snapshot = chain.snapshot
|
|
43
43
|
if not snapshot then
|
|
44
|
-
snapshot = table.clone
|
|
44
|
+
snapshot = table.clone(handlers)
|
|
45
45
|
chain.snapshot = snapshot
|
|
46
46
|
end
|
|
47
47
|
|
|
@@ -49,13 +49,13 @@ local function run (chain: Chain, data: any, name: string, player: Player?): any
|
|
|
49
49
|
local result: any
|
|
50
50
|
|
|
51
51
|
if count == 1 then
|
|
52
|
-
ok, result = pcall
|
|
52
|
+
ok, result = pcall(snapshot[1], data, name, player)
|
|
53
53
|
else
|
|
54
|
-
ok, result = pcall
|
|
54
|
+
ok, result = pcall(runChain, snapshot, data, name, player)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
if not ok then
|
|
58
|
-
warn
|
|
58
|
+
warn(`[Lync] Middleware error on "{name}": {result}`)
|
|
59
59
|
return nil
|
|
60
60
|
end
|
|
61
61
|
|
|
@@ -66,20 +66,20 @@ local function run (chain: Chain, data: any, name: string, player: Player?): any
|
|
|
66
66
|
return result
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
local function addTo
|
|
70
|
-
table.insert
|
|
69
|
+
local function addTo(chain: Chain, fn: Handler): () -> ()
|
|
70
|
+
table.insert(chain.handlers, fn)
|
|
71
71
|
chain.snapshot = nil
|
|
72
72
|
|
|
73
|
-
return function
|
|
74
|
-
local pos = table.find
|
|
73
|
+
return function(): ()
|
|
74
|
+
local pos = table.find(chain.handlers, fn)
|
|
75
75
|
if pos then
|
|
76
|
-
table.remove
|
|
76
|
+
table.remove(chain.handlers, pos)
|
|
77
77
|
chain.snapshot = nil
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
80
|
end
|
|
81
81
|
|
|
82
|
-
-- Public
|
|
82
|
+
-- Public --------------------------------------------------------------
|
|
83
83
|
|
|
84
84
|
local Middleware = {}
|
|
85
85
|
|
|
@@ -87,32 +87,32 @@ Middleware.hasSend = false
|
|
|
87
87
|
Middleware.hasReceive = false
|
|
88
88
|
Middleware.DROP = DROP
|
|
89
89
|
|
|
90
|
-
function Middleware.addSend
|
|
91
|
-
local remover = addTo
|
|
90
|
+
function Middleware.addSend(fn: Handler): () -> ()
|
|
91
|
+
local remover = addTo(_send, fn)
|
|
92
92
|
Middleware.hasSend = true
|
|
93
93
|
|
|
94
|
-
return function
|
|
95
|
-
remover
|
|
94
|
+
return function(): ()
|
|
95
|
+
remover()
|
|
96
96
|
Middleware.hasSend = #_send.handlers > 0
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
-
function Middleware.addReceive
|
|
101
|
-
local remover = addTo
|
|
100
|
+
function Middleware.addReceive(fn: Handler): () -> ()
|
|
101
|
+
local remover = addTo(_receive, fn)
|
|
102
102
|
Middleware.hasReceive = true
|
|
103
103
|
|
|
104
|
-
return function
|
|
105
|
-
remover
|
|
104
|
+
return function(): ()
|
|
105
|
+
remover()
|
|
106
106
|
Middleware.hasReceive = #_receive.handlers > 0
|
|
107
107
|
end
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
-
function Middleware.runSend
|
|
111
|
-
return run
|
|
110
|
+
function Middleware.runSend(data: any, name: string, player: Player?): any?
|
|
111
|
+
return run(_send, data, name, player)
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
-
function Middleware.runReceive
|
|
115
|
-
return run
|
|
114
|
+
function Middleware.runReceive(data: any, name: string, player: Player?): any?
|
|
115
|
+
return run(_receive, data, name, player)
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
-- Not frozen: hasSend and hasReceive are mutated at runtime.
|
package/src/internal/Pool.luau
CHANGED
|
@@ -2,38 +2,38 @@
|
|
|
2
2
|
--!optimize 2
|
|
3
3
|
-- Stack-based ChannelState pool with warmup support.
|
|
4
4
|
|
|
5
|
-
local Channel = require
|
|
6
|
-
local Types = require
|
|
5
|
+
local Channel = require(script.Parent.Channel)
|
|
6
|
+
local Types = require(script.Parent.Parent.Types)
|
|
7
7
|
|
|
8
8
|
type ChannelState = Types.ChannelState
|
|
9
9
|
|
|
10
|
-
-- Constants
|
|
10
|
+
-- Constants -----------------------------------------------------------
|
|
11
11
|
|
|
12
12
|
local DEFAULT_MAX = 16
|
|
13
13
|
|
|
14
|
-
-- State
|
|
14
|
+
-- State ---------------------------------------------------------------
|
|
15
15
|
|
|
16
16
|
local _stack = {} :: { ChannelState }
|
|
17
17
|
local _depth = 0
|
|
18
18
|
local _maxSize = DEFAULT_MAX
|
|
19
19
|
|
|
20
|
-
-- Public
|
|
20
|
+
-- Public --------------------------------------------------------------
|
|
21
21
|
|
|
22
22
|
local Pool = {}
|
|
23
23
|
|
|
24
24
|
-- Override the max idle ChannelStates in the pool. Default 16. Range: 2-128.
|
|
25
|
-
function Pool.setMaxSize
|
|
25
|
+
function Pool.setMaxSize(count: number): ()
|
|
26
26
|
if count < 2 or count > 128 then
|
|
27
|
-
error
|
|
27
|
+
error(`[Lync] Pool max size must be 2-128, got {count}`)
|
|
28
28
|
end
|
|
29
29
|
_maxSize = count
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
function Pool.getMaxSize
|
|
32
|
+
function Pool.getMaxSize(): number
|
|
33
33
|
return _maxSize
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
function Pool.acquire
|
|
36
|
+
function Pool.acquire(): ChannelState
|
|
37
37
|
if _depth > 0 then
|
|
38
38
|
local ch = _stack[_depth]
|
|
39
39
|
_stack[_depth] = nil :: any
|
|
@@ -41,16 +41,16 @@ function Pool.acquire (): ChannelState
|
|
|
41
41
|
return ch
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
return Channel.create
|
|
44
|
+
return Channel.create()
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
function Pool.release
|
|
47
|
+
function Pool.release(ch: ChannelState): ()
|
|
48
48
|
ch.cursor = 0
|
|
49
49
|
ch.lastId = -1
|
|
50
50
|
ch.countPos = 0
|
|
51
51
|
ch.itemCount = 0
|
|
52
|
-
table.clear
|
|
53
|
-
table.clear
|
|
52
|
+
table.clear(ch.refs)
|
|
53
|
+
table.clear(ch.deltas)
|
|
54
54
|
ch.prevDump = nil
|
|
55
55
|
|
|
56
56
|
if _depth >= _maxSize then
|
|
@@ -61,8 +61,8 @@ function Pool.release (ch: ChannelState): ()
|
|
|
61
61
|
_stack[_depth] = ch
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
function Pool.size
|
|
64
|
+
function Pool.size(): number
|
|
65
65
|
return _depth
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
return table.freeze
|
|
68
|
+
return table.freeze(Pool)
|
|
@@ -2,28 +2,28 @@
|
|
|
2
2
|
--!optimize 2
|
|
3
3
|
-- Deterministic ID assignment for packets and queries.
|
|
4
4
|
|
|
5
|
-
local Types = require
|
|
5
|
+
local Types = require(script.Parent.Parent.Types)
|
|
6
6
|
|
|
7
7
|
type Codec<T> = Types.Codec<T>
|
|
8
8
|
type Registration = Types.Registration
|
|
9
9
|
type RateLimitConfig = Types.RateLimitConfig
|
|
10
10
|
|
|
11
|
-
-- Constants
|
|
11
|
+
-- Constants -----------------------------------------------------------
|
|
12
12
|
|
|
13
13
|
local KIND_PACKET = 0
|
|
14
14
|
local KIND_REQUEST = 1
|
|
15
15
|
local KIND_RESPONSE = 2
|
|
16
16
|
local MAX_PACKETS = 255
|
|
17
17
|
|
|
18
|
-
-- State
|
|
18
|
+
-- State ---------------------------------------------------------------
|
|
19
19
|
|
|
20
20
|
local _entries = {} :: { Registration }
|
|
21
21
|
local _names = {} :: { [string]: number }
|
|
22
22
|
local _nextId = 1
|
|
23
23
|
|
|
24
|
-
-- Private
|
|
24
|
+
-- Private -------------------------------------------------------------
|
|
25
25
|
|
|
26
|
-
local function assign
|
|
26
|
+
local function assign(
|
|
27
27
|
name: string,
|
|
28
28
|
baseName: string,
|
|
29
29
|
codec: Codec<any>,
|
|
@@ -35,23 +35,23 @@ local function assign (
|
|
|
35
35
|
maxPayloadBytes: number?
|
|
36
36
|
): Registration
|
|
37
37
|
if _names[name] then
|
|
38
|
-
error
|
|
38
|
+
error(`[Lync] Duplicate registration: "{name}"`)
|
|
39
39
|
end
|
|
40
40
|
if _nextId > MAX_PACKETS then
|
|
41
|
-
error
|
|
41
|
+
error(`[Lync] Registration limit reached: {MAX_PACKETS} max`)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
if rateLimit then
|
|
45
45
|
if rateLimit.maxPerSecond <= 0 then
|
|
46
|
-
error
|
|
46
|
+
error(`[Lync] maxPerSecond must be positive: "{name}"`)
|
|
47
47
|
end
|
|
48
48
|
if rateLimit.burstAllowance and rateLimit.burstAllowance <= 0 then
|
|
49
|
-
error
|
|
49
|
+
error(`[Lync] burstAllowance must be positive: "{name}"`)
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
if maxPayloadBytes and maxPayloadBytes <= 0 then
|
|
54
|
-
error
|
|
54
|
+
error(`[Lync] maxPayloadBytes must be positive: "{name}"`)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
local id = _nextId
|
|
@@ -77,7 +77,7 @@ local function assign (
|
|
|
77
77
|
return reg
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
-
-- Public
|
|
80
|
+
-- Public --------------------------------------------------------------
|
|
81
81
|
|
|
82
82
|
local Registry = {
|
|
83
83
|
KIND_PACKET = KIND_PACKET,
|
|
@@ -85,7 +85,7 @@ local Registry = {
|
|
|
85
85
|
KIND_RESPONSE = KIND_RESPONSE,
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
function Registry.register
|
|
88
|
+
function Registry.register(
|
|
89
89
|
name: string,
|
|
90
90
|
codec: Codec<any>,
|
|
91
91
|
isUnreliable: boolean,
|
|
@@ -94,7 +94,7 @@ function Registry.register (
|
|
|
94
94
|
validate: ((data: any, player: Player) -> (boolean, string?))?,
|
|
95
95
|
maxPayloadBytes: number?
|
|
96
96
|
): Registration
|
|
97
|
-
return assign
|
|
97
|
+
return assign(
|
|
98
98
|
name,
|
|
99
99
|
name,
|
|
100
100
|
codec,
|
|
@@ -107,7 +107,7 @@ function Registry.register (
|
|
|
107
107
|
)
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
-
function Registry.registerQueryPair
|
|
110
|
+
function Registry.registerQueryPair(
|
|
111
111
|
name: string,
|
|
112
112
|
requestCodec: Codec<any>,
|
|
113
113
|
responseCodec: Codec<any>,
|
|
@@ -116,7 +116,7 @@ function Registry.registerQueryPair (
|
|
|
116
116
|
rateLimit: RateLimitConfig?,
|
|
117
117
|
validate: ((data: any, player: Player) -> (boolean, string?))?
|
|
118
118
|
): (Registration, Registration)
|
|
119
|
-
local req = assign
|
|
119
|
+
local req = assign(
|
|
120
120
|
`{name}:req`,
|
|
121
121
|
name,
|
|
122
122
|
requestCodec,
|
|
@@ -127,20 +127,20 @@ function Registry.registerQueryPair (
|
|
|
127
127
|
validate
|
|
128
128
|
)
|
|
129
129
|
local resp =
|
|
130
|
-
assign
|
|
130
|
+
assign(`{name}:resp`, name, responseCodec, false, KIND_RESPONSE, responseSignal, nil, nil)
|
|
131
131
|
|
|
132
132
|
req.partner = resp.id
|
|
133
133
|
resp.partner = req.id
|
|
134
134
|
return req, resp
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
-
function Registry.get
|
|
137
|
+
function Registry.get(id: number): Registration?
|
|
138
138
|
return _entries[id]
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
-
function Registry.getByName
|
|
141
|
+
function Registry.getByName(name: string): Registration?
|
|
142
142
|
local id = _names[name]
|
|
143
143
|
return if id then _entries[id] else nil
|
|
144
144
|
end
|
|
145
145
|
|
|
146
|
-
return table.freeze
|
|
146
|
+
return table.freeze(Registry)
|
|
@@ -2,35 +2,35 @@
|
|
|
2
2
|
--!optimize 2
|
|
3
3
|
-- Creates and exposes the network remote instances.
|
|
4
4
|
|
|
5
|
-
local ReplicatedStorage = game:GetService
|
|
6
|
-
local RunService = game:GetService
|
|
5
|
+
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
6
|
+
local RunService = game:GetService("RunService")
|
|
7
7
|
|
|
8
|
-
-- Constants
|
|
8
|
+
-- Constants -----------------------------------------------------------
|
|
9
9
|
|
|
10
10
|
local FOLDER = "_lync"
|
|
11
11
|
local RELIABLE = "R"
|
|
12
12
|
local UNRELIABLE = "U"
|
|
13
13
|
local TIMEOUT = 10
|
|
14
14
|
|
|
15
|
-
-- State
|
|
15
|
+
-- State ---------------------------------------------------------------
|
|
16
16
|
|
|
17
17
|
local _reliable: RemoteEvent
|
|
18
18
|
local _unreliable: UnreliableRemoteEvent
|
|
19
19
|
|
|
20
|
-
-- Public
|
|
20
|
+
-- Public --------------------------------------------------------------
|
|
21
21
|
|
|
22
22
|
local Bridge = {}
|
|
23
23
|
|
|
24
|
-
function Bridge.setup
|
|
25
|
-
if RunService:IsServer
|
|
26
|
-
local folder = Instance.new
|
|
24
|
+
function Bridge.setup(): ()
|
|
25
|
+
if RunService:IsServer() then
|
|
26
|
+
local folder = Instance.new("Folder")
|
|
27
27
|
folder.Name = FOLDER
|
|
28
28
|
|
|
29
|
-
local reliable = Instance.new
|
|
29
|
+
local reliable = Instance.new("RemoteEvent")
|
|
30
30
|
reliable.Name = RELIABLE
|
|
31
31
|
reliable.Parent = folder
|
|
32
32
|
|
|
33
|
-
local unreliable = Instance.new
|
|
33
|
+
local unreliable = Instance.new("UnreliableRemoteEvent")
|
|
34
34
|
unreliable.Name = UNRELIABLE
|
|
35
35
|
unreliable.Parent = folder
|
|
36
36
|
|
|
@@ -39,19 +39,19 @@ function Bridge.setup (): ()
|
|
|
39
39
|
_reliable = reliable
|
|
40
40
|
_unreliable = unreliable
|
|
41
41
|
else
|
|
42
|
-
local folder = ReplicatedStorage:WaitForChild
|
|
42
|
+
local folder = ReplicatedStorage:WaitForChild(FOLDER, TIMEOUT)
|
|
43
43
|
if not folder then
|
|
44
|
-
error
|
|
44
|
+
error("[Lync] Network folder not found, is the server started?")
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
local reliable = folder:WaitForChild
|
|
47
|
+
local reliable = folder:WaitForChild(RELIABLE, TIMEOUT)
|
|
48
48
|
if not reliable then
|
|
49
|
-
error
|
|
49
|
+
error("[Lync] Reliable remote not found")
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
local unreliable = folder:WaitForChild
|
|
52
|
+
local unreliable = folder:WaitForChild(UNRELIABLE, TIMEOUT)
|
|
53
53
|
if not unreliable then
|
|
54
|
-
error
|
|
54
|
+
error("[Lync] Unreliable remote not found")
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
_reliable = reliable :: RemoteEvent
|
|
@@ -60,7 +60,7 @@ function Bridge.setup (): ()
|
|
|
60
60
|
|
|
61
61
|
Bridge.reliable = _reliable :: any
|
|
62
62
|
Bridge.unreliable = _unreliable :: any
|
|
63
|
-
table.freeze
|
|
63
|
+
table.freeze(Bridge)
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
-- Not frozen at module level: setup() populates reliable/unreliable then freezes.
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
--!optimize 2
|
|
3
3
|
-- Client-side transport with batching, frame XOR on reliable.
|
|
4
4
|
|
|
5
|
-
local RunService = game:GetService
|
|
5
|
+
local RunService = game:GetService("RunService")
|
|
6
6
|
|
|
7
|
-
local Bridge = require
|
|
8
|
-
local Channel = require
|
|
9
|
-
local Middleware = require
|
|
10
|
-
local Reader = require
|
|
11
|
-
local Types = require
|
|
7
|
+
local Bridge = require(script.Parent.Bridge)
|
|
8
|
+
local Channel = require(script.Parent.Parent.internal.Channel)
|
|
9
|
+
local Middleware = require(script.Parent.Parent.internal.Middleware)
|
|
10
|
+
local Reader = require(script.Parent.Reader)
|
|
11
|
+
local Types = require(script.Parent.Parent.Types)
|
|
12
12
|
|
|
13
13
|
type ChannelState = Types.ChannelState
|
|
14
14
|
type Codec<T> = Types.Codec<T>
|
|
15
15
|
|
|
16
|
-
-- State
|
|
16
|
+
-- State ---------------------------------------------------------------
|
|
17
17
|
|
|
18
18
|
local NOT_STARTED = "[Lync] Client not started. Call Lync.start() before sending"
|
|
19
19
|
|
|
@@ -22,77 +22,77 @@ local _unreliable = nil :: ChannelState?
|
|
|
22
22
|
local _prevRecv = nil :: buffer?
|
|
23
23
|
local _isStarted = false
|
|
24
24
|
|
|
25
|
-
-- Private
|
|
25
|
+
-- Private -------------------------------------------------------------
|
|
26
26
|
|
|
27
|
-
local function receive
|
|
28
|
-
local buf = Reader.decodeIncoming
|
|
27
|
+
local function receive(data: any, refs: any, applyXor: boolean): ()
|
|
28
|
+
local buf = Reader.decodeIncoming(data)
|
|
29
29
|
if not buf then
|
|
30
30
|
return
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
local raw: buffer
|
|
34
34
|
if applyXor then
|
|
35
|
-
raw = Channel.xorApply
|
|
35
|
+
raw = Channel.xorApply(buf, _prevRecv)
|
|
36
36
|
_prevRecv = raw
|
|
37
37
|
else
|
|
38
38
|
raw = buf
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
local safeRefs: { Instance }? = if typeof
|
|
42
|
-
local ok, err = pcall
|
|
41
|
+
local safeRefs: { Instance }? = if typeof(refs) == "table" then refs else nil
|
|
42
|
+
local ok, err = pcall(Reader.process, raw, safeRefs, nil, 0)
|
|
43
43
|
if not ok then
|
|
44
|
-
warn
|
|
44
|
+
warn(`[Lync] Read failed: {err}`)
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
local function flushChannel
|
|
48
|
+
local function flushChannel(remote: any, ch: ChannelState, applyXor: boolean): ()
|
|
49
49
|
if ch.cursor == 0 then
|
|
50
50
|
return
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
local raw, refs = Channel.sealAndDump
|
|
53
|
+
local raw, refs = Channel.sealAndDump(ch)
|
|
54
54
|
|
|
55
55
|
if applyXor then
|
|
56
|
-
local xored = Channel.xorApply
|
|
56
|
+
local xored = Channel.xorApply(raw, ch.prevDump)
|
|
57
57
|
ch.prevDump = raw
|
|
58
|
-
remote:FireServer
|
|
58
|
+
remote:FireServer(xored, refs)
|
|
59
59
|
else
|
|
60
|
-
remote:FireServer
|
|
60
|
+
remote:FireServer(raw, refs)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
Channel.reset
|
|
63
|
+
Channel.reset(ch)
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
local function flush
|
|
67
|
-
flushChannel
|
|
68
|
-
flushChannel
|
|
66
|
+
local function flush(): ()
|
|
67
|
+
flushChannel(Bridge.reliable, _reliable :: ChannelState, true)
|
|
68
|
+
flushChannel(Bridge.unreliable, _unreliable :: ChannelState, false)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
-- Public
|
|
71
|
+
-- Public --------------------------------------------------------------
|
|
72
72
|
|
|
73
73
|
local Client = {}
|
|
74
74
|
|
|
75
|
-
function Client.start
|
|
75
|
+
function Client.start(): ()
|
|
76
76
|
if _isStarted then
|
|
77
77
|
return
|
|
78
78
|
end
|
|
79
79
|
_isStarted = true
|
|
80
80
|
|
|
81
|
-
Bridge.setup
|
|
81
|
+
Bridge.setup()
|
|
82
82
|
|
|
83
|
-
_reliable = Channel.create
|
|
84
|
-
_unreliable = Channel.create
|
|
83
|
+
_reliable = Channel.create()
|
|
84
|
+
_unreliable = Channel.create()
|
|
85
85
|
|
|
86
|
-
Bridge.reliable.OnClientEvent:Connect
|
|
87
|
-
receive
|
|
86
|
+
Bridge.reliable.OnClientEvent:Connect(function(data: any, refs: any): ()
|
|
87
|
+
receive(data, refs, true)
|
|
88
88
|
end)
|
|
89
|
-
Bridge.unreliable.OnClientEvent:Connect
|
|
90
|
-
receive
|
|
89
|
+
Bridge.unreliable.OnClientEvent:Connect(function(data: any, refs: any): ()
|
|
90
|
+
receive(data, refs, false)
|
|
91
91
|
end)
|
|
92
|
-
RunService.Heartbeat:Connect
|
|
92
|
+
RunService.Heartbeat:Connect(flush)
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
function Client.write
|
|
95
|
+
function Client.write(
|
|
96
96
|
id: number,
|
|
97
97
|
name: string,
|
|
98
98
|
codec: Codec<any>,
|
|
@@ -100,12 +100,12 @@ function Client.write (
|
|
|
100
100
|
isUnreliable: boolean
|
|
101
101
|
): ()
|
|
102
102
|
if not _isStarted then
|
|
103
|
-
error
|
|
103
|
+
error(NOT_STARTED)
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
local final: any
|
|
107
107
|
if Middleware.hasSend then
|
|
108
|
-
final = Middleware.runSend
|
|
108
|
+
final = Middleware.runSend(data, name, nil)
|
|
109
109
|
if final == nil then
|
|
110
110
|
return
|
|
111
111
|
end
|
|
@@ -114,11 +114,11 @@ function Client.write (
|
|
|
114
114
|
end
|
|
115
115
|
|
|
116
116
|
local ch = if isUnreliable then _unreliable :: ChannelState else _reliable :: ChannelState
|
|
117
|
-
Channel.writeBatch
|
|
117
|
+
Channel.writeBatch(ch, id, name, codec, final)
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
-- Shared for both query requests and responses
|
|
121
|
-
function Client.writeQuery
|
|
120
|
+
-- Shared for both query requests and responses(identical wire format).
|
|
121
|
+
function Client.writeQuery(
|
|
122
122
|
id: number,
|
|
123
123
|
name: string,
|
|
124
124
|
correlationId: number,
|
|
@@ -126,12 +126,12 @@ function Client.writeQuery (
|
|
|
126
126
|
data: any
|
|
127
127
|
): ()
|
|
128
128
|
if not _isStarted then
|
|
129
|
-
error
|
|
129
|
+
error(NOT_STARTED)
|
|
130
130
|
end
|
|
131
131
|
|
|
132
132
|
local final: any
|
|
133
133
|
if Middleware.hasSend then
|
|
134
|
-
final = Middleware.runSend
|
|
134
|
+
final = Middleware.runSend(data, name, nil)
|
|
135
135
|
if final == nil then
|
|
136
136
|
return
|
|
137
137
|
end
|
|
@@ -139,14 +139,14 @@ function Client.writeQuery (
|
|
|
139
139
|
final = data
|
|
140
140
|
end
|
|
141
141
|
|
|
142
|
-
Channel.writeQuery
|
|
142
|
+
Channel.writeQuery(_reliable :: ChannelState, id, name, correlationId, codec, final)
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
function Client.writeQueryNil
|
|
145
|
+
function Client.writeQueryNil(id: number, name: string, correlationId: number): ()
|
|
146
146
|
if not _isStarted then
|
|
147
|
-
error
|
|
147
|
+
error(NOT_STARTED)
|
|
148
148
|
end
|
|
149
|
-
Channel.writeQuery
|
|
149
|
+
Channel.writeQuery(_reliable :: ChannelState, id, name, correlationId, nil, nil)
|
|
150
150
|
end
|
|
151
151
|
|
|
152
|
-
return table.freeze
|
|
152
|
+
return table.freeze(Client)
|