@rbxts/replecs 0.2.3-test1 → 0.2.4
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 +0 -2
- package/out/replecs/client.luau +620 -320
- package/out/replecs/common.luau +184 -59
- package/out/replecs/customid.luau +9 -8
- package/out/replecs/index.d.ts +229 -229
- package/out/replecs/init.luau +53 -66
- package/out/replecs/masking/init.luau +523 -386
- package/out/replecs/masking/mask_generator.luau +1 -1
- package/out/replecs/server.luau +953 -440
- package/out/replecs/types.luau +67 -0
- package/out/replecs/utils.luau +257 -198
- package/out/replecs/ver.luau +1 -2
- package/out/tsconfig.tsbuildinfo +1 -0
- package/package.json +47 -45
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
local customid = require (script.Parent:WaitForChild('customid'))
|
|
2
|
+
local common = require (script.Parent:WaitForChild('common'))
|
|
3
|
+
|
|
4
|
+
export type PlayerFilter = {
|
|
5
|
+
[Player]: boolean,
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type FunctionFilter = (player: Player) -> boolean
|
|
9
|
+
export type AnyFilter = PlayerFilter | Player
|
|
10
|
+
|
|
11
|
+
type Entity = common.Entity
|
|
12
|
+
type World = common.World
|
|
13
|
+
type Component<T = any> = common.Component<T>
|
|
14
|
+
|
|
15
|
+
export type SharedInfo<T> = {
|
|
16
|
+
lookup: { [string]: T },
|
|
17
|
+
keys: { string },
|
|
18
|
+
indexes: { [number]: T },
|
|
19
|
+
members: { [T]: number },
|
|
20
|
+
}
|
|
21
|
+
export type HandshakeInfo = {
|
|
22
|
+
components: { [string]: boolean },
|
|
23
|
+
custom_ids: { [string]: boolean },
|
|
24
|
+
serdes: { [string]: {
|
|
25
|
+
includes_variants: boolean?,
|
|
26
|
+
bytespan: number?,
|
|
27
|
+
} },
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type Serdes<T = any> = {
|
|
31
|
+
includes_variants: boolean?,
|
|
32
|
+
bytespan: number?,
|
|
33
|
+
serialize: (value: T) -> (buffer, ...{ any }),
|
|
34
|
+
deserialize: (buffer,...{ any }) -> T,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type Components = {
|
|
38
|
+
shared: Entity,
|
|
39
|
+
Shared: Entity,
|
|
40
|
+
networked: Component<any?>,
|
|
41
|
+
Networked: Component<AnyFilter?>,
|
|
42
|
+
reliable: Component<AnyFilter?>,
|
|
43
|
+
Reliable: Component<AnyFilter?>,
|
|
44
|
+
unreliable: Component<AnyFilter?>,
|
|
45
|
+
Unreliable: Component<AnyFilter?>,
|
|
46
|
+
relation: Component<AnyFilter?>,
|
|
47
|
+
Relation: Component<AnyFilter?>,
|
|
48
|
+
|
|
49
|
+
serdes: Component<Serdes>,
|
|
50
|
+
Serdes: Component<Serdes>,
|
|
51
|
+
custom: Entity,
|
|
52
|
+
Custom: Entity,
|
|
53
|
+
custom_handler: Component<(val: any) -> Entity?>,
|
|
54
|
+
CustomHandler: Component<(val: any) -> Entity?>,
|
|
55
|
+
global: Component<number>,
|
|
56
|
+
Global: Component<number>,
|
|
57
|
+
__alive_tracking__: Entity,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type Shared = {
|
|
61
|
+
components: SharedInfo<Entity>,
|
|
62
|
+
custom_ids: SharedInfo<customid.CustomId>,
|
|
63
|
+
|
|
64
|
+
serdes: { [Component]: Serdes },
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return nil
|
package/out/replecs/utils.luau
CHANGED
|
@@ -1,23 +1,244 @@
|
|
|
1
|
-
--!native
|
|
2
1
|
--!optimize 2
|
|
2
|
+
--!native
|
|
3
3
|
|
|
4
|
-
local
|
|
5
|
-
local
|
|
6
|
-
local
|
|
4
|
+
local customid = require (script.Parent:WaitForChild('customid'))
|
|
5
|
+
local common = require (script.Parent:WaitForChild('common'))
|
|
6
|
+
local types = require (script.Parent:WaitForChild('types'))
|
|
7
7
|
|
|
8
|
-
type World =
|
|
9
|
-
type Entity
|
|
8
|
+
type World = common.World
|
|
9
|
+
type Entity = common.Entity
|
|
10
|
+
type Component = common.Component
|
|
10
11
|
|
|
11
12
|
export type Cursor = {
|
|
12
13
|
offset: number,
|
|
13
14
|
buffer: buffer,
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
local ECS_NAME =
|
|
17
|
-
local
|
|
17
|
+
local ECS_NAME = common.ecs_name
|
|
18
|
+
local RELATIONSHPIS = common.relationships
|
|
18
19
|
|
|
19
20
|
local utils = {}
|
|
20
21
|
|
|
22
|
+
function utils.create_shared_lookup<T>(lookup: { [string]: T }): types.SharedInfo<T>
|
|
23
|
+
local keys = {}
|
|
24
|
+
local indexes = {}
|
|
25
|
+
local members = {}
|
|
26
|
+
|
|
27
|
+
for name in lookup do
|
|
28
|
+
table.insert(keys, name)
|
|
29
|
+
end
|
|
30
|
+
table.sort(keys)
|
|
31
|
+
|
|
32
|
+
for index, name in keys do
|
|
33
|
+
local member = lookup[name]
|
|
34
|
+
members[member] = index
|
|
35
|
+
indexes[index] = member
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
lookup = lookup,
|
|
40
|
+
keys = keys,
|
|
41
|
+
indexes = indexes,
|
|
42
|
+
members = members,
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
function utils.generate_handshake(shared: types.Shared): types.HandshakeInfo
|
|
47
|
+
local component_to_name: { [Entity]: string } = {}
|
|
48
|
+
local handshake: types.HandshakeInfo = {
|
|
49
|
+
components = {},
|
|
50
|
+
custom_ids = {},
|
|
51
|
+
serdes = {},
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
for component_name, component in shared.components.lookup do
|
|
55
|
+
handshake.components[component_name] = true
|
|
56
|
+
component_to_name[component] = component_name
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
for custom_id in shared.custom_ids.lookup do
|
|
60
|
+
handshake.custom_ids[custom_id] = true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
for component, serdes in shared.serdes do
|
|
64
|
+
local name = component_to_name[component]
|
|
65
|
+
if not name then
|
|
66
|
+
continue
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
handshake.serdes[name] = {
|
|
70
|
+
includes_variants = serdes.includes_variants,
|
|
71
|
+
bytespan = serdes.bytespan,
|
|
72
|
+
}
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
return handshake
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
function utils.verify_handshake(
|
|
79
|
+
shared: types.Shared,
|
|
80
|
+
handshake: types.HandshakeInfo,
|
|
81
|
+
handshake_side: string,
|
|
82
|
+
verify_side: string
|
|
83
|
+
): (boolean, string?)
|
|
84
|
+
local component_to_name: { [Entity]: string } = {}
|
|
85
|
+
|
|
86
|
+
for component_name in handshake.components do
|
|
87
|
+
if not shared.components.lookup[component_name] then
|
|
88
|
+
return false, `missing shared component "{component_name}" in {verify_side}`
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
for component_name, component in shared.components.lookup do
|
|
92
|
+
if not handshake.components[component_name] then
|
|
93
|
+
return false, `missing shared component "{component_name}" in {handshake_side}`
|
|
94
|
+
end
|
|
95
|
+
component_to_name[component] = component_name
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
for custom_id in handshake.custom_ids do
|
|
99
|
+
if not shared.custom_ids.lookup[custom_id] then
|
|
100
|
+
return false, `missing custom id "{custom_id}" in {verify_side}`
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
for custom_id in shared.custom_ids.lookup do
|
|
104
|
+
if not handshake.custom_ids[custom_id] then
|
|
105
|
+
return false, `missing custom id "{custom_id}" in {handshake_side}`
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
for component_name, serdes_info in handshake.serdes do
|
|
110
|
+
local component = shared.components.lookup[component_name]
|
|
111
|
+
if not component then
|
|
112
|
+
warn(`{handshake_side} registered a serdes for "{component_name}" that {verify_side} doesn't have`)
|
|
113
|
+
continue
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
local serdes = shared.serdes[component]
|
|
117
|
+
if not serdes then
|
|
118
|
+
return false, `missing serdes for component "{component_name}" in {verify_side}`
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
if (serdes_info.includes_variants or false) ~= (serdes.includes_variants or false) then
|
|
122
|
+
return false,
|
|
123
|
+
`mismatched includes_variants for component "{component_name}": ({serdes_info.includes_variants} ~= {serdes.includes_variants})`
|
|
124
|
+
end
|
|
125
|
+
if serdes_info.bytespan ~= serdes.bytespan then
|
|
126
|
+
return false,
|
|
127
|
+
`mismatched bytespan for component "{component_name}": ({serdes_info.bytespan} ~= {serdes.bytespan})`
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
for component in shared.serdes do
|
|
131
|
+
local component_name = component_to_name[component]
|
|
132
|
+
if not component_name then
|
|
133
|
+
continue
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
if not handshake.serdes[component_name] then
|
|
137
|
+
warn(`{verify_side} registered a serdes for "{component_name}" that {handshake_side} doesn't have`)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
return true, nil
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
function utils.resolved_shared(
|
|
145
|
+
world: World,
|
|
146
|
+
components: types.Components,
|
|
147
|
+
registered_custom_ids: { [customid.CustomId]: boolean },
|
|
148
|
+
serdes: { [Component]: types.Serdes }
|
|
149
|
+
): types.Shared
|
|
150
|
+
local shared = {} :: types.Shared
|
|
151
|
+
|
|
152
|
+
local components_lookup: { [string]: Entity } = table.clone(common.implicitly_shared)
|
|
153
|
+
local custom_ids_lookup = {}
|
|
154
|
+
|
|
155
|
+
for component, name in world:query(ECS_NAME):with(components.shared):iter() do
|
|
156
|
+
if components_lookup[name] then
|
|
157
|
+
common.log_error(`detected two components with the same {name} name: ({components_lookup[name]}, {component})`)
|
|
158
|
+
end
|
|
159
|
+
components_lookup[name] = component
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
for component in world:query(components.shared):without(ECS_NAME):iter() do
|
|
163
|
+
common.log_warn(`shared component: {component} has no name assigned.`)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
for custom in registered_custom_ids do
|
|
167
|
+
custom_ids_lookup[custom.identifier] = custom
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
for custom in registered_custom_ids do
|
|
171
|
+
custom_ids_lookup[custom.identifier] = custom
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
shared.serdes = serdes
|
|
175
|
+
shared.components = utils.create_shared_lookup(components_lookup)
|
|
176
|
+
shared.custom_ids = utils.create_shared_lookup(custom_ids_lookup)
|
|
177
|
+
|
|
178
|
+
return shared
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
function utils.create_components(tag: () -> Component, component: () -> Component, push: types.Components?)
|
|
182
|
+
local components = push or {} :: types.Components
|
|
183
|
+
components.shared = tag()
|
|
184
|
+
components.networked = component()
|
|
185
|
+
|
|
186
|
+
if RELATIONSHPIS then
|
|
187
|
+
components.reliable = component()
|
|
188
|
+
components.unreliable = component()
|
|
189
|
+
components.relation = component()
|
|
190
|
+
|
|
191
|
+
components.custom = tag()
|
|
192
|
+
end
|
|
193
|
+
components.custom_handler = component()
|
|
194
|
+
components.serdes = component()
|
|
195
|
+
components.global = component()
|
|
196
|
+
components.__alive_tracking__ = tag()
|
|
197
|
+
|
|
198
|
+
components.Shared = components.shared
|
|
199
|
+
components.Networked = components.networked
|
|
200
|
+
if RELATIONSHPIS then
|
|
201
|
+
components.Reliable = components.reliable
|
|
202
|
+
components.Unreliable = components.unreliable
|
|
203
|
+
components.Relation = components.relation
|
|
204
|
+
|
|
205
|
+
components.Custom = components.custom
|
|
206
|
+
end
|
|
207
|
+
components.CustomHandler = components.custom_handler
|
|
208
|
+
components.Serdes = components.serdes
|
|
209
|
+
components.Global = components.global
|
|
210
|
+
return components
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
function utils.add_component_names(components: types.Components, set: (component: Component, name: string) -> ())
|
|
214
|
+
set(components.shared, "replecs.shared")
|
|
215
|
+
if RELATIONSHPIS then
|
|
216
|
+
set(components.networked, "replecs.networked")
|
|
217
|
+
set(components.reliable, "replecs.reliable")
|
|
218
|
+
set(components.unreliable, "replecs.unreliable")
|
|
219
|
+
set(components.relation, "replecs.relation")
|
|
220
|
+
|
|
221
|
+
set(components.custom, "replecs.custom")
|
|
222
|
+
end
|
|
223
|
+
set(components.custom_handler, "replecs.custom_handler")
|
|
224
|
+
set(components.serdes, "replecs.serdes")
|
|
225
|
+
set(components.global, "replecs.global")
|
|
226
|
+
|
|
227
|
+
set(components.__alive_tracking__, "replecs.__alive_tracking__")
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
function utils.component_factory(world: World)
|
|
231
|
+
return function()
|
|
232
|
+
return common.world_component(world)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
function utils.tag_factory(world: World)
|
|
237
|
+
return function()
|
|
238
|
+
return common.world_tag(world)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
21
242
|
local cursor = {}
|
|
22
243
|
|
|
23
244
|
function cursor.new(): Cursor
|
|
@@ -34,6 +255,13 @@ function cursor.from(buf: buffer): Cursor
|
|
|
34
255
|
}
|
|
35
256
|
end
|
|
36
257
|
|
|
258
|
+
function cursor.from_offset(buf: buffer, offset: number): Cursor
|
|
259
|
+
return {
|
|
260
|
+
buffer = buf,
|
|
261
|
+
offset = offset,
|
|
262
|
+
}
|
|
263
|
+
end
|
|
264
|
+
|
|
37
265
|
function cursor.tryalloc(c: Cursor, bytes: number)
|
|
38
266
|
local buf = c.buffer
|
|
39
267
|
local offset = c.offset
|
|
@@ -64,10 +292,10 @@ function cursor.write_buffer(c: Cursor, buf: buffer, start: number?, count: numb
|
|
|
64
292
|
end
|
|
65
293
|
|
|
66
294
|
function cursor.print(c: Cursor)
|
|
67
|
-
local bytes = { string.byte(buffer.tostring(c.buffer), 1, -1) }
|
|
295
|
+
local bytes: { any } = { string.byte(buffer.tostring(c.buffer), 1, -1) }
|
|
68
296
|
local offset = 7
|
|
69
297
|
for i = 1, c.offset do
|
|
70
|
-
local byte = bytes[i]
|
|
298
|
+
local byte = bytes[i] :: number
|
|
71
299
|
local digits = if byte == 0 then 1 else math.ceil(math.log10(1 + byte))
|
|
72
300
|
offset += digits + 1
|
|
73
301
|
end
|
|
@@ -80,7 +308,7 @@ function cursor.print(c: Cursor)
|
|
|
80
308
|
bytes[c.offset + 1] = `[{bytes[c.offset + 1] :: number}]` :: any
|
|
81
309
|
|
|
82
310
|
if #bytes == 0 or c.offset == buffer.len(c.buffer) then
|
|
83
|
-
table.insert(bytes, " "
|
|
311
|
+
table.insert(bytes, " ")
|
|
84
312
|
end
|
|
85
313
|
|
|
86
314
|
return `Pos: {c.offset} / {buffer.len(c.buffer)}\nBuf: \{ {table.concat(bytes, " ")} \}`
|
|
@@ -214,17 +442,17 @@ function cursor.readi32(c: Cursor): number
|
|
|
214
442
|
end
|
|
215
443
|
|
|
216
444
|
function cursor.write_vlq(c: Cursor, value: number)
|
|
217
|
-
local x0 = value //
|
|
218
|
-
local x1 = value // 128
|
|
219
|
-
local x2 = value //
|
|
220
|
-
local x3 = value //
|
|
445
|
+
local x0 = value // 1% 128
|
|
446
|
+
local x1 = value // 128% 128
|
|
447
|
+
local x2 = value // 16384% 128
|
|
448
|
+
local x3 = value // 2097152% 128
|
|
221
449
|
|
|
222
450
|
if x3 ~= 0 then
|
|
223
451
|
cursor.tryalloc(c, 4)
|
|
224
|
-
cursor.writeu32(c, x0 *
|
|
452
|
+
cursor.writeu32(c, x0 * 16777216+ x1 * 65536+ x2 * 256 + x3 + 128)
|
|
225
453
|
elseif x2 ~= 0 then
|
|
226
454
|
cursor.tryalloc(c, 3)
|
|
227
|
-
cursor.writeu24(c, x0 *
|
|
455
|
+
cursor.writeu24(c, x0 * 65536+ x1 * 256 + x2 + 128)
|
|
228
456
|
elseif x1 ~= 0 then
|
|
229
457
|
cursor.tryalloc(c, 2)
|
|
230
458
|
cursor.writeu16(c, x0 * 256 + x1 + 128)
|
|
@@ -249,17 +477,17 @@ function cursor.read_vlq(c: Cursor): number
|
|
|
249
477
|
|
|
250
478
|
b = cursor.readu8(c)
|
|
251
479
|
if b >= 128 then
|
|
252
|
-
return x + (b - 128) *
|
|
253
|
-
|
|
254
|
-
x += b *
|
|
255
|
-
|
|
256
|
-
|
|
480
|
+
return x + (b - 128) * 16384
|
|
481
|
+
end
|
|
482
|
+
x += b * 16384
|
|
483
|
+
|
|
484
|
+
b = cursor.readu8(c)
|
|
257
485
|
if b >= 128 then
|
|
258
|
-
return x + (b - 128) *
|
|
259
|
-
|
|
260
|
-
x += b *
|
|
261
|
-
|
|
262
|
-
|
|
486
|
+
return x + (b - 128) * 2097152
|
|
487
|
+
end
|
|
488
|
+
x += b * 2097152
|
|
489
|
+
|
|
490
|
+
error "vlq length too large"
|
|
263
491
|
end
|
|
264
492
|
|
|
265
493
|
function cursor.close(c: Cursor): buffer
|
|
@@ -560,8 +788,8 @@ local BYTES = table.create(6)
|
|
|
560
788
|
function bitmask.tostring(self: Bitmask): string
|
|
561
789
|
local buf = self.buffer
|
|
562
790
|
|
|
563
|
-
local highest_entry = -1
|
|
564
|
-
|
|
791
|
+
local highest_entry = -1
|
|
792
|
+
for i = self.entries - 1, 0, -1 do
|
|
565
793
|
local value = buffer.readu32(buf, i * BYTES_PER_ENTRY)
|
|
566
794
|
if value ~= 0 then
|
|
567
795
|
highest_entry = i
|
|
@@ -589,164 +817,6 @@ utils.bitmask = {
|
|
|
589
817
|
from_set = bitmask.from_set,
|
|
590
818
|
}
|
|
591
819
|
|
|
592
|
-
function utils.create_shared_lookup<T>(lookup: { [string]: T }): common.SharedInfo<T>
|
|
593
|
-
local keys = {}
|
|
594
|
-
local indexes = {}
|
|
595
|
-
local members = {}
|
|
596
|
-
|
|
597
|
-
for name in lookup do
|
|
598
|
-
table.insert(keys, name)
|
|
599
|
-
end
|
|
600
|
-
table.sort(keys)
|
|
601
|
-
|
|
602
|
-
for index, name in keys do
|
|
603
|
-
local member = lookup[name]
|
|
604
|
-
members[member] = index
|
|
605
|
-
indexes[index] = member
|
|
606
|
-
end
|
|
607
|
-
|
|
608
|
-
return {
|
|
609
|
-
lookup = lookup,
|
|
610
|
-
keys = keys,
|
|
611
|
-
indexes = indexes,
|
|
612
|
-
members = members,
|
|
613
|
-
}
|
|
614
|
-
end
|
|
615
|
-
|
|
616
|
-
function utils.resolved_shared(
|
|
617
|
-
world: World,
|
|
618
|
-
components: common.Components,
|
|
619
|
-
registered_custom_ids: { [customid.CustomId]: boolean }
|
|
620
|
-
): common.Shared
|
|
621
|
-
local shared = {
|
|
622
|
-
serdes = {},
|
|
623
|
-
bytespan = {},
|
|
624
|
-
} :: common.Shared
|
|
625
|
-
|
|
626
|
-
local components_lookup: { [string]: jecs.Entity } = {
|
|
627
|
-
["jecs.ChildOf"] = CHILD_OF,
|
|
628
|
-
}
|
|
629
|
-
local custom_ids_lookup = {}
|
|
630
|
-
|
|
631
|
-
for component, name in world:query(ECS_NAME):with(components.shared):iter() do
|
|
632
|
-
components_lookup[name] = component
|
|
633
|
-
end
|
|
634
|
-
|
|
635
|
-
for custom in registered_custom_ids do
|
|
636
|
-
custom_ids_lookup[custom.identifier] = custom
|
|
637
|
-
end
|
|
638
|
-
|
|
639
|
-
for component, serdes in world:query(components.serdes):with(components.shared, ECS_NAME):iter() do
|
|
640
|
-
shared.serdes[component] = serdes
|
|
641
|
-
end
|
|
642
|
-
|
|
643
|
-
shared.components = utils.create_shared_lookup(components_lookup)
|
|
644
|
-
shared.custom_ids = utils.create_shared_lookup(custom_ids_lookup)
|
|
645
|
-
|
|
646
|
-
return shared
|
|
647
|
-
end
|
|
648
|
-
|
|
649
|
-
function utils.generate_handshake(world: World, shared: common.Shared): common.HandshakeInfo
|
|
650
|
-
local component_to_name: { [Entity]: string } = {}
|
|
651
|
-
local handshake: common.HandshakeInfo = {
|
|
652
|
-
components = {},
|
|
653
|
-
custom_ids = {},
|
|
654
|
-
serdes = {},
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
for component_name, component in shared.components.lookup do
|
|
658
|
-
handshake.components[component_name] = true
|
|
659
|
-
component_to_name[component] = component_name
|
|
660
|
-
end
|
|
661
|
-
|
|
662
|
-
for custom_id in shared.custom_ids.lookup do
|
|
663
|
-
handshake.custom_ids[custom_id] = true
|
|
664
|
-
end
|
|
665
|
-
|
|
666
|
-
for component, serdes in shared.serdes do
|
|
667
|
-
local name = component_to_name[component]
|
|
668
|
-
if not name then
|
|
669
|
-
utils.logwarn(`found serdes for component {utils.logcomponent(world, component)} was not shared`)
|
|
670
|
-
continue
|
|
671
|
-
end
|
|
672
|
-
|
|
673
|
-
handshake.serdes[name] = {
|
|
674
|
-
includes_variants = serdes.includes_variants,
|
|
675
|
-
bytespan = serdes.bytespan,
|
|
676
|
-
}
|
|
677
|
-
end
|
|
678
|
-
|
|
679
|
-
return handshake
|
|
680
|
-
end
|
|
681
|
-
|
|
682
|
-
function utils.verify_handshake(
|
|
683
|
-
world: World,
|
|
684
|
-
shared: common.Shared,
|
|
685
|
-
handshake: common.HandshakeInfo,
|
|
686
|
-
handshake_side: string,
|
|
687
|
-
verify_side: string
|
|
688
|
-
): (boolean, string?)
|
|
689
|
-
local component_to_name: { [Entity]: string } = {}
|
|
690
|
-
|
|
691
|
-
for component_name in handshake.components do
|
|
692
|
-
if not shared.components.lookup[component_name] then
|
|
693
|
-
return false, `missing shared component "{component_name}" in {verify_side}`
|
|
694
|
-
end
|
|
695
|
-
end
|
|
696
|
-
for component_name, component in shared.components.lookup do
|
|
697
|
-
if not handshake.components[component_name] then
|
|
698
|
-
return false, `missing shared component "{component_name}" in {handshake_side}`
|
|
699
|
-
end
|
|
700
|
-
component_to_name[component] = component_name
|
|
701
|
-
end
|
|
702
|
-
|
|
703
|
-
for custom_id in handshake.custom_ids do
|
|
704
|
-
if not shared.custom_ids.lookup[custom_id] then
|
|
705
|
-
return false, `missing custom id "{custom_id}" in {verify_side}`
|
|
706
|
-
end
|
|
707
|
-
end
|
|
708
|
-
for custom_id in shared.custom_ids.lookup do
|
|
709
|
-
if not handshake.custom_ids[custom_id] then
|
|
710
|
-
return false, `missing custom id "{custom_id}" in {handshake_side}`
|
|
711
|
-
end
|
|
712
|
-
end
|
|
713
|
-
|
|
714
|
-
for component_name, serdes_info in handshake.serdes do
|
|
715
|
-
local component = shared.components.lookup[component_name]
|
|
716
|
-
if not component then
|
|
717
|
-
warn(`{handshake_side} registered a serdes for "{component_name}" that {verify_side} doesn't have`)
|
|
718
|
-
continue
|
|
719
|
-
end
|
|
720
|
-
|
|
721
|
-
local serdes = shared.serdes[component]
|
|
722
|
-
if not serdes then
|
|
723
|
-
return false, `missing serdes for component "{component_name}" in {verify_side}`
|
|
724
|
-
end
|
|
725
|
-
|
|
726
|
-
if (serdes_info.includes_variants or false) ~= (serdes.includes_variants or false) then
|
|
727
|
-
return false,
|
|
728
|
-
`mismatched includes_variants for component "{component_name}": ({serdes_info.includes_variants} ~= {serdes.includes_variants})`
|
|
729
|
-
end
|
|
730
|
-
if serdes_info.bytespan ~= serdes.bytespan then
|
|
731
|
-
return false,
|
|
732
|
-
`mismatched bytespan for component "{component_name}": ({serdes_info.bytespan} ~= {serdes.bytespan})`
|
|
733
|
-
end
|
|
734
|
-
end
|
|
735
|
-
for component in shared.serdes do
|
|
736
|
-
local component_name = component_to_name[component]
|
|
737
|
-
if not component_name then
|
|
738
|
-
utils.logwarn(`found serdes for component {utils.logcomponent(world, component)} was not shared`)
|
|
739
|
-
continue
|
|
740
|
-
end
|
|
741
|
-
|
|
742
|
-
if not handshake.serdes[component_name] then
|
|
743
|
-
warn(`{verify_side} registered a serdes for "{component_name}" that {handshake_side} doesn't have`)
|
|
744
|
-
end
|
|
745
|
-
end
|
|
746
|
-
|
|
747
|
-
return true, nil
|
|
748
|
-
end
|
|
749
|
-
|
|
750
820
|
function utils.is_client_valid(player: any): boolean
|
|
751
821
|
if game then
|
|
752
822
|
if typeof(player) == "Instance" then
|
|
@@ -797,15 +867,4 @@ function utils.checkbit(mask: number, bit: number)
|
|
|
797
867
|
return bit32.band(mask, bit32.lshift(1, bit)) ~= 0
|
|
798
868
|
end
|
|
799
869
|
|
|
800
|
-
function utils.logerror(...: string): never
|
|
801
|
-
error("REPLECS ERROR - " .. table.concat({ ... }, " "))
|
|
802
|
-
end
|
|
803
|
-
function utils.logwarn(...: string)
|
|
804
|
-
warn("REPLECS WARN - " .. table.concat({ ... }, " "))
|
|
805
|
-
end
|
|
806
|
-
|
|
807
|
-
function utils.logcomponent(world: World, component: Entity)
|
|
808
|
-
return ` name: {world:get(component, ECS_NAME) or "(no name)"}, id: {component}`
|
|
809
|
-
end
|
|
810
|
-
|
|
811
870
|
return utils
|
package/out/replecs/ver.luau
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
return ""
|
|
1
|
+
return "v0.2.3"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"program":{"fileNames":["../node_modules/.pnpm/@rbxts+jecs@0.9.0/node_modules/@rbxts/jecs/jecs.d.ts","../src/jecs.ts","../src/replecs/index.d.ts","../src/index.ts","../node_modules/.pnpm/@rbxts+types@1.0.906/node_modules/@rbxts/types/include/generated/enums.d.ts","../node_modules/.pnpm/@rbxts+types@1.0.906/node_modules/@rbxts/types/include/generated/none.d.ts","../node_modules/.pnpm/@rbxts+types@1.0.906/node_modules/@rbxts/types/include/lua.d.ts","../node_modules/.pnpm/@rbxts+types@1.0.906/node_modules/@rbxts/types/include/macro_math.d.ts","../node_modules/.pnpm/@rbxts+types@1.0.906/node_modules/@rbxts/types/include/roblox.d.ts","../node_modules/.pnpm/@rbxts+compiler-types@2.3.0-types.2/node_modules/@rbxts/compiler-types/types/array.d.ts","../node_modules/.pnpm/@rbxts+compiler-types@2.3.0-types.2/node_modules/@rbxts/compiler-types/types/callmacros.d.ts","../node_modules/.pnpm/@rbxts+compiler-types@2.3.0-types.2/node_modules/@rbxts/compiler-types/types/iterable.d.ts","../node_modules/.pnpm/@rbxts+compiler-types@2.3.0-types.2/node_modules/@rbxts/compiler-types/types/map.d.ts","../node_modules/.pnpm/@rbxts+compiler-types@2.3.0-types.2/node_modules/@rbxts/compiler-types/types/promise.d.ts","../node_modules/.pnpm/@rbxts+compiler-types@2.3.0-types.2/node_modules/@rbxts/compiler-types/types/set.d.ts","../node_modules/.pnpm/@rbxts+compiler-types@2.3.0-types.2/node_modules/@rbxts/compiler-types/types/string.d.ts","../node_modules/.pnpm/@rbxts+compiler-types@2.3.0-types.2/node_modules/@rbxts/compiler-types/types/symbol.d.ts","../node_modules/.pnpm/@rbxts+compiler-types@2.3.0-types.2/node_modules/@rbxts/compiler-types/types/typeutils.d.ts","../node_modules/.pnpm/@rbxts+compiler-types@2.3.0-types.2/node_modules/@rbxts/compiler-types/types/eslintignore.d.ts","../node_modules/.pnpm/@rbxts+compiler-types@2.3.0-types.2/node_modules/@rbxts/compiler-types/types/core.d.ts"],"fileInfos":[{"version":"53514b26cc40aa5044286cab894f8605c209df71575c34962082a0465aae08eb","signature":false},{"version":"da09e64284f2a1d722f7ca4691112b118338772e1b4912d3ade1d4e59bf37e23","signature":false},{"version":"8f768612c8b1e4c817aba95b5cf990df298e50fabbee0e08889646c438888a68","signature":false},{"version":"f5d2f7767ffe11849eab647370f2b04547612804dc0505300d7e7f98aea81447","signature":false},{"version":"ede7031d81a14dcfc438a295417ca20e4d5cc61bfa94a6d6365abf19022c5c99","signature":false,"affectsGlobalScope":true},{"version":"7ec7f5ca60877967bc3e75caa8f79ac4ea742a2e3e66b028f46a363b98fae4c1","signature":false,"affectsGlobalScope":true},{"version":"37bb82039d3d849fecd25abff22fd3eb49be438d321d6e2647fc174020168832","signature":false,"affectsGlobalScope":true},{"version":"3d53bb0b3bebf42415ee836dc0036b62fd635fbf763bade7105a673a1dff379a","signature":false,"affectsGlobalScope":true},{"version":"4896acd074161b21207dfce96db5d8487695418eb494a6c608f330e6781ae223","signature":false,"affectsGlobalScope":true},{"version":"6457d2a2e58b705b90031987181895c6009d1b36b0cb49f34f8e71114b5f6c58","signature":false,"affectsGlobalScope":true},{"version":"e524700086557f08b882e68d438dbeebb7d2d4080c71eec45dc26f46398bf5ee","signature":false,"affectsGlobalScope":true},{"version":"3f724f88079047762d020ede77d9f3a053f6eaa0f41230e2c68df62dca2c5fd2","signature":false,"affectsGlobalScope":true},{"version":"aa74592016ddb5ba50c9089516fce2c6ffd3b148ecd7cee51e196d6f459551c0","signature":false,"affectsGlobalScope":true},{"version":"c2c86dc2a89e19b34cd718a5499cd732e48385090151e68a5ecac26e9a4d97fa","signature":false,"affectsGlobalScope":true},{"version":"b8c099b5a7944f89db48ab3aa3debb9870aff999bfb29360ba56cda8801c3d29","signature":false,"affectsGlobalScope":true},{"version":"63521eb393155dc5991ab3d0ec8be19fc39f4da476476d5ae1573f6adffbf85e","signature":false,"affectsGlobalScope":true},{"version":"3684d1f40ecc50beef9d389d57995ca30ff0140df2468f26a7a55239026358fb","signature":false,"affectsGlobalScope":true},{"version":"048a7a2651cd6ab24d77f3374012fe0c7d01142c7857d0ac104cc9f65e8753b3","signature":false,"affectsGlobalScope":true},{"version":"25b9dfcbc1799ec90e5367de64939f17bd524859f72554658db12e1d32ed29c1","signature":false,"affectsGlobalScope":true},{"version":"e70206829fdad27d9ae67d9c629a48c55418e508671b44c222f0701b3c73c066","signature":false,"affectsGlobalScope":true}],"root":[[2,4]],"options":{"allowSyntheticDefaultImports":true,"declaration":true,"downlevelIteration":true,"experimentalDecorators":true,"jsx":2,"module":1,"outDir":"./","rootDir":"../src","strict":true,"target":99,"tsBuildInfoFile":"./tsconfig.tsbuildinfo"},"fileIdsList":[[9],[9,10,11,12,13,14,15,16,17,18,19],[5,9],[6,20],[5,6,7,8,20],[2,3],[1]],"referencedMap":[[10,1],[11,1],[20,2],[19,1],[12,1],[13,1],[14,1],[15,1],[16,1],[17,1],[18,1],[5,1],[6,3],[7,4],[9,5],[4,6],[2,7],[3,7]],"semanticDiagnosticsPerFile":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]},"version":"5.5.3"}
|