@rbxts/replecs 0.2.3 → 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 +521 -384
- 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
package/out/replecs/client.luau
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
--!native
|
|
2
1
|
--!optimize 2
|
|
2
|
+
--!native
|
|
3
3
|
|
|
4
|
-
local
|
|
5
|
-
local
|
|
6
|
-
local customid = require
|
|
7
|
-
local utils = require
|
|
4
|
+
local common = require (script.Parent:WaitForChild('common'))
|
|
5
|
+
local types = require (script.Parent:WaitForChild('types'))
|
|
6
|
+
local customid = require (script.Parent:WaitForChild('customid'))
|
|
7
|
+
local utils = require (script.Parent:WaitForChild('utils'))
|
|
8
8
|
|
|
9
9
|
local cursor = utils.cursor
|
|
10
10
|
|
|
11
11
|
type Cursor = utils.Cursor
|
|
12
12
|
type CustomId = customid.CustomId
|
|
13
13
|
|
|
14
|
-
type Entity
|
|
15
|
-
type
|
|
16
|
-
type World =
|
|
14
|
+
type Entity = common.Entity
|
|
15
|
+
type Component<T = any> = common.Component<T>
|
|
16
|
+
type World = common.World
|
|
17
17
|
|
|
18
18
|
type Array<T> = { T }
|
|
19
19
|
type Map<K, V> = { [K]: V }
|
|
@@ -21,33 +21,46 @@ type Set<T> = { [T]: boolean }
|
|
|
21
21
|
type Disconnect = () -> ()
|
|
22
22
|
|
|
23
23
|
type CommandBuffer = {
|
|
24
|
-
tags:
|
|
25
|
-
components:
|
|
26
|
-
unreliable_components:
|
|
27
|
-
remove:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
tags: Set<Component>,
|
|
25
|
+
components: Map<Component, { value: any }>,
|
|
26
|
+
unreliable_components: Map<Component, { value: any }>,
|
|
27
|
+
remove: Set<Component>,
|
|
28
|
+
|
|
29
|
+
pairs_add: { [Component]: Set<Entity> },
|
|
30
|
+
pairs_set: { [Component]: Map<Entity, { value: any }> },
|
|
31
|
+
pairs_unprocessed: {
|
|
32
|
+
[Component]: Map<Entity, {
|
|
33
|
+
cursor: Cursor,
|
|
34
|
+
variants: { any }?,
|
|
35
|
+
processed_value: { value: any }?,
|
|
36
|
+
}>,
|
|
37
|
+
},
|
|
38
|
+
pairs_remove: { [Component]: Set<Entity> },
|
|
39
|
+
relations_clear: Set<Component>,
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
type HookMethod =
|
|
35
43
|
& ((
|
|
36
44
|
self: Client,
|
|
37
45
|
action: "changed",
|
|
38
|
-
relation:
|
|
39
|
-
callback: (entity: Entity, id:
|
|
46
|
+
relation: Component,
|
|
47
|
+
callback: (entity: Entity, id: Component, value: any) -> ()
|
|
40
48
|
) -> Disconnect)
|
|
41
|
-
& ((
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
& ((
|
|
50
|
+
self: Client,
|
|
51
|
+
action: "removed",
|
|
52
|
+
relation: Component,
|
|
53
|
+
callback: (entity: Entity, id: Component) -> ()
|
|
54
|
+
) -> Disconnect)
|
|
55
|
+
& ((self: Client, action: "deleted", entity: Entity, callback: (entity: Entity) -> ()) -> Disconnect
|
|
56
|
+
)
|
|
44
57
|
type ChangedHooksEntry = {
|
|
45
58
|
overrides: boolean,
|
|
46
|
-
callbacks: Array<(entity: Entity, id:
|
|
59
|
+
callbacks: Array<(entity: Entity, id: Component, value: any) -> ()>,
|
|
47
60
|
}
|
|
48
61
|
type RemovedHooksEntry = {
|
|
49
62
|
overrides: boolean,
|
|
50
|
-
callbacks: Array<(entity: Entity, id:
|
|
63
|
+
callbacks: Array<(entity: Entity, id: Component) -> ()>,
|
|
51
64
|
}
|
|
52
65
|
type DeletedHookEntry = {
|
|
53
66
|
overrides: boolean,
|
|
@@ -56,7 +69,12 @@ type DeletedHookEntry = {
|
|
|
56
69
|
|
|
57
70
|
type CustomIdMap = { [Entity]: CustomId | Entity }
|
|
58
71
|
|
|
59
|
-
export type
|
|
72
|
+
export type ClientImp = {
|
|
73
|
+
set_serdes: <T>(client: Client, id: Component<T>, serdes: types.Serdes<T>) -> (),
|
|
74
|
+
remove_serdes: (client: Client, id: Component) -> (),
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export type Client = ClientImp & {
|
|
60
78
|
world: World,
|
|
61
79
|
inited: boolean?,
|
|
62
80
|
|
|
@@ -65,16 +83,17 @@ export type Client = {
|
|
|
65
83
|
|
|
66
84
|
is_shared_dirty: boolean,
|
|
67
85
|
requires_shared_lookup: { Entity },
|
|
68
|
-
components:
|
|
69
|
-
shared:
|
|
86
|
+
components: types.Components,
|
|
87
|
+
shared: types.Shared,
|
|
70
88
|
global_handler: ((id: number) -> Entity)?,
|
|
71
89
|
server_ids: { [number]: Entity },
|
|
72
90
|
client_ids: { [Entity]: number },
|
|
73
|
-
ordered_creation: boolean,
|
|
74
|
-
registered_custom_ids: { [CustomId]: boolean },
|
|
75
91
|
command_buffers: { [Entity]: CommandBuffer }?,
|
|
76
92
|
command_buffers_active: boolean,
|
|
77
93
|
|
|
94
|
+
registered_custom_ids: { [CustomId]: boolean },
|
|
95
|
+
component_serdes: Map<Component, types.Serdes>,
|
|
96
|
+
|
|
78
97
|
init: (self: Client, world: World?) -> (),
|
|
79
98
|
destroy: (self: Client) -> (),
|
|
80
99
|
handle_global: (self: Client, handler: (id: number) -> Entity) -> (),
|
|
@@ -84,7 +103,6 @@ export type Client = {
|
|
|
84
103
|
register_entity: (self: Client, entity: Entity, server_entity: number) -> (),
|
|
85
104
|
unregister_entity: (self: Client, entity: Entity) -> (),
|
|
86
105
|
|
|
87
|
-
hooks: common.WorldHooks,
|
|
88
106
|
hooked: Array<() -> ()>,
|
|
89
107
|
|
|
90
108
|
after_replication: (self: Client, callback: () -> ()) -> (),
|
|
@@ -94,20 +112,23 @@ export type Client = {
|
|
|
94
112
|
addition_hooks: Array<(entity: Entity) -> ()>,
|
|
95
113
|
network_hooks: {
|
|
96
114
|
deleted: { [Entity]: DeletedHookEntry },
|
|
97
|
-
changed: { [
|
|
98
|
-
removed: { [
|
|
115
|
+
changed: { [Component]: ChangedHooksEntry },
|
|
116
|
+
removed: { [Component]: RemovedHooksEntry },
|
|
99
117
|
},
|
|
100
118
|
|
|
101
119
|
encode_component: (self: Client, component: Entity) -> number,
|
|
102
120
|
decode_component: (self: Client, component: number) -> Entity,
|
|
121
|
+
get_shared_count: (self: Client) -> number,
|
|
122
|
+
|
|
103
123
|
register_custom_id: (self: Client, custom_id: CustomId) -> (),
|
|
104
124
|
|
|
125
|
+
apply_full: (self: Client, buf: buffer, all_variants: { { any } }?) -> (),
|
|
126
|
+
apply_entity: (self: Client, buf: buffer, all_variants: { { any } }?) -> (),
|
|
105
127
|
apply_updates: (self: Client, buf: buffer, all_variants: { { any } }?) -> (),
|
|
106
128
|
apply_unreliable: (self: Client, buf: buffer, all_variants: { { any } }?) -> (),
|
|
107
|
-
apply_full: (self: Client, buf: buffer, all_variants: { { any } }?) -> (),
|
|
108
129
|
|
|
109
|
-
generate_handshake: (self: Client) ->
|
|
110
|
-
verify_handshake: (self: Client, handshake:
|
|
130
|
+
generate_handshake: (self: Client) -> types.HandshakeInfo,
|
|
131
|
+
verify_handshake: (self: Client, handshake: types.HandshakeInfo) -> (boolean, string?),
|
|
111
132
|
}
|
|
112
133
|
|
|
113
134
|
local client_replicator = {}
|
|
@@ -123,23 +144,41 @@ local ENTITY_ID_TYPES = {
|
|
|
123
144
|
}
|
|
124
145
|
local PACKET_TYPES = {
|
|
125
146
|
full = 1,
|
|
126
|
-
|
|
127
|
-
|
|
147
|
+
entity = 2,
|
|
148
|
+
updates = 3,
|
|
149
|
+
unreliable = 4,
|
|
128
150
|
}
|
|
129
151
|
|
|
130
|
-
local
|
|
131
|
-
|
|
132
|
-
local
|
|
133
|
-
|
|
152
|
+
local ECS_NAME = common.ecs_name
|
|
153
|
+
local ECS_WILDCARD = common.wildcard
|
|
154
|
+
local PAIR = common.pair
|
|
155
|
+
local ITERATE_ALL_RELATIONS = common.iterate_all_relations
|
|
156
|
+
local WORLD_ENTITY = common.world_entity
|
|
157
|
+
local WORLD_ADD = common.world_add
|
|
158
|
+
local WORLD_SET = common.world_set
|
|
159
|
+
local WORLD_REMOVE = common.world_remove
|
|
160
|
+
local WORLD_GET = common.world_get
|
|
161
|
+
local WORLD_DELETE = common.world_delete
|
|
162
|
+
|
|
163
|
+
local HOOK_ADDED = common.hook_added
|
|
164
|
+
local HOOK_CHANGED = common.hook_changed
|
|
165
|
+
local HOOK_REMOVED = common.hook_removed
|
|
166
|
+
|
|
167
|
+
local function QUERY_CURRENT_COMPONENTS(client: Client)
|
|
168
|
+
for component, serdes in client.world:query(client.components.serdes):iter() do
|
|
169
|
+
client.component_serdes[component] = serdes
|
|
170
|
+
end
|
|
134
171
|
end
|
|
135
172
|
|
|
136
173
|
local function get_or_create_entity(client: Client, server_id: number): Entity
|
|
174
|
+
local world = client.world
|
|
175
|
+
|
|
137
176
|
local server_entity = client.server_ids[server_id]
|
|
138
177
|
if server_entity then
|
|
139
178
|
return server_entity
|
|
140
179
|
else
|
|
141
|
-
local entity =
|
|
142
|
-
|
|
180
|
+
local entity = WORLD_ENTITY(world)
|
|
181
|
+
WORLD_ADD(world, entity, client.components.__alive_tracking__)
|
|
143
182
|
|
|
144
183
|
client.server_ids[server_id] = entity
|
|
145
184
|
client.client_ids[entity] = server_id
|
|
@@ -152,11 +191,11 @@ local function get_or_create_entity(client: Client, server_id: number): Entity
|
|
|
152
191
|
end
|
|
153
192
|
end
|
|
154
193
|
|
|
155
|
-
local function
|
|
194
|
+
local function get_or_create_command_buffer(client: Client, entity: Entity): CommandBuffer
|
|
156
195
|
local command_buffers = client.command_buffers
|
|
157
196
|
|
|
158
197
|
if not command_buffers then
|
|
159
|
-
error "attempted to use a command buffer without
|
|
198
|
+
error "attempted to use a command buffer without being active. (this should never happen)"
|
|
160
199
|
end
|
|
161
200
|
|
|
162
201
|
local command_buffer = command_buffers[entity :: any]
|
|
@@ -166,10 +205,11 @@ local function get_command_buffer(client: Client, entity: Entity): CommandBuffer
|
|
|
166
205
|
components = {},
|
|
167
206
|
unreliable_components = {},
|
|
168
207
|
remove = {},
|
|
169
|
-
|
|
170
|
-
|
|
208
|
+
pairs_add = {},
|
|
209
|
+
pairs_set = {},
|
|
210
|
+
pairs_unprocessed = {},
|
|
171
211
|
pairs_remove = {},
|
|
172
|
-
|
|
212
|
+
relations_clear = {},
|
|
173
213
|
}
|
|
174
214
|
command_buffers[entity :: any] = command_buffer
|
|
175
215
|
end
|
|
@@ -179,41 +219,41 @@ end
|
|
|
179
219
|
function client_replicator.entity_set(
|
|
180
220
|
client: Client,
|
|
181
221
|
entity: Entity,
|
|
182
|
-
id:
|
|
222
|
+
id: Component,
|
|
183
223
|
value: any,
|
|
184
224
|
changed_hooks: ChangedHooksEntry?
|
|
185
225
|
)
|
|
186
226
|
if client.command_buffers_active then
|
|
187
|
-
local command_buffer =
|
|
227
|
+
local command_buffer = get_or_create_command_buffer(client, entity)
|
|
188
228
|
command_buffer.components[id] = { value = value }
|
|
189
229
|
else
|
|
190
230
|
if changed_hooks then
|
|
191
231
|
if not changed_hooks.overrides then
|
|
192
|
-
client.world
|
|
232
|
+
WORLD_SET(client.world, entity, id, value)
|
|
193
233
|
end
|
|
194
234
|
for _, callback in changed_hooks.callbacks do
|
|
195
235
|
callback(entity, id, value)
|
|
196
236
|
end
|
|
197
237
|
else
|
|
198
|
-
client.world
|
|
238
|
+
WORLD_SET(client.world, entity, id, value)
|
|
199
239
|
end
|
|
200
240
|
end
|
|
201
241
|
end
|
|
202
242
|
|
|
203
243
|
function client_replicator.entity_add(client: Client, entity: Entity, tag: Entity, changed_hooks: ChangedHooksEntry?)
|
|
204
244
|
if client.command_buffers_active then
|
|
205
|
-
local command_buffer =
|
|
245
|
+
local command_buffer = get_or_create_command_buffer(client, entity)
|
|
206
246
|
command_buffer.tags[tag] = true
|
|
207
247
|
else
|
|
208
248
|
if changed_hooks then
|
|
209
249
|
if not changed_hooks.overrides then
|
|
210
|
-
client.world
|
|
250
|
+
WORLD_ADD(client.world, entity, tag)
|
|
211
251
|
end
|
|
212
252
|
for _, callback in changed_hooks.callbacks do
|
|
213
253
|
callback(entity, tag)
|
|
214
254
|
end
|
|
215
255
|
else
|
|
216
|
-
client.world
|
|
256
|
+
WORLD_ADD(client.world, entity, tag)
|
|
217
257
|
end
|
|
218
258
|
end
|
|
219
259
|
end
|
|
@@ -226,7 +266,7 @@ function client_replicator.entity_set_unreliable(
|
|
|
226
266
|
changed_hooks: ChangedHooksEntry?
|
|
227
267
|
)
|
|
228
268
|
if client.command_buffers_active then
|
|
229
|
-
local command_buffer =
|
|
269
|
+
local command_buffer = get_or_create_command_buffer(client, entity)
|
|
230
270
|
command_buffer.unreliable_components[id] = { value = value }
|
|
231
271
|
else
|
|
232
272
|
client_replicator.entity_set(client, entity, id, value, changed_hooks)
|
|
@@ -242,13 +282,13 @@ function client_replicator.entity_set_pair(
|
|
|
242
282
|
changed_hooks: ChangedHooksEntry?
|
|
243
283
|
)
|
|
244
284
|
if client.command_buffers_active then
|
|
245
|
-
local command_buffer =
|
|
246
|
-
local pair_relation = command_buffer.
|
|
285
|
+
local command_buffer = get_or_create_command_buffer(client, entity)
|
|
286
|
+
local pair_relation = command_buffer.pairs_set[relation]
|
|
247
287
|
|
|
248
288
|
if pair_relation then
|
|
249
289
|
pair_relation[target] = { value = value }
|
|
250
290
|
else
|
|
251
|
-
command_buffer.
|
|
291
|
+
command_buffer.pairs_set[relation] = { [target] = { value = value } }
|
|
252
292
|
end
|
|
253
293
|
else
|
|
254
294
|
client_replicator.entity_set(client, entity, PAIR(relation, target), value, changed_hooks)
|
|
@@ -263,22 +303,56 @@ function client_replicator.entity_add_pair(
|
|
|
263
303
|
changed_hooks: ChangedHooksEntry?
|
|
264
304
|
)
|
|
265
305
|
if client.command_buffers_active then
|
|
266
|
-
local command_buffer =
|
|
267
|
-
local pair_relation = command_buffer.
|
|
306
|
+
local command_buffer = get_or_create_command_buffer(client, entity)
|
|
307
|
+
local pair_relation = command_buffer.pairs_add[relation]
|
|
268
308
|
|
|
269
309
|
if pair_relation then
|
|
270
310
|
pair_relation[target] = true
|
|
271
311
|
else
|
|
272
|
-
command_buffer.
|
|
312
|
+
command_buffer.pairs_add[relation] = { [target] = true }
|
|
273
313
|
end
|
|
274
314
|
else
|
|
275
315
|
client_replicator.entity_add(client, entity, PAIR(relation, target), changed_hooks)
|
|
276
316
|
end
|
|
277
317
|
end
|
|
278
318
|
|
|
319
|
+
function client_replicator.entity_set_postponed_pair(
|
|
320
|
+
client: Client,
|
|
321
|
+
entity: Entity,
|
|
322
|
+
relation: Component,
|
|
323
|
+
target: Entity,
|
|
324
|
+
c: Cursor,
|
|
325
|
+
variants: { any }?
|
|
326
|
+
): any
|
|
327
|
+
if client.command_buffers_active then
|
|
328
|
+
local commmand_buffer = get_or_create_command_buffer(client, entity)
|
|
329
|
+
local pairs_unprocessed = commmand_buffer.pairs_unprocessed
|
|
330
|
+
local pair_relation = pairs_unprocessed[relation]
|
|
331
|
+
if pair_relation then
|
|
332
|
+
pair_relation[target] = {
|
|
333
|
+
cursor = c,
|
|
334
|
+
variants = variants,
|
|
335
|
+
}
|
|
336
|
+
else
|
|
337
|
+
pairs_unprocessed[relation] = {
|
|
338
|
+
[target] = {
|
|
339
|
+
cursor = c,
|
|
340
|
+
variants = variants,
|
|
341
|
+
},
|
|
342
|
+
}
|
|
343
|
+
end
|
|
344
|
+
return nil
|
|
345
|
+
else
|
|
346
|
+
local pair_id, value = client_replicator.read_pair_value(client, relation, target, c, variants)
|
|
347
|
+
-- TODO: respect hooks
|
|
348
|
+
WORLD_SET(client.world, entity, pair_id, value)
|
|
349
|
+
return value
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
279
353
|
function client_replicator.entity_remove(client: Client, entity: Entity, id: Entity, removed_hooks: RemovedHooksEntry?)
|
|
280
354
|
if client.command_buffers_active then
|
|
281
|
-
local command_buffer =
|
|
355
|
+
local command_buffer = get_or_create_command_buffer(client, entity)
|
|
282
356
|
command_buffer.remove[id] = true
|
|
283
357
|
else
|
|
284
358
|
if removed_hooks then
|
|
@@ -286,10 +360,10 @@ function client_replicator.entity_remove(client: Client, entity: Entity, id: Ent
|
|
|
286
360
|
callback(entity, id)
|
|
287
361
|
end
|
|
288
362
|
if not removed_hooks.overrides then
|
|
289
|
-
client.world
|
|
363
|
+
WORLD_REMOVE(client.world, entity, id)
|
|
290
364
|
end
|
|
291
365
|
else
|
|
292
|
-
client.world
|
|
366
|
+
WORLD_REMOVE(client.world, entity, id)
|
|
293
367
|
end
|
|
294
368
|
end
|
|
295
369
|
end
|
|
@@ -302,7 +376,7 @@ function client_replicator.entity_remove_pair(
|
|
|
302
376
|
removed_hooks: RemovedHooksEntry?
|
|
303
377
|
)
|
|
304
378
|
if client.command_buffers_active then
|
|
305
|
-
local command_buffer =
|
|
379
|
+
local command_buffer = get_or_create_command_buffer(client, entity)
|
|
306
380
|
local pair_relation = command_buffer.pairs_remove[relation]
|
|
307
381
|
|
|
308
382
|
if pair_relation then
|
|
@@ -315,97 +389,91 @@ function client_replicator.entity_remove_pair(
|
|
|
315
389
|
end
|
|
316
390
|
end
|
|
317
391
|
|
|
318
|
-
function client_replicator.
|
|
392
|
+
function client_replicator.entity_clear_relation(
|
|
319
393
|
client: Client,
|
|
320
394
|
entity: Entity,
|
|
321
395
|
relation: Entity,
|
|
322
396
|
removed_hooks: RemovedHooksEntry?
|
|
323
397
|
)
|
|
324
398
|
if client.command_buffers_active then
|
|
325
|
-
local command_buffer =
|
|
326
|
-
command_buffer.
|
|
399
|
+
local command_buffer = get_or_create_command_buffer(client, entity)
|
|
400
|
+
command_buffer.relations_clear[relation] = true
|
|
327
401
|
else
|
|
328
402
|
local world = client.world
|
|
329
|
-
local entity_index = jecs.entity_index_try_get_fast(world.entity_index :: any, entity :: any)
|
|
330
|
-
if not entity_index then
|
|
331
|
-
return
|
|
332
|
-
end
|
|
333
|
-
local archetype = entity_index.archetype
|
|
334
|
-
|
|
335
|
-
local wildcard = PAIR(relation, WILDCARD) :: any
|
|
336
|
-
local idr = world.component_index[wildcard]
|
|
337
|
-
if not idr then
|
|
338
|
-
return
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
local archetype_id = archetype.id
|
|
342
|
-
local count = idr.counts[archetype_id]
|
|
343
|
-
if not count then
|
|
344
|
-
return
|
|
345
|
-
end
|
|
346
|
-
|
|
347
|
-
local start = idr.records[archetype_id]
|
|
348
|
-
if not start then
|
|
349
|
-
return
|
|
350
|
-
end
|
|
351
|
-
|
|
352
403
|
if removed_hooks then
|
|
353
|
-
|
|
354
|
-
local pair = archetype.types[i]
|
|
404
|
+
ITERATE_ALL_RELATIONS(world, entity, relation, function(pair)
|
|
355
405
|
for _, callback in removed_hooks.callbacks do
|
|
356
406
|
callback(entity, pair)
|
|
357
407
|
end
|
|
358
408
|
if not removed_hooks.overrides then
|
|
359
|
-
world
|
|
409
|
+
WORLD_REMOVE(world, entity, pair)
|
|
360
410
|
end
|
|
361
|
-
end
|
|
411
|
+
end)
|
|
362
412
|
else
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
end
|
|
413
|
+
ITERATE_ALL_RELATIONS(world, entity, relation, function(pair)
|
|
414
|
+
WORLD_REMOVE(world, entity, pair)
|
|
415
|
+
end)
|
|
367
416
|
end
|
|
368
417
|
end
|
|
369
418
|
end
|
|
370
419
|
|
|
371
|
-
function
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
420
|
+
local function read_variant_value(c: Cursor, serdes: types.Serdes?, variants: { any }?)
|
|
421
|
+
if serdes then
|
|
422
|
+
local bytespan = serdes.bytespan or cursor.read_vlq(c)
|
|
423
|
+
|
|
424
|
+
local appended = cursor.read_buffer(c, bytespan)
|
|
425
|
+
local serdes_variants: { any }?
|
|
426
|
+
|
|
427
|
+
if serdes.includes_variants then
|
|
428
|
+
local start_variant = cursor.read_vlq(c)
|
|
429
|
+
|
|
430
|
+
if start_variant > 0 then
|
|
431
|
+
local size = cursor.read_vlq(c)
|
|
432
|
+
serdes_variants = table.move(variants :: { any }, start_variant, start_variant + size - 1, 1, {})
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
local output = serdes.deserialize(appended, serdes_variants :: any)
|
|
437
|
+
return output
|
|
438
|
+
else
|
|
439
|
+
local variant_id = cursor.read_vlq(c)
|
|
440
|
+
if variant_id == 0 then
|
|
441
|
+
return nil
|
|
442
|
+
end
|
|
443
|
+
local value = (variants :: { any })[variant_id]
|
|
444
|
+
return value
|
|
384
445
|
end
|
|
385
|
-
return component
|
|
386
446
|
end
|
|
387
447
|
|
|
388
|
-
function client_replicator.
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
448
|
+
function client_replicator.read_pair_value(
|
|
449
|
+
client: Client,
|
|
450
|
+
relation: Component,
|
|
451
|
+
target: Entity,
|
|
452
|
+
c: Cursor,
|
|
453
|
+
variants: { any }?
|
|
454
|
+
)
|
|
455
|
+
local pair_id = PAIR(relation, target)
|
|
456
|
+
local pair_wildcard = PAIR(relation, ECS_WILDCARD)
|
|
457
|
+
local serdes = client.component_serdes[pair_id] or client.component_serdes[pair_wildcard]
|
|
458
|
+
local value = read_variant_value(c, serdes, variants)
|
|
459
|
+
return pair_id, value
|
|
397
460
|
end
|
|
398
461
|
|
|
399
|
-
function client_replicator.read_component_value(
|
|
462
|
+
function client_replicator.read_component_value(
|
|
463
|
+
client: Client,
|
|
464
|
+
component: Component,
|
|
465
|
+
c: Cursor,
|
|
466
|
+
variants: { any }?
|
|
467
|
+
): any
|
|
400
468
|
local serdes = client.shared.serdes[component]
|
|
401
469
|
|
|
402
470
|
if serdes then
|
|
403
471
|
local bytespan = serdes.bytespan or cursor.read_vlq(c)
|
|
404
472
|
|
|
405
473
|
local appended = cursor.read_buffer(c, bytespan)
|
|
406
|
-
local serdes_variants: { any }?
|
|
407
|
-
|
|
408
|
-
|
|
474
|
+
local serdes_variants: { any }?
|
|
475
|
+
|
|
476
|
+
if serdes.includes_variants then
|
|
409
477
|
local start_variant = cursor.read_vlq(c)
|
|
410
478
|
|
|
411
479
|
if start_variant > 0 then
|
|
@@ -414,7 +482,7 @@ function client_replicator.read_component_value(client: Client, component: Entit
|
|
|
414
482
|
end
|
|
415
483
|
end
|
|
416
484
|
|
|
417
|
-
local output = serdes.deserialize(appended, serdes_variants)
|
|
485
|
+
local output = serdes.deserialize(appended, serdes_variants :: any)
|
|
418
486
|
return output
|
|
419
487
|
else
|
|
420
488
|
local variant_id = cursor.read_vlq(c)
|
|
@@ -426,10 +494,15 @@ function client_replicator.read_component_value(client: Client, component: Entit
|
|
|
426
494
|
end
|
|
427
495
|
end
|
|
428
496
|
|
|
429
|
-
function client_replicator.
|
|
430
|
-
local
|
|
431
|
-
local
|
|
432
|
-
|
|
497
|
+
function client_replicator.read_component_id(client: Client, c: Cursor): Entity
|
|
498
|
+
local shared_components = client.shared.components
|
|
499
|
+
local shared_id = cursor.read_span(c, #shared_components.keys)
|
|
500
|
+
local component = shared_components.indexes[shared_id]
|
|
501
|
+
if not component then
|
|
502
|
+
print("NON SHARED COMPONENT", shared_id, client.shared.components)
|
|
503
|
+
error "received a non shared component"
|
|
504
|
+
end
|
|
505
|
+
return component
|
|
433
506
|
end
|
|
434
507
|
|
|
435
508
|
function client_replicator.resolve_global(client: Client, global_id: number): Entity
|
|
@@ -461,6 +534,14 @@ function client_replicator.read_entity_id(client: Client, c: Cursor): (Entity?,
|
|
|
461
534
|
end
|
|
462
535
|
end
|
|
463
536
|
|
|
537
|
+
local function read_vlq_bitmask(c: Cursor, mask: number, bit: number): number
|
|
538
|
+
if utils.checkbit(mask, bit) then
|
|
539
|
+
return cursor.read_vlq(c)
|
|
540
|
+
else
|
|
541
|
+
return 0
|
|
542
|
+
end
|
|
543
|
+
end
|
|
544
|
+
|
|
464
545
|
function client_replicator.process_entity_id(
|
|
465
546
|
client: Client,
|
|
466
547
|
c: Cursor,
|
|
@@ -488,7 +569,7 @@ function client_replicator.process_entity_id(
|
|
|
488
569
|
local handler = client.shared.custom_ids.indexes[shared_custom_id]
|
|
489
570
|
|
|
490
571
|
if not handler then
|
|
491
|
-
|
|
572
|
+
common.log_error "attempted to use a custom id that wasn't registered"
|
|
492
573
|
end
|
|
493
574
|
custom_ids[server_id :: any] = handler
|
|
494
575
|
end
|
|
@@ -509,16 +590,11 @@ function client_replicator.process_entity_id(
|
|
|
509
590
|
end
|
|
510
591
|
end
|
|
511
592
|
|
|
512
|
-
function client_replicator.process_entity_relations(
|
|
513
|
-
client: Client,
|
|
514
|
-
entity: jecs.Entity,
|
|
515
|
-
c: Cursor,
|
|
516
|
-
custom_ids: CustomIdMap
|
|
517
|
-
)
|
|
593
|
+
function client_replicator.process_entity_relations(client: Client, entity: Entity, c: Cursor, custom_ids: CustomIdMap)
|
|
518
594
|
local components = client.components
|
|
519
595
|
local relation = client_replicator.read_component_id(client, c)
|
|
520
596
|
local total_targets = cursor.read_vlq(c)
|
|
521
|
-
local pair_hooks = client.network_hooks.changed[PAIR(components.
|
|
597
|
+
local pair_hooks = client.network_hooks.changed[PAIR(components.relation, relation)]
|
|
522
598
|
|
|
523
599
|
for _ = 1, total_targets do
|
|
524
600
|
client_replicator.process_entity_id(client, c, custom_ids, function(target)
|
|
@@ -529,7 +605,7 @@ end
|
|
|
529
605
|
|
|
530
606
|
function client_replicator.process_entity_relation_values(
|
|
531
607
|
client: Client,
|
|
532
|
-
entity:
|
|
608
|
+
entity: Entity,
|
|
533
609
|
c: Cursor,
|
|
534
610
|
custom_ids: CustomIdMap,
|
|
535
611
|
variants: { any }?
|
|
@@ -537,47 +613,99 @@ function client_replicator.process_entity_relation_values(
|
|
|
537
613
|
local relation = client_replicator.read_component_id(client, c)
|
|
538
614
|
local total_targets = cursor.read_vlq(c)
|
|
539
615
|
local components = client.components
|
|
540
|
-
local
|
|
616
|
+
local relation_hooks = client.network_hooks.changed[PAIR(components.relation, relation)]
|
|
541
617
|
|
|
542
618
|
for _ = 1, total_targets do
|
|
543
619
|
local value = client_replicator.read_component_value(client, relation, c, variants)
|
|
544
620
|
client_replicator.process_entity_id(client, c, custom_ids, function(target)
|
|
545
|
-
client_replicator.entity_set_pair(client, entity, relation, target, value,
|
|
621
|
+
client_replicator.entity_set_pair(client, entity, relation, target, value, relation_hooks)
|
|
546
622
|
end)
|
|
547
623
|
end
|
|
548
624
|
end
|
|
549
625
|
|
|
550
|
-
function client_replicator.
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
626
|
+
function client_replicator.process_entity_pair_value(
|
|
627
|
+
client: Client,
|
|
628
|
+
entity: Entity,
|
|
629
|
+
c: Cursor,
|
|
630
|
+
custom_ids: CustomIdMap,
|
|
631
|
+
variants: { any }?
|
|
632
|
+
)
|
|
633
|
+
local relation = client_replicator.read_component_id(client, c)
|
|
634
|
+
client_replicator.process_entity_id(client, c, custom_ids, function(target)
|
|
635
|
+
if (target :: any) > 0 then
|
|
636
|
+
local pointer_offset = cursor.read_vlq(c)
|
|
637
|
+
local jump_offset = c.offset - pointer_offset
|
|
554
638
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
local tag = client_replicator.read_component_id(client, c)
|
|
558
|
-
local tag_hooks = changed_hooks[PAIR(components.reliable, tag)]
|
|
559
|
-
client_replicator.entity_add(client, entity, tag, tag_hooks)
|
|
560
|
-
end
|
|
639
|
+
local _, value = client_replicator.read_pair_value(client, relation, target, c, variants)
|
|
640
|
+
client_replicator.entity_set_pair(client, entity, relation, target, value)
|
|
561
641
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
local
|
|
565
|
-
local component_hooks = changed_hooks[PAIR(components.reliable, component)]
|
|
566
|
-
client_replicator.entity_set(client, entity, component, value, component_hooks)
|
|
567
|
-
end
|
|
642
|
+
c.offset = jump_offset
|
|
643
|
+
else
|
|
644
|
+
local frozen_cursor = cursor.from_offset(c.buffer, c.offset)
|
|
568
645
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
client_replicator.process_entity_relations(client, entity, c, custom_ids)
|
|
572
|
-
end
|
|
646
|
+
local pointer_offset = cursor.read_vlq(c)
|
|
647
|
+
c.offset -= pointer_offset
|
|
573
648
|
|
|
574
|
-
|
|
575
|
-
for _ = 1, total_pairs_values do
|
|
576
|
-
client_replicator.process_entity_relation_values(client, entity, c, custom_ids, variants)
|
|
649
|
+
client_replicator.entity_set_postponed_pair(client, entity, relation, target, frozen_cursor, variants)
|
|
577
650
|
end
|
|
578
651
|
end)
|
|
579
652
|
end
|
|
580
653
|
|
|
654
|
+
function client_replicator.process_entity_pair(client: Client, entity: Entity, c: Cursor, custom_ids: CustomIdMap)
|
|
655
|
+
local relation = client_replicator.read_component_id(client, c)
|
|
656
|
+
client_replicator.process_entity_id(client, c, custom_ids, function(target)
|
|
657
|
+
-- TODO: respect hooks/overrides
|
|
658
|
+
client_replicator.entity_add_pair(client, entity, relation, target)
|
|
659
|
+
end)
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
function client_replicator.process_entity(
|
|
663
|
+
client: Client,
|
|
664
|
+
entity: Entity,
|
|
665
|
+
c: Cursor,
|
|
666
|
+
custom_ids: CustomIdMap,
|
|
667
|
+
variants: { any }?
|
|
668
|
+
)
|
|
669
|
+
local mask = cursor.readu8(c)
|
|
670
|
+
local changed_hooks = client.network_hooks.changed
|
|
671
|
+
local components = client.components
|
|
672
|
+
|
|
673
|
+
local total_tags = read_vlq_bitmask(c, mask, 0)
|
|
674
|
+
for _ = 1, total_tags do
|
|
675
|
+
local tag = client_replicator.read_component_id(client, c)
|
|
676
|
+
local tag_hooks = changed_hooks[PAIR(components.reliable, tag)]
|
|
677
|
+
client_replicator.entity_add(client, entity, tag, tag_hooks)
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
local total_components = read_vlq_bitmask(c, mask, 1)
|
|
681
|
+
for _ = 1, total_components do
|
|
682
|
+
local component = client_replicator.read_component_id(client, c)
|
|
683
|
+
local value = client_replicator.read_component_value(client, component, c, variants)
|
|
684
|
+
local component_hooks = changed_hooks[PAIR(components.reliable, component)]
|
|
685
|
+
client_replicator.entity_set(client, entity, component, value, component_hooks)
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
local total_pairs = read_vlq_bitmask(c, mask, 2)
|
|
689
|
+
for _ = 1, total_pairs do
|
|
690
|
+
client_replicator.process_entity_pair(client, entity, c, custom_ids)
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
local total_pair_values = read_vlq_bitmask(c, mask, 3)
|
|
694
|
+
for _ = 1, total_pair_values do
|
|
695
|
+
client_replicator.process_entity_pair_value(client, entity, c, custom_ids, variants)
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
local total_relations = read_vlq_bitmask(c, mask, 4)
|
|
699
|
+
for _ = 1, total_relations do
|
|
700
|
+
client_replicator.process_entity_relations(client, entity, c, custom_ids)
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
local total_relation_values = read_vlq_bitmask(c, mask, 5)
|
|
704
|
+
for _ = 1, total_relation_values do
|
|
705
|
+
client_replicator.process_entity_relation_values(client, entity, c, custom_ids, variants)
|
|
706
|
+
end
|
|
707
|
+
end
|
|
708
|
+
|
|
581
709
|
function client_replicator.finish_replication(client: Client)
|
|
582
710
|
client.is_replicating = false
|
|
583
711
|
for _, callback in client.after_replication_callbacks do
|
|
@@ -588,32 +716,33 @@ end
|
|
|
588
716
|
|
|
589
717
|
function client_replicator.resolve_dirty(client: Client)
|
|
590
718
|
if client.is_shared_dirty then
|
|
591
|
-
|
|
592
|
-
client.
|
|
719
|
+
-- stylua: ignore
|
|
720
|
+
client.shared = utils.resolved_shared(
|
|
721
|
+
client.world,
|
|
722
|
+
client.components,
|
|
723
|
+
client.registered_custom_ids,
|
|
724
|
+
client.component_serdes
|
|
725
|
+
)
|
|
726
|
+
client.is_shared_dirty = false
|
|
593
727
|
end
|
|
594
728
|
end
|
|
595
729
|
|
|
596
|
-
local function check_packet_type(c: Cursor,
|
|
597
|
-
local
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
730
|
+
local function check_packet_type(c: Cursor, expected_byte: number)
|
|
731
|
+
local got_byte = cursor.readu8(c)
|
|
732
|
+
if got_byte ~= expected_byte then
|
|
733
|
+
local got_type: string?
|
|
734
|
+
local expected_type: string?
|
|
735
|
+
|
|
736
|
+
for packet_type, byte in PACKET_TYPES :: { [string]: number } do
|
|
737
|
+
if byte == got_byte then
|
|
738
|
+
got_type = packet_type
|
|
739
|
+
elseif byte == expected_byte then
|
|
740
|
+
expected_type = packet_type
|
|
605
741
|
end
|
|
606
742
|
end
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
end
|
|
611
|
-
|
|
612
|
-
local function read_vlq_bitmask(c: Cursor, mask: number, bit: number): number
|
|
613
|
-
if utils.checkbit(mask, bit) then
|
|
614
|
-
return cursor.read_vlq(c)
|
|
615
|
-
else
|
|
616
|
-
return 0
|
|
743
|
+
common.log_error(
|
|
744
|
+
`packet type mismatch, expected: {expected_type or "(unknown)"} got: {got_type or "(unknown)"} instead`
|
|
745
|
+
)
|
|
617
746
|
end
|
|
618
747
|
end
|
|
619
748
|
|
|
@@ -621,7 +750,7 @@ function client_replicator.apply_command_buffer(
|
|
|
621
750
|
client: Client,
|
|
622
751
|
entity: Entity,
|
|
623
752
|
command_buffer: CommandBuffer,
|
|
624
|
-
request: (e: Entity
|
|
753
|
+
request: (e: Entity,...any) -> Entity?
|
|
625
754
|
)
|
|
626
755
|
local components = client.components
|
|
627
756
|
|
|
@@ -641,36 +770,59 @@ function client_replicator.apply_command_buffer(
|
|
|
641
770
|
local component_hooks = client.network_hooks.removed[PAIR(components.reliable, component)]
|
|
642
771
|
client_replicator.entity_remove(client, entity, component, component_hooks)
|
|
643
772
|
end
|
|
644
|
-
for relation, targets in command_buffer.
|
|
645
|
-
local
|
|
773
|
+
for relation, targets in command_buffer.pairs_add do
|
|
774
|
+
local relation_hooks = client.network_hooks.changed[PAIR(components.relation, relation)]
|
|
646
775
|
for target in targets do
|
|
647
776
|
local client_target = request(target)
|
|
648
777
|
if client_target then
|
|
649
|
-
client_replicator.entity_add_pair(client, entity, relation, client_target,
|
|
778
|
+
client_replicator.entity_add_pair(client, entity, relation, client_target, relation_hooks)
|
|
650
779
|
end
|
|
651
780
|
end
|
|
652
781
|
end
|
|
653
|
-
for relation, targets in command_buffer.
|
|
654
|
-
local
|
|
782
|
+
for relation, targets in command_buffer.pairs_set do
|
|
783
|
+
local relation_hooks = client.network_hooks.changed[PAIR(components.relation, relation)]
|
|
655
784
|
for target, value in targets do
|
|
656
785
|
local client_target = request(target)
|
|
657
786
|
if client_target then
|
|
658
|
-
client_replicator.entity_set_pair(client, entity, relation, client_target, value.value,
|
|
787
|
+
client_replicator.entity_set_pair(client, entity, relation, client_target, value.value, relation_hooks)
|
|
659
788
|
end
|
|
660
789
|
end
|
|
661
790
|
end
|
|
791
|
+
for relation, targets in command_buffer.pairs_unprocessed do
|
|
792
|
+
-- TODO: respect hooks
|
|
793
|
+
for target, unprocessed in targets do
|
|
794
|
+
local client_target = request(target)
|
|
795
|
+
if client_target then
|
|
796
|
+
local processed_value = unprocessed.processed_value
|
|
797
|
+
if processed_value then
|
|
798
|
+
client_replicator.entity_set_pair(client, entity, relation, client_target, processed_value.value)
|
|
799
|
+
else
|
|
800
|
+
local value = client_replicator.entity_set_postponed_pair(
|
|
801
|
+
client,
|
|
802
|
+
entity,
|
|
803
|
+
relation,
|
|
804
|
+
client_target,
|
|
805
|
+
unprocessed.cursor,
|
|
806
|
+
unprocessed.variants
|
|
807
|
+
)
|
|
808
|
+
unprocessed.processed_value = { value = value }
|
|
809
|
+
end
|
|
810
|
+
end
|
|
811
|
+
end
|
|
812
|
+
end
|
|
813
|
+
|
|
662
814
|
for relation, targets in command_buffer.pairs_remove do
|
|
663
|
-
local
|
|
815
|
+
local relation_hooks = client.network_hooks.removed[PAIR(components.relation, relation)]
|
|
664
816
|
for target in targets do
|
|
665
817
|
local client_target = request(target)
|
|
666
818
|
if client_target then
|
|
667
|
-
client_replicator.entity_remove_pair(client, entity, relation, client_target,
|
|
819
|
+
client_replicator.entity_remove_pair(client, entity, relation, client_target, relation_hooks)
|
|
668
820
|
end
|
|
669
821
|
end
|
|
670
822
|
end
|
|
671
|
-
for relation in command_buffer.
|
|
672
|
-
local
|
|
673
|
-
client_replicator.
|
|
823
|
+
for relation in command_buffer.relations_clear do
|
|
824
|
+
local relation_hooks = client.network_hooks.removed[PAIR(components.relation, relation)]
|
|
825
|
+
client_replicator.entity_clear_relation(client, entity, relation, relation_hooks)
|
|
674
826
|
end
|
|
675
827
|
end
|
|
676
828
|
|
|
@@ -683,32 +835,44 @@ function client_replicator.find_has_in_buffer(command_buffer: CommandBuffer, tag
|
|
|
683
835
|
or (command_buffer.components[tag] ~= nil)
|
|
684
836
|
or (command_buffer.unreliable_components[tag] ~= nil)
|
|
685
837
|
end
|
|
838
|
+
|
|
686
839
|
function client_replicator.find_pair_in_buffer(
|
|
687
840
|
command_buffer: CommandBuffer,
|
|
688
841
|
relation: Entity,
|
|
689
842
|
target: Entity,
|
|
690
843
|
find: (unprocessed_entity: Entity) -> (Entity?, Entity)
|
|
691
844
|
): (boolean, any)
|
|
692
|
-
local value_relations = command_buffer.
|
|
693
|
-
|
|
845
|
+
local value_relations = command_buffer.pairs_set[relation]
|
|
694
846
|
if value_relations then
|
|
695
|
-
for
|
|
696
|
-
local found = find(
|
|
847
|
+
for buffer_target, value in value_relations do
|
|
848
|
+
local found = find(buffer_target)
|
|
697
849
|
if found == target then
|
|
698
850
|
return true, value.value
|
|
699
851
|
end
|
|
700
852
|
end
|
|
701
853
|
end
|
|
702
854
|
|
|
703
|
-
local relations = command_buffer.
|
|
855
|
+
local relations = command_buffer.pairs_add[relation]
|
|
704
856
|
if relations then
|
|
705
|
-
for
|
|
706
|
-
local found = find(
|
|
857
|
+
for buffer_target in relations do
|
|
858
|
+
local found = find(buffer_target)
|
|
707
859
|
if found == target then
|
|
708
860
|
return true, nil
|
|
709
861
|
end
|
|
710
862
|
end
|
|
711
863
|
end
|
|
864
|
+
|
|
865
|
+
local unprocessed_relations = command_buffer.pairs_unprocessed[relation]
|
|
866
|
+
if unprocessed_relations then
|
|
867
|
+
for buffer_target, unprocessed in unprocessed_relations do
|
|
868
|
+
local found = find(buffer_target)
|
|
869
|
+
if found == target then
|
|
870
|
+
local processed_value = unprocessed.processed_value
|
|
871
|
+
return true, processed_value and processed_value.value
|
|
872
|
+
end
|
|
873
|
+
end
|
|
874
|
+
end
|
|
875
|
+
|
|
712
876
|
return false, nil
|
|
713
877
|
end
|
|
714
878
|
|
|
@@ -719,7 +883,7 @@ function client_replicator.find_target_in_buffer(
|
|
|
719
883
|
): Entity?
|
|
720
884
|
local i = 0
|
|
721
885
|
|
|
722
|
-
local pairs = command_buffer.
|
|
886
|
+
local pairs = command_buffer.pairs_add[relation]
|
|
723
887
|
if pairs then
|
|
724
888
|
for target in pairs do
|
|
725
889
|
if i == (index or 0) then
|
|
@@ -728,7 +892,8 @@ function client_replicator.find_target_in_buffer(
|
|
|
728
892
|
i += 1
|
|
729
893
|
end
|
|
730
894
|
end
|
|
731
|
-
|
|
895
|
+
|
|
896
|
+
local pairs_values = command_buffer.pairs_set[relation]
|
|
732
897
|
if pairs_values then
|
|
733
898
|
for target in pairs_values do
|
|
734
899
|
if i == (index or 0) then
|
|
@@ -737,6 +902,17 @@ function client_replicator.find_target_in_buffer(
|
|
|
737
902
|
i += 1
|
|
738
903
|
end
|
|
739
904
|
end
|
|
905
|
+
|
|
906
|
+
local unprocessed_pairs = command_buffer.pairs_unprocessed[relation]
|
|
907
|
+
if unprocessed_pairs then
|
|
908
|
+
for target in unprocessed_pairs do
|
|
909
|
+
if i == (index or 0) then
|
|
910
|
+
return target
|
|
911
|
+
end
|
|
912
|
+
i += 1
|
|
913
|
+
end
|
|
914
|
+
end
|
|
915
|
+
|
|
740
916
|
return nil
|
|
741
917
|
end
|
|
742
918
|
|
|
@@ -745,6 +921,7 @@ function client_replicator.finish_custom_ids(
|
|
|
745
921
|
custom_ids: CustomIdMap,
|
|
746
922
|
command_buffers: { [Entity]: CommandBuffer }
|
|
747
923
|
)
|
|
924
|
+
local world = client.world
|
|
748
925
|
local funcs = {} -- this is so process can use create_context even if its defined after
|
|
749
926
|
local processed: { [Entity]: boolean } = {}
|
|
750
927
|
|
|
@@ -771,18 +948,18 @@ function client_replicator.finish_custom_ids(
|
|
|
771
948
|
return nil
|
|
772
949
|
end
|
|
773
950
|
|
|
774
|
-
local new_entity: Entity?
|
|
775
|
-
|
|
951
|
+
local new_entity: Entity?
|
|
952
|
+
local command_buffer = command_buffers[unprocessed_entity :: any]
|
|
776
953
|
custom_handler = custom_handler or custom_ids[server_entity]
|
|
777
954
|
|
|
778
955
|
if type(custom_handler) == "number" then
|
|
779
956
|
local component: Entity = custom_handler :: any
|
|
780
957
|
|
|
781
|
-
local handler =
|
|
958
|
+
local handler = WORLD_GET(world, component, client.components.custom_handler)
|
|
782
959
|
if not handler then
|
|
783
|
-
return
|
|
784
|
-
`received a custom id for a non custom component, consider adding custom_handler to component: {
|
|
785
|
-
|
|
960
|
+
return common.log_error(
|
|
961
|
+
`received a custom id for a non custom component, consider adding custom_handler to component: {common.log_component(
|
|
962
|
+
world,
|
|
786
963
|
component
|
|
787
964
|
)}`
|
|
788
965
|
)
|
|
@@ -792,19 +969,17 @@ function client_replicator.finish_custom_ids(
|
|
|
792
969
|
if value then
|
|
793
970
|
new_entity = handler(value.value)
|
|
794
971
|
else
|
|
795
|
-
|
|
796
|
-
`No component found for custom id handler: {utils.logcomponent(client.world, component)}`
|
|
797
|
-
)
|
|
972
|
+
common.log_warn(`No component found for custom id handler: {common.log_component(world, component)}`)
|
|
798
973
|
new_entity = handler(nil)
|
|
799
974
|
end
|
|
800
975
|
else
|
|
801
|
-
|
|
976
|
+
common.log_warn(`No component found for custom id handler: {common.log_component(world, component)}`)
|
|
802
977
|
new_entity = handler(nil)
|
|
803
978
|
end
|
|
804
979
|
else
|
|
805
980
|
local handle_callback = (custom_handler :: CustomId).handle_callback
|
|
806
981
|
if not handle_callback then
|
|
807
|
-
return
|
|
982
|
+
return common.log_error(
|
|
808
983
|
"no handler callback was set for custom id:",
|
|
809
984
|
(custom_handler :: CustomId).identifier
|
|
810
985
|
)
|
|
@@ -813,7 +988,11 @@ function client_replicator.finish_custom_ids(
|
|
|
813
988
|
end
|
|
814
989
|
|
|
815
990
|
if new_entity then
|
|
991
|
+
WORLD_ADD(world, new_entity, client.components.__alive_tracking__)
|
|
992
|
+
|
|
816
993
|
client.server_ids[server_entity :: any] = new_entity
|
|
994
|
+
client.client_ids[new_entity] = server_entity :: any
|
|
995
|
+
|
|
817
996
|
if command_buffer then
|
|
818
997
|
client_replicator.apply_command_buffer(client, new_entity, command_buffer, process)
|
|
819
998
|
command_buffers[unprocessed_entity] = nil
|
|
@@ -894,12 +1073,71 @@ function client_replicator.finish_custom_ids(
|
|
|
894
1073
|
end
|
|
895
1074
|
end
|
|
896
1075
|
|
|
897
|
-
function client_replicator.
|
|
1076
|
+
function client_replicator.apply_full(client: Client, buf: buffer, all_variants: { { any } }?)
|
|
1077
|
+
client_replicator.resolve_dirty(client)
|
|
1078
|
+
client.is_replicating = true
|
|
1079
|
+
|
|
898
1080
|
local c = cursor.from(buf)
|
|
899
|
-
check_packet_type(c,
|
|
1081
|
+
check_packet_type(c, PACKET_TYPES.full)
|
|
1082
|
+
|
|
1083
|
+
local total_packets = cursor.read_vlq(c)
|
|
1084
|
+
local variant_start = (all_variants and #all_variants + 1) :: number
|
|
1085
|
+
|
|
1086
|
+
local command_buffers: { [Entity]: CommandBuffer } = {}
|
|
1087
|
+
local custom_ids: CustomIdMap = {}
|
|
1088
|
+
|
|
1089
|
+
client.command_buffers = command_buffers
|
|
1090
|
+
|
|
1091
|
+
for a = 1, total_packets do
|
|
1092
|
+
local total_entities = cursor.read_vlq(c)
|
|
1093
|
+
local variants = all_variants and all_variants[variant_start - a]
|
|
1094
|
+
|
|
1095
|
+
for _ = 1, total_entities do
|
|
1096
|
+
client_replicator.process_entity_id(client, c, custom_ids, function(entity)
|
|
1097
|
+
client_replicator.process_entity(client, entity, c, custom_ids, variants)
|
|
1098
|
+
end)
|
|
1099
|
+
end
|
|
1100
|
+
end
|
|
1101
|
+
|
|
1102
|
+
client_replicator.finish_custom_ids(client, custom_ids, command_buffers)
|
|
1103
|
+
client_replicator.finish_replication(client)
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1106
|
+
function client_replicator.apply_entity(client: Client, buf: buffer, all_variants: { { any } })
|
|
1107
|
+
client_replicator.resolve_dirty(client)
|
|
1108
|
+
client.is_replicating = true
|
|
1109
|
+
|
|
1110
|
+
local c = cursor.from(buf)
|
|
1111
|
+
check_packet_type(c, PACKET_TYPES.entity)
|
|
1112
|
+
|
|
1113
|
+
local total_packets = cursor.read_vlq(c)
|
|
1114
|
+
local variant_start = (all_variants and #all_variants + 1) :: number
|
|
1115
|
+
|
|
1116
|
+
local command_buffers: { [Entity]: CommandBuffer } = {}
|
|
1117
|
+
local custom_ids: CustomIdMap = {}
|
|
1118
|
+
|
|
1119
|
+
client.command_buffers = command_buffers
|
|
1120
|
+
|
|
1121
|
+
for a = 1, total_packets do
|
|
1122
|
+
local variants = all_variants and all_variants[variant_start - a]
|
|
1123
|
+
|
|
1124
|
+
client_replicator.process_entity_id(client, c, custom_ids, function(entity)
|
|
1125
|
+
client_replicator.process_entity(client, entity, c, custom_ids, variants)
|
|
1126
|
+
end)
|
|
1127
|
+
end
|
|
1128
|
+
|
|
1129
|
+
client_replicator.finish_custom_ids(client, custom_ids, command_buffers)
|
|
1130
|
+
client_replicator.finish_replication(client)
|
|
1131
|
+
end
|
|
1132
|
+
|
|
1133
|
+
function client_replicator.apply_updates(client: Client, buf: buffer, all_variants: { { any } }?)
|
|
900
1134
|
client_replicator.resolve_dirty(client)
|
|
901
1135
|
client.is_replicating = true
|
|
902
1136
|
|
|
1137
|
+
local c = cursor.from(buf)
|
|
1138
|
+
check_packet_type(c, PACKET_TYPES.updates)
|
|
1139
|
+
|
|
1140
|
+
local world = client.world
|
|
903
1141
|
local components = client.components
|
|
904
1142
|
local total_packets = cursor.read_vlq(c)
|
|
905
1143
|
local variant_start = (all_variants and #all_variants + 1) :: number
|
|
@@ -918,7 +1156,9 @@ function client_replicator.apply_updates(client: Client, buf: buffer, all_varian
|
|
|
918
1156
|
|
|
919
1157
|
local total_added = read_vlq_bitmask(c, storage_mask, 0)
|
|
920
1158
|
for _ = 1, total_added do
|
|
921
|
-
client_replicator.
|
|
1159
|
+
client_replicator.process_entity_id(client, c, custom_ids, function(entity)
|
|
1160
|
+
client_replicator.process_entity(client, entity, c, custom_ids, variants)
|
|
1161
|
+
end)
|
|
922
1162
|
end
|
|
923
1163
|
|
|
924
1164
|
local total_components_added = read_vlq_bitmask(c, storage_mask, 1)
|
|
@@ -935,18 +1175,29 @@ function client_replicator.apply_updates(client: Client, buf: buffer, all_varian
|
|
|
935
1175
|
|
|
936
1176
|
local total_components = read_vlq_bitmask(c, added_mask, 1)
|
|
937
1177
|
for _ = 1, total_components do
|
|
938
|
-
local component
|
|
1178
|
+
local component = client_replicator.read_component_id(client, c)
|
|
1179
|
+
local value = client_replicator.read_component_value(client, component, c, variants)
|
|
939
1180
|
local component_hooks = changed_hooks[PAIR(components.reliable, component)]
|
|
940
1181
|
client_replicator.entity_set(client, entity, component, value, component_hooks)
|
|
941
1182
|
end
|
|
942
1183
|
|
|
943
1184
|
local total_pairs = read_vlq_bitmask(c, added_mask, 2)
|
|
944
1185
|
for _ = 1, total_pairs do
|
|
1186
|
+
client_replicator.process_entity_pair(client, entity, c, custom_ids)
|
|
1187
|
+
end
|
|
1188
|
+
|
|
1189
|
+
local total_pair_values = read_vlq_bitmask(c, added_mask, 3)
|
|
1190
|
+
for _ = 1, total_pair_values do
|
|
1191
|
+
client_replicator.process_entity_pair_value(client, entity, c, custom_ids, variants)
|
|
1192
|
+
end
|
|
1193
|
+
|
|
1194
|
+
local total_relations = read_vlq_bitmask(c, added_mask, 4)
|
|
1195
|
+
for _ = 1, total_relations do
|
|
945
1196
|
client_replicator.process_entity_relations(client, entity, c, custom_ids)
|
|
946
1197
|
end
|
|
947
1198
|
|
|
948
|
-
local
|
|
949
|
-
for _ = 1,
|
|
1199
|
+
local total_relation_values = read_vlq_bitmask(c, added_mask, 5)
|
|
1200
|
+
for _ = 1, total_relation_values do
|
|
950
1201
|
client_replicator.process_entity_relation_values(client, entity, c, custom_ids, variants)
|
|
951
1202
|
end
|
|
952
1203
|
end)
|
|
@@ -966,7 +1217,8 @@ function client_replicator.apply_updates(client: Client, buf: buffer, all_varian
|
|
|
966
1217
|
|
|
967
1218
|
local total_components = read_vlq_bitmask(c, changed_mask, 1)
|
|
968
1219
|
for _ = 1, total_components do
|
|
969
|
-
local component
|
|
1220
|
+
local component = client_replicator.read_component_id(client, c)
|
|
1221
|
+
local value = client_replicator.read_component_value(client, component, c, variants)
|
|
970
1222
|
local component_hooks = changed_hooks[PAIR(components.reliable, component)]
|
|
971
1223
|
client_replicator.entity_set(client, entity, component, value, component_hooks)
|
|
972
1224
|
end
|
|
@@ -978,57 +1230,63 @@ function client_replicator.apply_updates(client: Client, buf: buffer, all_varian
|
|
|
978
1230
|
client_replicator.entity_remove(client, entity, component, component_hooks)
|
|
979
1231
|
end
|
|
980
1232
|
|
|
981
|
-
local
|
|
982
|
-
for _ = 1,
|
|
1233
|
+
local total_pairs_added = read_vlq_bitmask(c, changed_mask, 3)
|
|
1234
|
+
for _ = 1, total_pairs_added do
|
|
1235
|
+
client_replicator.process_entity_pair(client, entity, c, custom_ids)
|
|
1236
|
+
end
|
|
1237
|
+
|
|
1238
|
+
local total_pairs_set = read_vlq_bitmask(c, changed_mask, 4)
|
|
1239
|
+
for _ = 1, total_pairs_set do
|
|
1240
|
+
client_replicator.process_entity_pair(client, entity, c, custom_ids)
|
|
1241
|
+
end
|
|
1242
|
+
|
|
1243
|
+
local total_pairs_removed = read_vlq_bitmask(c, changed_mask, 5)
|
|
1244
|
+
for _ = 1, total_pairs_removed do
|
|
1245
|
+
local relation = client_replicator.read_component_id(client, c)
|
|
1246
|
+
client_replicator.process_entity_id(client, c, custom_ids, function(target)
|
|
1247
|
+
-- TODO: respect hooks/overrides
|
|
1248
|
+
client_replicator.entity_remove_pair(client, entity, relation, target)
|
|
1249
|
+
end)
|
|
1250
|
+
end
|
|
1251
|
+
|
|
1252
|
+
local total_relations_added = read_vlq_bitmask(c, changed_mask, 6)
|
|
1253
|
+
for _ = 1, total_relations_added do
|
|
983
1254
|
local relation = client_replicator.read_component_id(client, c)
|
|
984
|
-
local pair_changed_hooks = changed_hooks[PAIR(components.pair, relation)]
|
|
985
|
-
local pair_removed_hooks = removed_hooks[PAIR(components.pair, relation)]
|
|
986
1255
|
local total_targets = cursor.read_vlq(c)
|
|
1256
|
+
local pair_changed_hooks = changed_hooks[PAIR(components.relation, relation)]
|
|
987
1257
|
|
|
988
1258
|
for _ = 1, total_targets do
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
client_replicator.process_entity_id(client, c, custom_ids, function(target)
|
|
993
|
-
client_replicator.entity_add_pair(client, entity, relation, target, pair_changed_hooks)
|
|
994
|
-
end)
|
|
995
|
-
elseif action_type == -1 then -- remove pair
|
|
996
|
-
client_replicator.process_entity_id(client, c, custom_ids, function(target)
|
|
997
|
-
client_replicator.entity_remove_pair(
|
|
998
|
-
client,
|
|
999
|
-
entity,
|
|
1000
|
-
relation,
|
|
1001
|
-
target,
|
|
1002
|
-
pair_removed_hooks
|
|
1003
|
-
)
|
|
1004
|
-
end)
|
|
1005
|
-
end
|
|
1259
|
+
client_replicator.process_entity_id(client, c, custom_ids, function(target)
|
|
1260
|
+
client_replicator.entity_add_pair(client, entity, relation, target, pair_changed_hooks)
|
|
1261
|
+
end)
|
|
1006
1262
|
end
|
|
1007
1263
|
end
|
|
1008
1264
|
|
|
1009
|
-
local
|
|
1010
|
-
for _ = 1,
|
|
1265
|
+
local total_relation_values = read_vlq_bitmask(c, changed_mask, 7)
|
|
1266
|
+
for _ = 1, total_relation_values do
|
|
1011
1267
|
local relation = client_replicator.read_component_id(client, c)
|
|
1012
|
-
local pair_hooks = removed_hooks[PAIR(components.pair, relation)]
|
|
1013
1268
|
local total_targets = cursor.read_vlq(c)
|
|
1269
|
+
local pair_changed_hooks = changed_hooks[PAIR(components.relation, relation)]
|
|
1014
1270
|
|
|
1015
1271
|
for _ = 1, total_targets do
|
|
1272
|
+
local value = client_replicator.read_component_value(client, relation, c, variants)
|
|
1016
1273
|
client_replicator.process_entity_id(client, c, custom_ids, function(target)
|
|
1017
|
-
client_replicator.
|
|
1274
|
+
client_replicator.entity_set_pair(client, entity, relation, target, value, pair_changed_hooks)
|
|
1018
1275
|
end)
|
|
1019
1276
|
end
|
|
1020
1277
|
end
|
|
1021
1278
|
|
|
1022
|
-
|
|
1023
|
-
|
|
1279
|
+
-- using a normal vlq here sadly
|
|
1280
|
+
-- cause I ran out of bitmask space for this one :/
|
|
1281
|
+
local total_relations_removed = cursor.read_vlq(c)
|
|
1282
|
+
for _ = 1, total_relations_removed do
|
|
1024
1283
|
local relation = client_replicator.read_component_id(client, c)
|
|
1025
|
-
local pair_hooks = changed_hooks[PAIR(components.pair, relation)]
|
|
1026
1284
|
local total_targets = cursor.read_vlq(c)
|
|
1285
|
+
local pair_removed_hooks = removed_hooks[PAIR(components.relation, relation)]
|
|
1027
1286
|
|
|
1028
1287
|
for _ = 1, total_targets do
|
|
1029
|
-
local value = client_replicator.read_component_value(client, relation, c, variants)
|
|
1030
1288
|
client_replicator.process_entity_id(client, c, custom_ids, function(target)
|
|
1031
|
-
client_replicator.
|
|
1289
|
+
client_replicator.entity_remove_pair(client, entity, relation, target, pair_removed_hooks)
|
|
1032
1290
|
end)
|
|
1033
1291
|
end
|
|
1034
1292
|
end
|
|
@@ -1038,8 +1296,8 @@ function client_replicator.apply_updates(client: Client, buf: buffer, all_varian
|
|
|
1038
1296
|
local total_component_deletions = read_vlq_bitmask(c, storage_mask, 3)
|
|
1039
1297
|
for _ = 1, total_component_deletions do
|
|
1040
1298
|
client_replicator.process_entity_id(client, c, custom_ids, function(entity)
|
|
1041
|
-
local
|
|
1042
|
-
for _ = 1,
|
|
1299
|
+
local total_components = cursor.read_vlq(c)
|
|
1300
|
+
for _ = 1, total_components do
|
|
1043
1301
|
local component = client_replicator.read_component_id(client, c)
|
|
1044
1302
|
local component_hooks = removed_hooks[PAIR(components.reliable, component)]
|
|
1045
1303
|
client_replicator.entity_remove(client, entity, component, component_hooks)
|
|
@@ -1048,8 +1306,17 @@ function client_replicator.apply_updates(client: Client, buf: buffer, all_varian
|
|
|
1048
1306
|
local total_pairs = cursor.read_vlq(c)
|
|
1049
1307
|
for _ = 1, total_pairs do
|
|
1050
1308
|
local relation = client_replicator.read_component_id(client, c)
|
|
1051
|
-
|
|
1052
|
-
|
|
1309
|
+
client_replicator.process_entity_id(client, c, custom_ids, function(target)
|
|
1310
|
+
-- TODO: respect hooks/overrides
|
|
1311
|
+
client_replicator.entity_remove_pair(client, entity, relation, target)
|
|
1312
|
+
end)
|
|
1313
|
+
end
|
|
1314
|
+
|
|
1315
|
+
local total_relations = cursor.read_vlq(c)
|
|
1316
|
+
for _ = 1, total_relations do
|
|
1317
|
+
local relation = client_replicator.read_component_id(client, c)
|
|
1318
|
+
local pair_hooks = removed_hooks[PAIR(components.relation, relation)]
|
|
1319
|
+
client_replicator.entity_clear_relation(client, entity, relation, pair_hooks)
|
|
1053
1320
|
end
|
|
1054
1321
|
end)
|
|
1055
1322
|
end
|
|
@@ -1064,10 +1331,10 @@ function client_replicator.apply_updates(client: Client, buf: buffer, all_varian
|
|
|
1064
1331
|
callback(entity)
|
|
1065
1332
|
end
|
|
1066
1333
|
if not deleted_hook.overrides then
|
|
1067
|
-
|
|
1334
|
+
WORLD_DELETE(world, entity)
|
|
1068
1335
|
end
|
|
1069
1336
|
else
|
|
1070
|
-
|
|
1337
|
+
WORLD_DELETE(world, entity)
|
|
1071
1338
|
end
|
|
1072
1339
|
end
|
|
1073
1340
|
if server_id then
|
|
@@ -1081,11 +1348,12 @@ function client_replicator.apply_updates(client: Client, buf: buffer, all_varian
|
|
|
1081
1348
|
end
|
|
1082
1349
|
|
|
1083
1350
|
function client_replicator.apply_unreliable(client: Client, buf: buffer, all_variants: { { any } }?)
|
|
1084
|
-
local c = cursor.from(buf)
|
|
1085
|
-
check_packet_type(c, "unreliable")
|
|
1086
1351
|
client_replicator.resolve_dirty(client)
|
|
1087
1352
|
client.is_replicating = true
|
|
1088
1353
|
|
|
1354
|
+
local c = cursor.from(buf)
|
|
1355
|
+
check_packet_type(c, PACKET_TYPES.unreliable)
|
|
1356
|
+
|
|
1089
1357
|
local components = client.components
|
|
1090
1358
|
local total_packets = cursor.read_vlq(c)
|
|
1091
1359
|
local variant_start = (all_variants and #all_variants + 1) :: number
|
|
@@ -1101,15 +1369,17 @@ function client_replicator.apply_unreliable(client: Client, buf: buffer, all_var
|
|
|
1101
1369
|
|
|
1102
1370
|
if entity then
|
|
1103
1371
|
for _ = 1, total_unreliable do
|
|
1104
|
-
local
|
|
1105
|
-
local
|
|
1106
|
-
|
|
1372
|
+
local component = client_replicator.read_component_id(client, c)
|
|
1373
|
+
local value = client_replicator.read_component_value(client, component, c, variants)
|
|
1374
|
+
local unreliable_hooks = changed_hooks[PAIR(components.unreliable, component)]
|
|
1375
|
+
client_replicator.entity_set_unreliable(client, entity, component, value, unreliable_hooks)
|
|
1107
1376
|
end
|
|
1108
1377
|
else
|
|
1109
1378
|
-- dont apply unreliable updates to entities that dont exist in the client yet
|
|
1110
1379
|
-- but we still need to process the values to keep the cursor in the right place
|
|
1111
1380
|
for _ = 1, total_unreliable do
|
|
1112
|
-
client_replicator.
|
|
1381
|
+
local component = client_replicator.read_component_id(client, c)
|
|
1382
|
+
client_replicator.read_component_value(client, component, c, variants)
|
|
1113
1383
|
end
|
|
1114
1384
|
end
|
|
1115
1385
|
end
|
|
@@ -1118,34 +1388,19 @@ function client_replicator.apply_unreliable(client: Client, buf: buffer, all_var
|
|
|
1118
1388
|
client_replicator.finish_replication(client)
|
|
1119
1389
|
end
|
|
1120
1390
|
|
|
1121
|
-
function client_replicator.
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
client.is_replicating = true
|
|
1126
|
-
|
|
1127
|
-
local total_packets = cursor.read_vlq(c)
|
|
1128
|
-
local variant_start = (all_variants and #all_variants + 1) :: number
|
|
1129
|
-
|
|
1130
|
-
local command_buffers: { [Entity]: CommandBuffer } = {}
|
|
1131
|
-
local custom_ids: CustomIdMap = {}
|
|
1132
|
-
|
|
1133
|
-
client.command_buffers = command_buffers
|
|
1134
|
-
|
|
1135
|
-
for a = 1, total_packets do
|
|
1136
|
-
local total_entities = cursor.read_vlq(c)
|
|
1137
|
-
local variants = all_variants and all_variants[variant_start - a]
|
|
1138
|
-
|
|
1139
|
-
for _ = 1, total_entities do
|
|
1140
|
-
client_replicator.process_entity(client, c, custom_ids, variants)
|
|
1141
|
-
end
|
|
1142
|
-
end
|
|
1391
|
+
function client_replicator.set_serdes(client: Client, component: Component, serdes: types.Serdes)
|
|
1392
|
+
client.component_serdes[component] = serdes
|
|
1393
|
+
client.is_shared_dirty = true
|
|
1394
|
+
end
|
|
1143
1395
|
|
|
1144
|
-
|
|
1145
|
-
|
|
1396
|
+
function client_replicator.remove_serdes(client: Client, component: Component)
|
|
1397
|
+
client.component_serdes[component] = nil
|
|
1398
|
+
client.is_shared_dirty = true
|
|
1146
1399
|
end
|
|
1147
1400
|
|
|
1148
|
-
|
|
1401
|
+
-- TODO: Deserialize pairs in client
|
|
1402
|
+
|
|
1403
|
+
function client_replicator.init(client: Client, wrd: World?)
|
|
1149
1404
|
if client.inited == true then
|
|
1150
1405
|
return warn "attempted to init a client twice"
|
|
1151
1406
|
end
|
|
@@ -1154,44 +1409,57 @@ function client_replicator.init(client: Client, _world: World?)
|
|
|
1154
1409
|
end
|
|
1155
1410
|
client.inited = true :: any
|
|
1156
1411
|
|
|
1157
|
-
local world =
|
|
1412
|
+
local world = wrd or client.world
|
|
1158
1413
|
client.world = world
|
|
1159
1414
|
|
|
1160
1415
|
if not world then
|
|
1161
1416
|
error "Providing a world is required to start replecs"
|
|
1162
1417
|
end
|
|
1163
1418
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1419
|
+
if not client.components then
|
|
1420
|
+
client.components = utils.create_components(utils.tag_factory(world), utils.component_factory(world))
|
|
1421
|
+
utils.add_component_names(client.components, function(component, name)
|
|
1422
|
+
common.add_name(world, component, name)
|
|
1423
|
+
end)
|
|
1424
|
+
end
|
|
1170
1425
|
|
|
1171
1426
|
local components = client.components
|
|
1172
1427
|
|
|
1173
|
-
|
|
1428
|
+
local function hook(unhook: () -> ())
|
|
1429
|
+
table.insert(client.hooked, unhook)
|
|
1430
|
+
end
|
|
1174
1431
|
|
|
1175
|
-
|
|
1432
|
+
hook(HOOK_REMOVED(world, components.__alive_tracking__, function(entity)
|
|
1176
1433
|
local server_id = client.client_ids[entity]
|
|
1177
1434
|
if server_id then
|
|
1178
1435
|
client.server_ids[server_id] = nil
|
|
1179
1436
|
client.client_ids[entity] = nil
|
|
1180
1437
|
end
|
|
1181
1438
|
client.network_hooks.deleted[entity] = nil
|
|
1182
|
-
end)
|
|
1183
|
-
|
|
1439
|
+
end))
|
|
1440
|
+
|
|
1441
|
+
hook(HOOK_ADDED(world, components.serdes, function(component, _, serdes)
|
|
1442
|
+
client_replicator.set_serdes(client, component, serdes)
|
|
1443
|
+
end))
|
|
1444
|
+
hook(HOOK_CHANGED(world, components.serdes, function(component, _, serdes)
|
|
1445
|
+
client_replicator.set_serdes(client, component, serdes)
|
|
1446
|
+
end))
|
|
1447
|
+
hook(HOOK_REMOVED(world, components.serdes, function(component)
|
|
1448
|
+
client_replicator.remove_serdes(client, component)
|
|
1449
|
+
end))
|
|
1184
1450
|
|
|
1185
1451
|
for _, component in client.requires_shared_lookup do
|
|
1186
|
-
|
|
1452
|
+
hook(HOOK_ADDED(world, component, function()
|
|
1187
1453
|
client.is_shared_dirty = true
|
|
1188
|
-
end)
|
|
1189
|
-
|
|
1454
|
+
end))
|
|
1455
|
+
hook(HOOK_REMOVED(world, component, function()
|
|
1190
1456
|
client.is_shared_dirty = true
|
|
1191
|
-
end)
|
|
1192
|
-
table.insert(client.hooked, added_hook)
|
|
1193
|
-
table.insert(client.hooked, removed_hook)
|
|
1457
|
+
end))
|
|
1194
1458
|
end
|
|
1459
|
+
|
|
1460
|
+
QUERY_CURRENT_COMPONENTS(client)
|
|
1461
|
+
|
|
1462
|
+
client.shared = utils.resolved_shared(world, components, client.registered_custom_ids, client.component_serdes)
|
|
1195
1463
|
end
|
|
1196
1464
|
|
|
1197
1465
|
function client_replicator.after_replication(client: Client, callback: () -> ())
|
|
@@ -1215,7 +1483,7 @@ end
|
|
|
1215
1483
|
local function add_hook_entry(client: Client, action: string, ...): ({ overrides: boolean }, () -> ())
|
|
1216
1484
|
if action == "changed" or action == "removed" then
|
|
1217
1485
|
local relation = select(1, ...) :: Entity
|
|
1218
|
-
local callback = select(2, ...) :: (entity: Entity, id:
|
|
1486
|
+
local callback = select(2, ...) :: (entity: Entity, id: Component, value: any) -> ()
|
|
1219
1487
|
local hooks = action == "changed" and client.network_hooks.changed or client.network_hooks.removed
|
|
1220
1488
|
local entries = hooks[relation] :: ChangedHooksEntry
|
|
1221
1489
|
|
|
@@ -1281,6 +1549,31 @@ function client_replicator.override(client: Client, action: string, ...)
|
|
|
1281
1549
|
return disconnect
|
|
1282
1550
|
end
|
|
1283
1551
|
|
|
1552
|
+
function client_replicator.encode_component(client: Client, component: Entity): number
|
|
1553
|
+
client_replicator.resolve_dirty(client)
|
|
1554
|
+
local encoded = client.shared.components.members[component]
|
|
1555
|
+
if not encoded then
|
|
1556
|
+
common.log_error(`attempted to encode a non-shared component `, common.log_component(client.world, component))
|
|
1557
|
+
return 0
|
|
1558
|
+
end
|
|
1559
|
+
return encoded
|
|
1560
|
+
end
|
|
1561
|
+
|
|
1562
|
+
function client_replicator.decode_component(client: Client, encoded: number): Entity
|
|
1563
|
+
client_replicator.resolve_dirty(client)
|
|
1564
|
+
local component = client.shared.components.indexes[encoded]
|
|
1565
|
+
if not component then
|
|
1566
|
+
print("NON SHARED COMPONENT", encoded, client.shared.components)
|
|
1567
|
+
error "attemped to decode a non shared component"
|
|
1568
|
+
end
|
|
1569
|
+
return component
|
|
1570
|
+
end
|
|
1571
|
+
|
|
1572
|
+
function client_replicator.get_shared_count(client: Client): number
|
|
1573
|
+
client_replicator.resolve_dirty(client)
|
|
1574
|
+
return #client.shared.components.keys
|
|
1575
|
+
end
|
|
1576
|
+
|
|
1284
1577
|
function client_replicator.get_server_entity(client: Client, client_entity: Entity): number?
|
|
1285
1578
|
return client.client_ids[client_entity]
|
|
1286
1579
|
end
|
|
@@ -1292,7 +1585,7 @@ end
|
|
|
1292
1585
|
function client_replicator.register_entity(client: Client, entity: Entity, server_entity: number)
|
|
1293
1586
|
client.server_ids[server_entity] = entity
|
|
1294
1587
|
client.client_ids[entity] = server_entity
|
|
1295
|
-
client.world
|
|
1588
|
+
WORLD_ADD(client.world, entity, client.components.__alive_tracking__)
|
|
1296
1589
|
end
|
|
1297
1590
|
|
|
1298
1591
|
function client_replicator.unregister_entity(client: Client, entity: Entity)
|
|
@@ -1308,14 +1601,14 @@ function client_replicator.register_custom_id(client: Client, custom_id: CustomI
|
|
|
1308
1601
|
client.is_shared_dirty = true
|
|
1309
1602
|
end
|
|
1310
1603
|
|
|
1311
|
-
function client_replicator.generate_handshake(client: Client):
|
|
1604
|
+
function client_replicator.generate_handshake(client: Client): types.HandshakeInfo
|
|
1312
1605
|
client_replicator.resolve_dirty(client)
|
|
1313
|
-
return utils.generate_handshake(client.
|
|
1606
|
+
return utils.generate_handshake(client.shared)
|
|
1314
1607
|
end
|
|
1315
1608
|
|
|
1316
|
-
function client_replicator.verify_handshake(client: Client, handshake:
|
|
1609
|
+
function client_replicator.verify_handshake(client: Client, handshake: types.HandshakeInfo): (boolean, string?)
|
|
1317
1610
|
client_replicator.resolve_dirty(client)
|
|
1318
|
-
return utils.verify_handshake(client.
|
|
1611
|
+
return utils.verify_handshake(client.shared, handshake, "server", "client")
|
|
1319
1612
|
end
|
|
1320
1613
|
|
|
1321
1614
|
function client_replicator.destroy(client: Client)
|
|
@@ -1332,18 +1625,25 @@ function client_replicator.handle_global(client: Client, handler: (id: number) -
|
|
|
1332
1625
|
client.global_handler = handler
|
|
1333
1626
|
end
|
|
1334
1627
|
|
|
1335
|
-
local function create(world: World?, components:
|
|
1628
|
+
local function create(world: World?, components: types.Components?): Client
|
|
1336
1629
|
local self = {} :: Client
|
|
1337
1630
|
|
|
1338
|
-
|
|
1339
|
-
|
|
1631
|
+
if components then
|
|
1632
|
+
self.components = components
|
|
1633
|
+
elseif world then
|
|
1634
|
+
self.components = utils.create_components(utils.tag_factory(world), utils.component_factory(world))
|
|
1635
|
+
utils.add_component_names(self.components, function(component, name)
|
|
1636
|
+
common.add_name(world, component, name)
|
|
1637
|
+
end)
|
|
1638
|
+
end
|
|
1639
|
+
|
|
1340
1640
|
self.server_ids = {}
|
|
1341
1641
|
self.client_ids = {}
|
|
1342
1642
|
self.is_shared_dirty = false
|
|
1643
|
+
self.component_serdes = {}
|
|
1343
1644
|
self.requires_shared_lookup = {
|
|
1344
1645
|
self.components.shared,
|
|
1345
|
-
|
|
1346
|
-
jecs.Name,
|
|
1646
|
+
ECS_NAME,
|
|
1347
1647
|
}
|
|
1348
1648
|
self.global_handler = nil
|
|
1349
1649
|
self.world = world :: any
|