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