@rbxts/replecs 0.3.1 → 0.4.0-rc.2

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.
@@ -1,2216 +0,0 @@
1
- --!optimize 2
2
- --!native
3
-
4
- local utils = require (script.Parent:WaitForChild('utils'))
5
- local common = require (script.Parent:WaitForChild('common'))
6
- local types = require (script.Parent:WaitForChild('types'))
7
- local customid = require (script.Parent:WaitForChild('customid'))
8
- local masking_controller = require (script.Parent:WaitForChild('masking'))
9
-
10
- local cursor = utils.cursor
11
-
12
- type Cursor = utils.Cursor
13
- type CustomId = customid.CustomId
14
- type StorageGroup = masking_controller.StorageGroup
15
-
16
- type World = common.World
17
- type Entity = common.Entity
18
- type Component<T = any> = common.Component<T>
19
-
20
- type Set<T> = { [T]: boolean }
21
- type Map<K, V> = { [K]: V }
22
- type Array<T> = { T }
23
-
24
- type FunctionFilter = types.FunctionFilter
25
- type AnyFilter = types.AnyFilter
26
-
27
- type CustomIdSerialization = {
28
- required: Map<Entity, CustomId>,
29
- cursor_skip: number,
30
- }
31
-
32
- type EntityTrackInfo = {
33
- components: Map<Component, number>,
34
- pairs: Map<Component, number>,
35
- }
36
-
37
- type TrackInfo = {
38
- networked: Set<Entity>,
39
- entities: Map<Entity, EntityTrackInfo>,
40
- components: Map<Component, Map<Entity, number>>,
41
- pairs: Map<Component, Map<Entity, number>>,
42
- }
43
-
44
- type EntityStorage = {
45
- tags: { [Component]: boolean },
46
- components: { [Component]: any },
47
- pair_tags: { [Component]: boolean },
48
- pair_components: { [Component]: any },
49
-
50
- relations: { [Component]: Set<Entity> },
51
- relation_values: { [Component]: Map<Entity, any> },
52
- }
53
-
54
- type Storage = { [Entity]: EntityStorage }
55
-
56
- export type ServerImp = {
57
- set_networked: (self: Server, entity: Entity, filter: AnyFilter?) -> (),
58
- set_reliable: (self: Server, entity: Entity, component: Component, filter: AnyFilter?) -> (),
59
- set_unreliable: (self: Server, entity: Entity, component: Component, filter: AnyFilter?) -> (),
60
- set_pair: (self: Server, entity: Entity, id: Component, filter: AnyFilter?) -> (),
61
- set_relation: (self: Server, entity: Entity, relation: Component, filter: AnyFilter?) -> (),
62
-
63
- stop_networked: (self: Server, entity: Entity, keep: boolean?) -> (),
64
- stop_reliable: (self: Server, entity: Entity, component: Component, keep: boolean?) -> (),
65
- stop_unreliable: (self: Server, entity: Entity, component: Component, keep: boolean?) -> (),
66
- stop_pair: (self: Server, entity: Entity, id: Component, keep: boolean?) -> (),
67
- stop_relation: (self: Server, entity: Entity, relation: Component, keep: boolean?) -> (),
68
-
69
- set_custom: (self: Server, entity: Entity, component: Component | CustomId) -> (),
70
- remove_custom: (self: Server, entity: Entity) -> (),
71
-
72
- set_serdes: <T>(self: Server, id: Component<T>, serdes: types.Serdes<T>) -> (),
73
- remove_serdes: (self: Server, id: Component) -> (),
74
- }
75
-
76
- export type Server = ServerImp & {
77
- world: World,
78
- inited: boolean?,
79
-
80
- shared: types.Shared,
81
-
82
- components: types.Components,
83
- alive_tracked: Set<Entity>,
84
-
85
- is_shared_dirty: boolean,
86
- requires_shared_lookup: { Entity },
87
-
88
- track_info: TrackInfo,
89
- additions: Set<Entity>,
90
- custom_ids: Map<Entity, CustomId | Entity>,
91
- global_ids: Map<Entity, number>,
92
- storage: Storage,
93
- hooked: Array<() -> ()>,
94
- masking: masking_controller.MaskingController,
95
- pending_cleanups: Set<Entity>,
96
- connections: Array<RBXScriptConnection>,
97
- function_filters: masking_controller.EntityComponentIndex<FunctionFilter>,
98
-
99
- registered_custom_ids: Map<CustomId, boolean>,
100
- component_serdes: Map<Component, types.Serdes>,
101
-
102
- init: (self: Server, world: World?) -> (),
103
- destroy: (self: Server) -> (),
104
-
105
- encode_component: (self: Server, component: Component) -> number,
106
- decode_component: (self: Server, component: number) -> Component?,
107
- get_shared_count: (self: Server) -> number,
108
- register_custom_id: (self: Server, custom_id: CustomId) -> (),
109
-
110
- get_full: (self: Server, player: Player) -> (buffer, { { any } }),
111
- collect_entity: (self: Server, entity: Entity) -> () -> (Player, buffer, { { any } }),
112
- collect_updates: (self: Server) -> () -> (Player, buffer, { { any } }),
113
- collect_unreliable: (self: Server) -> () -> (Player, buffer, { { any } }),
114
-
115
- mark_player_ready: (self: Server, player: Player) -> (),
116
- is_player_ready: (self: Server, player: Player) -> boolean,
117
-
118
- add_player_alias: (self: Server, client: Player, alias: any) -> (),
119
- remove_player_alias: (self: Server, alias: any) -> (),
120
-
121
- generate_handshake: (self: Server) -> types.HandshakeInfo,
122
- verify_handshake: (self: Server, handshake: types.HandshakeInfo) -> (boolean, string?),
123
- }
124
-
125
- local server_replicator = {}
126
- server_replicator.__index = server_replicator
127
-
128
- local NIL_COMPONENT_VALUE = newproxy()
129
- local GLOBAL_ID_OFFSET = 10
130
-
131
- local COMPONENT_TYPES = {
132
- tag = 1,
133
- component = 2,
134
- pair_tag = 3,
135
- pair_component = 4,
136
- relation = 5,
137
- relation_component = 6,
138
- unreliable = 7,
139
- unreliable_pair = 8,
140
- }
141
-
142
- local PACKET_TYPES = {
143
- full = 1,
144
- entity = 2,
145
- updates = 3,
146
- unreliable = 4,
147
- }
148
-
149
- local MAX_PACKET_SIZE = 900
150
- local ENTITY_ID_TYPES = {
151
- entity = 1,
152
- custom_handler = 2,
153
- custom_id = 3,
154
- shared = 4,
155
- }
156
-
157
- local RELATIONSHIPS = common.relationships
158
- local WILDCARD = common.wildcard
159
- local ECS_NAME = common.ecs_name
160
-
161
- local IS_PAIR = common.is_pair
162
- local PAIR = common.pair
163
- local PAIR_FIRST = common.pair_first
164
- local PAIR_SECOND = common.pair_second
165
- local WORLD_ADD = common.world_add
166
- local WORLD_HAS = common.world_has
167
- local WORLD_GET = common.world_get
168
- local WORLD_TARGET = common.world_target
169
- local IS_COMPONENT = common.is_component
170
-
171
- local LISTEN_RELATION = common.listen_relation
172
-
173
- local HOOK_ADDED = common.hook_added
174
- local HOOK_CHANGED = common.hook_changed
175
- local HOOK_REMOVED = common.hook_removed
176
-
177
- local function HOOK_PAIR_ADDED(world: World, pair_id: Entity, callback: (Entity, Component, any) -> ())
178
- local relation = PAIR_FIRST(world, pair_id)
179
-
180
- return HOOK_ADDED(world, relation, function(entity, id, value)
181
- if id ~= pair_id then
182
- return
183
- end
184
- callback(entity, id, value)
185
- end)
186
- end
187
-
188
- local function HOOK_PAIR_CHANGED(world: World, pair_id: Entity, callback: (Entity, Component, any) -> ())
189
- local relation = PAIR_FIRST(world, pair_id)
190
-
191
- return HOOK_CHANGED(world, relation, function(entity, id, value)
192
- if id ~= pair_id then
193
- return
194
- end
195
- callback(entity, id, value)
196
- end)
197
- end
198
-
199
- local function HOOK_PAIR_REMOVED(world: World, pair_id: Entity, callback: (Entity, Component) -> ())
200
- local relation = PAIR_FIRST(world, pair_id)
201
-
202
- return HOOK_REMOVED(world, relation, function(entity, id)
203
- if id ~= pair_id then
204
- return
205
- end
206
- callback(entity, id)
207
- end)
208
- end
209
-
210
- local function QUERY_TRACKING_TYPE(server: Server, track_type: Component)
211
- local world = server.world
212
- for entity in world:query(PAIR(track_type, WILDCARD)):iter() do
213
- local index = 0
214
- while true do
215
- local target = WORLD_TARGET(world, entity, track_type, index)
216
- if not target then
217
- break
218
- end
219
- server.set_reliable(server, entity, target, WORLD_GET(world, entity, PAIR(track_type, target)))
220
- index += 1
221
- end
222
- end
223
- end
224
-
225
- local function QUERY_CURRENT_NETWORKED(server: Server)
226
- for entity, filter in server.world:query(server.components.networked):iter() do
227
- server.set_networked(server, entity, filter)
228
- end
229
-
230
- if RELATIONSHIPS then
231
- QUERY_TRACKING_TYPE(server, server.components.reliable)
232
- QUERY_TRACKING_TYPE(server, server.components.unreliable)
233
- QUERY_TRACKING_TYPE(server, server.components.relation)
234
- end
235
- end
236
-
237
- local function QUERY_CURRENT_COMPONENTS(server: Server)
238
- for component, serdes in server.world:query(server.components.serdes):iter() do
239
- server.component_serdes[component] = serdes
240
- end
241
- for entity, id in server.world:query(server.components.global):iter() do
242
- server.global_ids[entity] = id
243
- end
244
- end
245
-
246
- local function track_entity_lifetime(server: Server, entity: Entity)
247
- if server.alive_tracked[entity] then
248
- return
249
- end
250
- server.alive_tracked[entity] = true
251
- WORLD_ADD(server.world, entity, server.components.__alive_tracking__)
252
- end
253
-
254
- local function get_or_set_entity_storage(server: Server, entity: Entity): EntityStorage
255
- local storage: EntityStorage = server.storage[entity]
256
-
257
- if not storage then
258
- storage = {
259
- tags = {},
260
- components = {},
261
- pair_tags = {},
262
- pair_components = {},
263
- relations = {},
264
- relation_values = {},
265
- }
266
- server.storage[entity] = storage
267
- end
268
-
269
- return storage
270
- end
271
-
272
- local function allocate_component_change(server: Server, entity: Entity, component: Component, value: any)
273
- local storage = get_or_set_entity_storage(server, entity)
274
-
275
- local non_nil = if value == nil then NIL_COMPONENT_VALUE else value
276
- storage.components[component] = non_nil
277
-
278
- if not server.additions[entity] and server.track_info.networked[entity] then
279
- server.masking:allocate_component_change(entity, component, non_nil)
280
- end
281
- end
282
-
283
- local function allocate_unreliable_addition(server: Server, entity: Entity, component: Component)
284
- -- we dont modify the storage because changes are not tracked
285
- if not server.additions[entity] and server.track_info.networked[entity] then
286
- server.masking:allocate_unreliable_addition(entity, component)
287
- end
288
- end
289
-
290
- local function allocate_tag_addition(server: Server, entity: Entity, tag: Component)
291
- local storage = get_or_set_entity_storage(server, entity)
292
- storage.tags[tag] = true
293
-
294
- if not server.additions[entity] and server.track_info.networked[entity] then
295
- server.masking:allocate_tag_addition(entity, tag)
296
- end
297
- end
298
-
299
- local function allocate_pair_tag_addition(server: Server, entity: Entity, id: Component)
300
- local storage = get_or_set_entity_storage(server, entity)
301
- storage.pair_tags[id] = true
302
-
303
- if not server.additions[entity] and server.track_info.networked[entity] then
304
- server.masking:allocate_pair_tag_addition(entity, id)
305
- end
306
- end
307
-
308
- local function allocate_pair_component_change(server: Server, entity: Entity, id: Component, value: any)
309
- local storage = get_or_set_entity_storage(server, entity)
310
-
311
- local non_nil = if value == nil then NIL_COMPONENT_VALUE else value
312
- storage.pair_components[id] = non_nil
313
-
314
- if not server.additions[entity] and server.track_info.networked[entity] then
315
- server.masking:allocate_pair_component_change(entity, id, non_nil)
316
- end
317
- end
318
-
319
- local function allocate_relation_component_change(
320
- server: Server,
321
- entity: Entity,
322
- relation: Component,
323
- target: Entity,
324
- value: any
325
- )
326
- local storage = get_or_set_entity_storage(server, entity)
327
-
328
- local values = storage.relation_values[relation]
329
- if values == nil then
330
- values = {}
331
- storage.relation_values[relation] = values
332
- end
333
-
334
- local non_nil = if value == nil then NIL_COMPONENT_VALUE else value
335
- values[target] = non_nil
336
-
337
- if not server.additions[entity] and server.track_info.networked[entity] then
338
- server.masking:allocate_relation_component_change(entity, relation, target, non_nil)
339
- end
340
- end
341
-
342
- local function allocate_relation_tag_addition(server: Server, entity: Entity, relation: Component, target: Entity)
343
- local storage = get_or_set_entity_storage(server, entity)
344
- local targets = storage.relations[relation]
345
- if targets == nil then
346
- targets = {}
347
- storage.relations[relation] = targets
348
- end
349
- targets[target] = true
350
-
351
- if not server.additions[entity] and server.track_info.networked[entity] then
352
- server.masking:allocate_relation_tag_addition(entity, relation, target)
353
- end
354
- end
355
-
356
- local function allocate_component_removal(server: Server, entity: Entity, component: Component)
357
- local storage = get_or_set_entity_storage(server, entity)
358
- storage.components[component] = nil
359
-
360
- if not server.additions[entity] and server.track_info.networked[entity] then
361
- server.masking:allocate_component_removal(entity, component)
362
- end
363
- end
364
-
365
- local function allocate_unreliable_removal(server: Server, entity: Entity, component: Component)
366
- if not server.additions[entity] and server.track_info.networked[entity] then
367
- server.masking:allocate_unreliable_removal(entity, component)
368
- end
369
- end
370
-
371
- local function allocate_tag_removal(server: Server, entity: Entity, tag: Component)
372
- local storage = get_or_set_entity_storage(server, entity)
373
- storage.tags[tag] = nil
374
-
375
- if not server.additions[entity] and server.track_info.networked[entity] then
376
- server.masking:allocate_tag_removal(entity, tag)
377
- end
378
- end
379
-
380
- local function allocate_pair_tag_removal(server: Server, entity: Entity, id: Component)
381
- local storage = get_or_set_entity_storage(server, entity)
382
- storage.pair_tags[id] = nil
383
-
384
- if not server.additions[entity] and server.track_info.networked[entity] then
385
- server.masking:allocate_pair_tag_removal(entity, id)
386
- end
387
- end
388
-
389
- local function allocate_pair_component_removal(server: Server, entity: Entity, id: Component)
390
- local storage = get_or_set_entity_storage(server, entity)
391
- storage.pair_components[id] = nil
392
-
393
- if not server.additions[entity] and server.track_info.networked[entity] then
394
- server.masking:allocate_pair_component_removal(entity, id)
395
- end
396
- end
397
-
398
- local function allocate_relation_component_removal(server: Server, entity: Entity, relation: Component, target: Entity)
399
- local storage = get_or_set_entity_storage(server, entity)
400
- local values = storage.relation_values[relation]
401
- if values then
402
- values[target] = nil
403
- end
404
-
405
- if not server.additions[entity] and server.track_info.networked[entity] then
406
- server.masking:allocate_relation_component_removal(entity, relation, target)
407
- end
408
- end
409
-
410
- local function allocate_relation_tag_removal(server: Server, entity: Entity, relation: Component, target: Entity)
411
- local storage = get_or_set_entity_storage(server, entity)
412
- local targets = storage.relations[relation]
413
- if targets then
414
- targets[target] = nil
415
- end
416
-
417
- if not server.additions[entity] and server.track_info.networked[entity] then
418
- server.masking:allocate_relation_tag_removal(entity, relation, target)
419
- end
420
- end
421
-
422
- local function cleanup_entity(server: Server, entity: Entity)
423
- server.alive_tracked[entity] = nil
424
- server.storage[entity] = nil
425
- server.global_ids[entity] = nil
426
- server.custom_ids[entity] = nil
427
- server.additions[entity] = nil
428
- server.masking:cleanup_entity(entity)
429
-
430
- local track_info = server.track_info.entities[entity]
431
- if track_info then
432
- for component in track_info.components do
433
- local track_component = server.track_info.components[component]
434
- if track_component then
435
- track_component[entity] = nil
436
- end
437
- end
438
- for id in track_info.pairs do
439
- local track_pair = server.track_info.pairs[id]
440
- if track_pair then
441
- track_pair[entity] = nil
442
- end
443
- end
444
- server.track_info.entities[entity] = nil
445
- end
446
- end
447
-
448
- local function hook_pair(server: Server, pair_id: Component)
449
- local world = server.world
450
-
451
- if server.track_info.pairs[pair_id] then
452
- error(`attemped to track a pair twice: {common.log_component(server.world, PAIR_SECOND(world, pair_id))}`)
453
- end
454
-
455
- local info = {} :: Map<Entity, number>
456
- server.track_info.pairs[pair_id] = info
457
-
458
- local function hook(unhook: () -> ())
459
- table.insert(server.hooked, unhook)
460
- end
461
-
462
- hook(HOOK_PAIR_ADDED(world, pair_id, function(entity, id, value)
463
- local track_type = info[entity]
464
- if not track_type then
465
- return
466
- end
467
-
468
- if track_type == COMPONENT_TYPES.pair_component then
469
- allocate_pair_component_change(server, entity, id, value)
470
- else
471
- allocate_pair_tag_addition(server, entity, id)
472
- end
473
- end))
474
- hook(HOOK_PAIR_CHANGED(world, pair_id, function(entity, id, value)
475
- local track_type = info[entity]
476
- if not track_type then
477
- return
478
- end
479
-
480
- allocate_pair_component_change(server, entity, id, value)
481
- end))
482
- hook(HOOK_PAIR_REMOVED(world, pair_id, function(entity, id)
483
- local track_type = info[entity]
484
- if not track_type then
485
- return
486
- end
487
-
488
- if track_type == COMPONENT_TYPES.pair_component then
489
- allocate_pair_component_removal(server, entity, id)
490
- else
491
- allocate_pair_tag_removal(server, entity, id)
492
- end
493
- end))
494
-
495
- return info
496
- end
497
-
498
- local function hook_component(server: Server, component: Component)
499
- local world = server.world
500
-
501
- if server.track_info.components[component] then
502
- error(`attemped to track a component twice: {common.log_component(server.world, component)}`)
503
- end
504
-
505
- local info = {} :: Map<Entity, number>
506
- server.track_info.components[component] = info
507
-
508
- local function hook(unhook: () -> ())
509
- table.insert(server.hooked, unhook)
510
- end
511
-
512
- hook(HOOK_ADDED(world, component, function(entity, id, value)
513
- local track_type = info[entity]
514
- if not track_type then
515
- return
516
- end
517
-
518
- if track_type == COMPONENT_TYPES.component then
519
- allocate_component_change(server, entity, component, value)
520
- elseif track_type == COMPONENT_TYPES.tag then
521
- allocate_tag_addition(server, entity, component)
522
- elseif track_type == COMPONENT_TYPES.relation then
523
- if not IS_PAIR(id) then
524
- return
525
- end
526
- allocate_relation_tag_addition(server, entity, component, PAIR_SECOND(world, id))
527
- elseif track_type == COMPONENT_TYPES.relation_component then
528
- if not IS_PAIR(id) then
529
- return
530
- end
531
- allocate_relation_component_change(server, entity, component, PAIR_SECOND(world, id), value)
532
- elseif track_type == COMPONENT_TYPES.unreliable then
533
- allocate_unreliable_addition(server, entity, component)
534
- end
535
- end))
536
- hook(HOOK_CHANGED(world, component, function(entity, id, value)
537
- local track_type = info[entity]
538
- if not track_type then
539
- return
540
- end
541
- if track_type == COMPONENT_TYPES.component then
542
- allocate_component_change(server, entity, component, value)
543
- elseif track_type == COMPONENT_TYPES.relation_component then
544
- if not IS_PAIR(id) then
545
- return
546
- end
547
- allocate_relation_component_change(server, entity, component, PAIR_SECOND(world, id), value)
548
- end
549
- end))
550
- hook(HOOK_REMOVED(world, component, function(entity, id)
551
- local track_type = info[entity]
552
- if not track_type then
553
- return
554
- end
555
-
556
- if track_type == COMPONENT_TYPES.component then
557
- allocate_component_removal(server, entity, component)
558
- elseif track_type == COMPONENT_TYPES.tag then
559
- allocate_tag_removal(server, entity, component)
560
- elseif track_type == COMPONENT_TYPES.relation then
561
- if not IS_PAIR(id) then
562
- return
563
- end
564
- allocate_relation_tag_removal(server, entity, component, PAIR_SECOND(world, id))
565
- elseif track_type == COMPONENT_TYPES.relation_component then
566
- if not IS_PAIR(id) then
567
- return
568
- end
569
- allocate_relation_component_removal(server, entity, component, PAIR_SECOND(world, id))
570
- elseif track_type == COMPONENT_TYPES.unreliable then
571
- allocate_unreliable_removal(server, entity, component)
572
- end
573
- end))
574
-
575
- return info
576
- end
577
-
578
- local function add_entity_component_tracked(server: Server, entity: Entity, component: Component, track_type: number)
579
- local track: EntityTrackInfo = server.track_info.entities[entity]
580
- if track == nil then
581
- track = {
582
- components = { [component] = track_type },
583
- pairs = {},
584
- }
585
- server.track_info.entities[entity] = track
586
- else
587
- track.components[component] = track_type
588
- end
589
- end
590
-
591
- local function add_entity_pair_tracked(server: Server, entity: Entity, id: Component, track_type: number)
592
- local track: EntityTrackInfo = server.track_info.entities[entity]
593
- if track == nil then
594
- track = {
595
- components = {},
596
- pairs = { [id] = track_type },
597
- }
598
- server.track_info.entities[entity] = track
599
- else
600
- track.pairs[id] = track_type
601
- end
602
- end
603
-
604
- local function remove_entity_component_tracked(server: Server, entity: Entity, component: Component)
605
- local track = server.track_info.entities[entity]
606
- if track then
607
- track.components[component] = nil
608
- end
609
- end
610
-
611
- local function remove_entity_pair_tracked(server: Server, entity: Entity, id: Component)
612
- local track = server.track_info.entities[entity]
613
- if track then
614
- track.pairs[id] = nil
615
- end
616
- end
617
-
618
- local function track_entity_unreliable(server: Server, entity: Entity, component: Component)
619
- local info = server.track_info.components[component]
620
- if not info then
621
- info = hook_component(server, component)
622
- end
623
-
624
- info[entity] = COMPONENT_TYPES.unreliable
625
- add_entity_component_tracked(server, entity, component, COMPONENT_TYPES.unreliable)
626
- end
627
-
628
- local function track_entity_component(server: Server, entity: Entity, component: Component)
629
- local world = server.world
630
- local info = server.track_info.components[component]
631
- if not info then
632
- info = hook_component(server, component)
633
- end
634
-
635
- local entity_storage = get_or_set_entity_storage(server, entity)
636
-
637
- if IS_COMPONENT(world, component) then
638
- if WORLD_HAS(world, entity, component) then
639
- local value = WORLD_GET(world, entity, component)
640
-
641
- if value == nil then
642
- entity_storage.components[component] = NIL_COMPONENT_VALUE
643
- else
644
- entity_storage.components[component] = value
645
- end
646
- end
647
-
648
- info[entity] = COMPONENT_TYPES.component
649
- add_entity_component_tracked(server, entity, component, COMPONENT_TYPES.component)
650
-
651
- return COMPONENT_TYPES.component
652
- else
653
- if WORLD_HAS(world, entity, component) then
654
- entity_storage.tags[component] = true
655
- end
656
-
657
- info[entity] = COMPONENT_TYPES.tag
658
- add_entity_component_tracked(server, entity, component, COMPONENT_TYPES.tag)
659
-
660
- return COMPONENT_TYPES.tag
661
- end
662
- end
663
-
664
- local function track_entity_pair(server: Server, entity: Entity, id: Component)
665
- local world = server.world
666
- local info = server.track_info.pairs[id]
667
- if not info then
668
- info = hook_pair(server, id)
669
- end
670
-
671
- local entity_storage = get_or_set_entity_storage(server, entity)
672
-
673
- if IS_COMPONENT(world, id) then
674
- if WORLD_HAS(world, entity, id) then
675
- local value = WORLD_GET(world, entity, id)
676
-
677
- if value == nil then
678
- entity_storage.pair_components[id] = NIL_COMPONENT_VALUE
679
- else
680
- entity_storage.pair_components[id] = value
681
- end
682
- end
683
-
684
- info[entity] = COMPONENT_TYPES.pair_component
685
- add_entity_pair_tracked(server, entity, id, COMPONENT_TYPES.pair_component)
686
-
687
- return COMPONENT_TYPES.pair_component
688
- else
689
- if WORLD_HAS(world, entity, id) then
690
- entity_storage.pair_tags[id] = true
691
- end
692
-
693
- info[entity] = COMPONENT_TYPES.pair_tag
694
- add_entity_pair_tracked(server, entity, id, COMPONENT_TYPES.pair_tag)
695
-
696
- return COMPONENT_TYPES.pair_tag
697
- end
698
- end
699
-
700
- local function track_entity_relation(server: Server, entity: Entity, relation: Component)
701
- local world = server.world
702
- local info = server.track_info.components[relation]
703
- if not info then
704
- info = hook_component(server, relation)
705
- end
706
-
707
- local entity_storage = get_or_set_entity_storage(server, entity)
708
-
709
- if IS_COMPONENT(world, relation) then
710
- local targets = {} :: Map<Entity, any>
711
-
712
- local index = 0
713
- while true do
714
- local target = WORLD_TARGET(world, entity, relation, index)
715
- if not target then
716
- break
717
- end
718
- index += 1
719
- local value = WORLD_GET(world, entity, PAIR(relation, target))
720
- targets[target] = if value == nil then NIL_COMPONENT_VALUE else value :: any
721
- end
722
-
723
- entity_storage.relation_values[relation] = targets
724
- info[entity] = COMPONENT_TYPES.relation_component
725
- add_entity_component_tracked(server, entity, relation, COMPONENT_TYPES.relation_component)
726
-
727
- return COMPONENT_TYPES.relation_component
728
- else
729
- local targets = {} :: Set<Entity>
730
-
731
- local index = 0
732
- while true do
733
- local target = WORLD_TARGET(world, entity, relation, index)
734
- if not target then
735
- break
736
- end
737
- index += 1
738
- targets[target] = true
739
- end
740
-
741
- entity_storage.relations[relation] = targets
742
- info[entity] = COMPONENT_TYPES.relation
743
- add_entity_component_tracked(server, entity, relation, COMPONENT_TYPES.relation)
744
-
745
- return COMPONENT_TYPES.relation
746
- end
747
- end
748
-
749
- local function untrack_entity_component(server: Server, entity: Entity, component: Component): number?
750
- local info = server.track_info.components[component]
751
- if not info then
752
- return nil
753
- end
754
- local listen_type = info[entity]
755
- info[entity] = nil
756
-
757
- local storage = server.storage[entity]
758
- if storage then
759
- storage.components[component] = nil
760
- storage.tags[component] = nil
761
- end
762
-
763
- remove_entity_component_tracked(server, entity, component)
764
- return listen_type
765
- end
766
-
767
- local function untrack_entity_pair(server: Server, entity: Entity, id: Entity): number?
768
- local info = server.track_info.pairs[id]
769
- if not info then
770
- return nil
771
- end
772
- local listen_type = info[entity]
773
- info[entity] = nil
774
-
775
- local storage = server.storage[entity]
776
- if storage then
777
- storage.pair_tags[id] = nil
778
- storage.pair_components[id] = nil
779
- end
780
-
781
- remove_entity_pair_tracked(server, entity, id)
782
- return listen_type
783
- end
784
-
785
- local function untrack_entity_relation(server: Server, entity: Entity, relation: Entity): number?
786
- local info = server.track_info.components[relation]
787
- if not info then
788
- return nil
789
- end
790
- local listen_type = info[entity]
791
- info[entity] = nil
792
-
793
- local storage = server.storage[entity]
794
- if storage then
795
- storage.relations[relation] = nil
796
- storage.relation_values[relation] = nil
797
- end
798
-
799
- remove_entity_component_tracked(server, entity, relation)
800
- return listen_type
801
- end
802
-
803
- local function write_vlq_bitmask(c: Cursor, value: number, mask: number, bit: number): number
804
- if value > 0 then
805
- cursor.write_vlq(c, value)
806
- return utils.setbit(mask, bit)
807
- else
808
- return mask
809
- end
810
- end
811
-
812
- function server_replicator.write_component_id(server: Server, c: Cursor, component: Entity)
813
- local shared_componens = server.shared.components
814
- local encoded = shared_componens.members[component]
815
- if not encoded then
816
- common.log_error(`attempted to replicate a non-shared component `, common.log_component(server.world, component))
817
- return
818
- end
819
- cursor.write_span(c, encoded, #shared_componens.keys)
820
- end
821
-
822
- function server_replicator.write_variant_value(
823
- server: Server,
824
- c: Cursor,
825
- log_component: Component,
826
- serdes: types.Serdes?,
827
- value: any,
828
- variants: any
829
- )
830
- if serdes then
831
- local output, serdes_variants = serdes.serialize(if value == NIL_COMPONENT_VALUE then nil else value)
832
-
833
- if serdes.includes_variants then
834
- if serdes_variants == nil then
835
- -- 128 is zero for vlq
836
- cursor.writeu8(c, 128)
837
- else
838
- local start_variants = #variants
839
- if #serdes_variants > 0 then
840
- table.move(serdes_variants, 1, #serdes_variants, #variants + 1, variants)
841
- end
842
- cursor.write_vlq(c, #serdes_variants)
843
- cursor.write_vlq(c, start_variants + 1)
844
- end
845
- elseif serdes_variants ~= nil then
846
- common.log_error(
847
- "serdes: serializer provided variants yet includes_variants is not set to true for component: ",
848
- common.log_component(server.world, log_component)
849
- )
850
- end
851
-
852
- local bytespan = serdes.bytespan
853
- cursor.write_buffer(c, output)
854
- if bytespan then
855
- if bytespan ~= buffer.len(output) then
856
- common.log_error(
857
- `bytespan: {bytespan} mismatch for buffer lenght: {buffer.len(output)} in component: `,
858
- common.log_component(server.world, log_component)
859
- )
860
- end
861
- else
862
- local len = buffer.len(output)
863
- cursor.write_vlq(c, len)
864
- end
865
- else
866
- if value == nil or value == NIL_COMPONENT_VALUE then
867
- -- 128 is zero for vlq
868
- cursor.writeu8(c, 128)
869
- else
870
- table.insert(variants, value :: any)
871
- cursor.write_vlq(c, #variants)
872
- end
873
- end
874
- end
875
-
876
- function server_replicator.write_component_value(
877
- server: Server,
878
- c: Cursor,
879
- component: Component,
880
- value: any,
881
- variants: { any }
882
- )
883
- local serdes = server.shared.serdes[component]
884
- server_replicator.write_variant_value(server, c, component, serdes, value, variants)
885
- end
886
-
887
- function server_replicator.write_pair_value(
888
- server: Server,
889
- c: Cursor,
890
- relation: Component,
891
- id: Entity,
892
- value: any,
893
- variants: { any }
894
- )
895
- local serdes = server.shared.serdes[id] or server.shared.serdes[PAIR(relation, WILDCARD)]
896
- server_replicator.write_variant_value(server, c, relation, serdes, value, variants)
897
- end
898
-
899
- function server_replicator.write_entity_id(server: Server, c: Cursor, entity: Entity)
900
- local custom = server.custom_ids[entity]
901
- local global_id = server.global_ids[entity]
902
-
903
- if global_id then
904
- cursor.writeu8(c, global_id + GLOBAL_ID_OFFSET)
905
- elseif custom then
906
- if type(custom) == "number" then
907
- server_replicator.write_component_id(server, c, (custom :: any) :: Entity)
908
- cursor.writeu40(c, entity :: any)
909
- cursor.writeu8(c, ENTITY_ID_TYPES.custom_id)
910
- else
911
- cursor.writeu8(c, server.shared.custom_ids.members[custom :: CustomId])
912
- cursor.writeu40(c, entity :: any)
913
- cursor.writeu8(c, ENTITY_ID_TYPES.custom_handler)
914
- end
915
- else
916
- local shared_id = server.shared.components.members[entity]
917
- if shared_id then
918
- cursor.writeu8(c, shared_id)
919
- cursor.writeu8(c, ENTITY_ID_TYPES.shared)
920
- else
921
- cursor.writeu40(c, entity :: any)
922
- cursor.writeu8(c, ENTITY_ID_TYPES.entity, entity)
923
- end
924
- end
925
- end
926
-
927
- function server_replicator.write_entity_relations(server: Server, storage: EntityStorage, c: Cursor, relation: Entity)
928
- local targets = storage.relations[relation]
929
- local total_targets = 0
930
-
931
- for target in targets do
932
- server_replicator.write_entity_id(server, c, target)
933
- total_targets += 1
934
- end
935
- cursor.write_vlq(c, total_targets)
936
- server_replicator.write_component_id(server, c, relation)
937
- end
938
-
939
- function server_replicator.write_entity_relations_values(
940
- server: Server,
941
- storage: EntityStorage,
942
- c: Cursor,
943
- relation: Entity,
944
- variants: { any }
945
- )
946
- local targets = storage.relation_values[relation]
947
- local total_targets = 0
948
-
949
- for target, value in targets do
950
- server_replicator.write_entity_id(server, c, target)
951
- server_replicator.write_component_value(server, c, relation, value, variants)
952
- total_targets += 1
953
- end
954
- cursor.write_vlq(c, total_targets)
955
- server_replicator.write_component_id(server, c, relation)
956
- end
957
-
958
- function server_replicator.write_entity_pair_value(
959
- server: Server,
960
- world: World,
961
- c: Cursor,
962
- id: Component,
963
- value: any,
964
- variants: { any }
965
- )
966
- local first, second = PAIR_FIRST(world, id), PAIR_SECOND(world, id)
967
- local pointer_start = c.offset
968
-
969
- server_replicator.write_pair_value(server, c, first, id, value, variants)
970
-
971
- -- if the entity is a custom id, we dont know if this has a serdes in the client, as it needs to be processed first
972
- -- we write a vlq so the client can jump in the cursor to skip this value entirely and process it later
973
- local pointer_offset = c.offset - pointer_start
974
- cursor.write_vlq(c, pointer_offset)
975
-
976
- server_replicator.write_entity_id(server, c, second)
977
- server_replicator.write_component_id(server, c, first)
978
- end
979
-
980
- function server_replicator.write_entity_pair(server: Server, world: World, c: Cursor, id: Component)
981
- local first, second = PAIR_FIRST(world, id), PAIR_SECOND(world, id)
982
-
983
- server_replicator.write_entity_id(server, c, second)
984
- server_replicator.write_component_id(server, c, first)
985
- end
986
-
987
- function server_replicator.write_entity(
988
- server: Server,
989
- c: Cursor,
990
- entity: Entity,
991
- active: masking_controller.ActiveEntity,
992
- variants: { any }
993
- )
994
- local world = server.world
995
- local storage = server.storage[entity]
996
- local entity_mask = 0
997
-
998
- local total_relation_values = 0
999
- for relation in active.components[COMPONENT_TYPES.relation_component] do
1000
- server_replicator.write_entity_relations_values(server, storage, c, relation, variants)
1001
- total_relation_values += 1
1002
- end
1003
- entity_mask = write_vlq_bitmask(c, total_relation_values, entity_mask, 5)
1004
-
1005
- local total_relations = 0
1006
- for relation in active.components[COMPONENT_TYPES.relation] do
1007
- server_replicator.write_entity_relations(server, storage, c, relation)
1008
- total_relations += 1
1009
- end
1010
- entity_mask = write_vlq_bitmask(c, total_relations, entity_mask, 4)
1011
-
1012
- local total_pair_values = 0
1013
- for id in active.components[COMPONENT_TYPES.pair_component] do
1014
- local value = storage.pair_components[id]
1015
- if value == nil then
1016
- continue
1017
- end
1018
-
1019
- server_replicator.write_entity_pair_value(server, world, c, id, value, variants)
1020
- total_pair_values += 1
1021
- end
1022
- entity_mask = write_vlq_bitmask(c, total_pair_values, entity_mask, 3)
1023
-
1024
- local total_pairs = 0
1025
- for id in active.components[COMPONENT_TYPES.pair_tag] do
1026
- local has_pair = storage.pair_tags[id]
1027
- if has_pair then
1028
- server_replicator.write_entity_pair(server, world, c, id)
1029
- total_pairs += 1
1030
- end
1031
- end
1032
- entity_mask = write_vlq_bitmask(c, total_pairs, entity_mask, 2)
1033
-
1034
- local total_components = 0
1035
- for component in active.components[COMPONENT_TYPES.component] do
1036
- local value = storage.components[component]
1037
- if value == nil then
1038
- continue
1039
- end
1040
-
1041
- server_replicator.write_component_value(server, c, component, value, variants)
1042
- server_replicator.write_component_id(server, c, component)
1043
- total_components += 1
1044
- end
1045
- for component in active.components[COMPONENT_TYPES.unreliable] do
1046
- local has = WORLD_HAS(world, entity, component)
1047
- if not has then
1048
- continue
1049
- end
1050
- local value = WORLD_GET(world, entity, component)
1051
-
1052
- server_replicator.write_component_value(server, c, component, value, variants)
1053
- server_replicator.write_component_id(server, c, component)
1054
-
1055
- total_components += 1
1056
- end
1057
- entity_mask = write_vlq_bitmask(c, total_components, entity_mask, 1)
1058
-
1059
- local total_tags = 0
1060
- for tag in active.components[COMPONENT_TYPES.tag] do
1061
- local has_tag = storage.tags[tag]
1062
- if has_tag then
1063
- server_replicator.write_component_id(server, c, tag)
1064
- total_tags += 1
1065
- end
1066
- end
1067
- entity_mask = write_vlq_bitmask(c, total_tags, entity_mask, 0)
1068
- cursor.writeu8(c, entity_mask)
1069
- end
1070
-
1071
- function server_replicator.resolve_dirty(server: Server)
1072
- if server.is_shared_dirty then
1073
- -- stylua: ignore
1074
- server.shared = utils.resolved_shared(
1075
- server.world,
1076
- server.components,
1077
- server.registered_custom_ids,
1078
- server.component_serdes
1079
- )
1080
- server.is_shared_dirty = false
1081
- end
1082
- end
1083
-
1084
- type Packet = {
1085
- buffer: buffer,
1086
- variants: { any },
1087
- }
1088
- type MemberPackets = {
1089
- packets: Array<Packet>,
1090
- variants: { { any } },
1091
- total_size: number,
1092
- }
1093
-
1094
- local function append_packet(packets: { [Player]: MemberPackets }, members: { any }, output: buffer, variants: { any })
1095
- local len = buffer.len(output)
1096
- for _, member in members do
1097
- if not utils.is_client_valid(member) then
1098
- continue
1099
- end
1100
-
1101
- local member_packets = packets[member]
1102
-
1103
- if member_packets then
1104
- table.insert(member_packets.packets, {
1105
- buffer = output,
1106
- variants = variants,
1107
- })
1108
- member_packets.total_size += len
1109
- else
1110
- member_packets = {
1111
- packets = { {
1112
- buffer = output,
1113
- variants = variants,
1114
- } },
1115
- total_size = len,
1116
- }
1117
- packets[member] = member_packets :: MemberPackets
1118
- end
1119
- end
1120
- end
1121
-
1122
- local function combine_packet_outputs(outputs: Array<Packet>, total_size: number, id: number): (buffer, { { any } })
1123
- local combined = buffer.create(total_size + utils.vlq_span(#outputs) + 1)
1124
- local offset = 0
1125
- local variants = table.create(#outputs) :: { { any } }
1126
-
1127
- for _, output in outputs do
1128
- buffer.copy(combined, offset, output.buffer)
1129
- offset += buffer.len(output.buffer)
1130
- table.insert(variants, output.variants)
1131
- end
1132
- cursor.write_vlq({
1133
- offset = offset,
1134
- buffer = combined,
1135
- }, #outputs)
1136
- buffer.writeu8(combined, buffer.len(combined) - 1, id)
1137
-
1138
- return combined, variants
1139
- end
1140
-
1141
- type PacketIterator = () -> (Player, buffer, { { any } })
1142
-
1143
- local function create_packet_iterator(packets: { [Player]: MemberPackets }, id: number)
1144
- local iterated: Player?
1145
- local function iterator()
1146
- local player, data = next(packets, iterated)
1147
- while not utils.is_client_valid(player) do
1148
- if not player and not data then
1149
- break
1150
- end
1151
- player, data = next(packets, player)
1152
- end
1153
- if not player then
1154
- return nil :: any
1155
- end
1156
- iterated = player
1157
-
1158
- local combined, variants = combine_packet_outputs(data.packets, data.total_size, id)
1159
- return player, combined, variants
1160
- end
1161
- return iterator :: PacketIterator
1162
- end
1163
-
1164
- local function create_unreliable_packet_iterator(packets: { [Player]: MemberPackets })
1165
- return coroutine.wrap(function()
1166
- for player, data in packets do
1167
- if not utils.is_client_valid(player) then
1168
- continue
1169
- end
1170
-
1171
- table.sort(data.packets, function(a, b)
1172
- return buffer.len(a.buffer) < buffer.len(b.buffer)
1173
- end)
1174
- local total_packets = #data.packets
1175
-
1176
- local current_packet_index = 1
1177
- while current_packet_index <= total_packets do
1178
- local sending = {} :: { Packet }
1179
- local total_size = 0
1180
-
1181
- while current_packet_index <= total_packets do
1182
- local packet = data.packets[current_packet_index]
1183
- local buffer_size = buffer.len(packet.buffer)
1184
-
1185
- if total_size + buffer_size > MAX_PACKET_SIZE and #sending > 0 then
1186
- break
1187
- end
1188
-
1189
- table.insert(sending, packet)
1190
- total_size += buffer_size
1191
- current_packet_index += 1
1192
-
1193
- if total_size >= MAX_PACKET_SIZE then
1194
- break
1195
- end
1196
- end
1197
-
1198
- if #sending > 0 then
1199
- coroutine.yield(player, combine_packet_outputs(sending, total_size, PACKET_TYPES.unreliable))
1200
- end
1201
- end
1202
- end
1203
- end) :: PacketIterator
1204
- end
1205
-
1206
- function server_replicator.get_full(server: Server, client: Player): (buffer, { { any } })
1207
- server_replicator.resolve_dirty(server)
1208
- local index = server.masking.client_indexes[client]
1209
- if index == nil then
1210
- common.log_error "attempted to replicate for a non registered client"
1211
- end
1212
-
1213
- local packets: Array<Packet> = {}
1214
- local total_size = 0
1215
-
1216
- -- maybe edges to quickly find all relevant storages improves performance?
1217
- for _, storage in server.masking.storages do
1218
- if storage.active_count == 0 then
1219
- continue
1220
- end
1221
- if not storage.mask.bitmask:get(index) then
1222
- continue
1223
- end
1224
- local c = cursor.new()
1225
- local variants: { any } = {}
1226
-
1227
- local total_entities = 0
1228
- for entity, active in storage.active do
1229
- server_replicator.write_entity(server, c, entity, active, variants)
1230
- server_replicator.write_entity_id(server, c, entity)
1231
- total_entities += 1
1232
- end
1233
- cursor.write_vlq(c, total_entities)
1234
-
1235
- local output = cursor.close(c)
1236
- table.insert(packets, {
1237
- buffer = output,
1238
- variants = variants,
1239
- })
1240
- total_size += buffer.len(output)
1241
- end
1242
-
1243
- return combine_packet_outputs(packets, total_size, PACKET_TYPES.full)
1244
- end
1245
-
1246
- function server_replicator.collect_entity(server: Server, entity: Entity)
1247
- server_replicator.resolve_dirty(server)
1248
- local packets: { [Player]: MemberPackets } = {}
1249
- local processed_storages: Set<StorageGroup> = {}
1250
-
1251
- local lookup = server.masking.lookups.entities[entity]
1252
- local entity_storage = lookup.storage_group
1253
-
1254
- local c_main = cursor.new()
1255
- local variants_main = {}
1256
-
1257
- server_replicator.write_entity(server, c_main, entity, entity_storage.active[entity], variants_main)
1258
- server_replicator.write_entity_id(server, c_main, entity)
1259
- append_packet(packets, entity_storage.mask.members, cursor.close(c_main), variants_main)
1260
- processed_storages[entity_storage] = true
1261
-
1262
- for _, filtered in lookup.filtered_components do
1263
- for _, component in filtered do
1264
- local storage = component.storage_group
1265
- if processed_storages[storage] then
1266
- continue
1267
- end
1268
-
1269
- local c = cursor.new()
1270
- local variants = {}
1271
-
1272
- server_replicator.write_entity(server, c, entity, storage.active[entity], variants)
1273
- server_replicator.write_entity_id(server, c, entity)
1274
- append_packet(packets, storage.mask.members, cursor.close(c), variants)
1275
- processed_storages[storage] = true
1276
- end
1277
- end
1278
-
1279
- return create_packet_iterator(packets, PACKET_TYPES.entity)
1280
- end
1281
-
1282
- function server_replicator.collect_updates(server: Server)
1283
- server_replicator.resolve_dirty(server)
1284
- local world = server.world
1285
- local packets: { [Player]: MemberPackets } = {}
1286
-
1287
- for _, storage in server.masking.storages do
1288
- local c = cursor.new()
1289
- local variants = {}
1290
-
1291
- local storage_mask = 0
1292
-
1293
- local total_deleted = 0
1294
- local entity_deletions = storage.deletions.entities
1295
- for entity in entity_deletions do
1296
- server_replicator.write_entity_id(server, c, entity)
1297
- total_deleted += 1
1298
- end
1299
- table.clear(entity_deletions)
1300
- storage_mask = write_vlq_bitmask(c, total_deleted, storage_mask, 4)
1301
-
1302
- local total_component_deleted = 0
1303
- local component_deletions = storage.deletions.components
1304
- for entity, deleted in component_deletions do
1305
- local total_relations = 0
1306
-
1307
- for relation in deleted[COMPONENT_TYPES.relation_component] do
1308
- server_replicator.write_component_id(server, c, relation)
1309
- total_relations += 1
1310
- end
1311
- for relation in deleted[COMPONENT_TYPES.relation] do
1312
- server_replicator.write_component_id(server, c, relation)
1313
- total_relations += 1
1314
- end
1315
- cursor.write_vlq(c, total_relations)
1316
-
1317
- local total_pairs = 0
1318
- for id in deleted[COMPONENT_TYPES.pair_component] do
1319
- server_replicator.write_entity_pair(server, world, c, id)
1320
- total_pairs += 1
1321
- end
1322
- for id in deleted[COMPONENT_TYPES.pair_tag] do
1323
- server_replicator.write_entity_pair(server, world, c, id)
1324
- total_pairs += 1
1325
- end
1326
- cursor.write_vlq(c, total_pairs)
1327
-
1328
- local total_components = 0
1329
- for component in deleted[COMPONENT_TYPES.component] do
1330
- server_replicator.write_component_id(server, c, component)
1331
- total_components += 1
1332
- end
1333
- for component in deleted[COMPONENT_TYPES.unreliable] do
1334
- server_replicator.write_component_id(server, c, component)
1335
- total_components += 1
1336
- end
1337
- for tag in deleted[COMPONENT_TYPES.tag] do
1338
- server_replicator.write_component_id(server, c, tag)
1339
- total_components += 1
1340
- end
1341
- cursor.write_vlq(c, total_components)
1342
-
1343
- server_replicator.write_entity_id(server, c, entity)
1344
- total_component_deleted += 1
1345
- end
1346
- table.clear(component_deletions)
1347
- storage_mask = write_vlq_bitmask(c, total_component_deleted, storage_mask, 3)
1348
-
1349
- local storage_changes = storage.changes
1350
- local changed = 0
1351
- for entity, changes in storage_changes.changed do
1352
- -- relations remove
1353
-
1354
- local total_relations_removed = 0
1355
- for relation, targets in changes.relation_component_removed do
1356
- local total_targets = 0
1357
-
1358
- for target in targets do
1359
- server_replicator.write_entity_id(server, c, target)
1360
- total_targets += 1
1361
- end
1362
- cursor.write_vlq(c, total_targets)
1363
- server_replicator.write_component_id(server, c, relation)
1364
- total_relations_removed += 1
1365
- end
1366
- for relation, targets in changes.relation_tag_removed do
1367
- local total_targets = 0
1368
-
1369
- for target in targets do
1370
- server_replicator.write_entity_id(server, c, target)
1371
- total_targets += 1
1372
- end
1373
- cursor.write_vlq(c, total_targets)
1374
- server_replicator.write_component_id(server, c, relation)
1375
- total_relations_removed += 1
1376
- end
1377
- -- using a normal vlq here sadly
1378
- -- cause I ran out of bitmask space for this one :/
1379
- cursor.write_vlq(c, total_relations_removed)
1380
-
1381
- local changed_mask = 0
1382
-
1383
- -- relations add/set
1384
-
1385
- local total_relation_components = 0
1386
- for relation, targets in changes.relation_component_changed do
1387
- local total_targets = 0
1388
-
1389
- for target, value in targets do
1390
- server_replicator.write_entity_id(server, c, target)
1391
- server_replicator.write_component_value(server, c, relation, value, variants)
1392
- total_targets += 1
1393
- end
1394
- cursor.write_vlq(c, total_targets)
1395
- server_replicator.write_component_id(server, c, relation)
1396
- total_relation_components += 1
1397
- end
1398
- changed_mask = write_vlq_bitmask(c, total_relation_components, changed_mask, 7)
1399
-
1400
- local total_relation_tags = 0
1401
- for relation, targets in changes.relation_tag_added do
1402
- local total_targets = 0
1403
-
1404
- for target in targets do
1405
- server_replicator.write_entity_id(server, c, target)
1406
- total_targets += 1
1407
- end
1408
- cursor.write_vlq(c, total_targets)
1409
- server_replicator.write_component_id(server, c, relation)
1410
- total_relation_tags += 1
1411
- end
1412
- changed_mask = write_vlq_bitmask(c, total_relation_tags, changed_mask, 6)
1413
-
1414
- -- pairs removed
1415
-
1416
- local total_pairs_removed = 0
1417
- for id in changes.pair_component_removed do
1418
- server_replicator.write_entity_pair(server, world, c, id)
1419
- total_pairs_removed += 1
1420
- end
1421
- for id in changes.pair_tag_removed do
1422
- server_replicator.write_entity_pair(server, world, c, id)
1423
- total_pairs_removed += 1
1424
- end
1425
- changed_mask = write_vlq_bitmask(c, total_pairs_removed, changed_mask, 5)
1426
-
1427
- -- pairs add/set
1428
-
1429
- local total_pair_components = 0
1430
- for id, value in changes.pair_component_changed do
1431
- server_replicator.write_entity_pair_value(server, world, c, id, value, variants)
1432
- total_pair_components += 1
1433
- end
1434
- changed_mask = write_vlq_bitmask(c, total_pair_components, changed_mask, 4)
1435
-
1436
- local total_pair_tags = 0
1437
- for id in changes.pair_tag_added do
1438
- server_replicator.write_entity_pair(server, world, c, id)
1439
- total_pair_tags += 1
1440
- end
1441
- changed_mask = write_vlq_bitmask(c, total_pair_tags, changed_mask, 3)
1442
-
1443
- -- tags/components removed
1444
-
1445
- local total_removed = 0
1446
- for component in changes.component_removed do
1447
- server_replicator.write_component_id(server, c, component)
1448
- total_removed += 1
1449
- end
1450
- for component in changes.unreliable_removed do
1451
- server_replicator.write_component_id(server, c, component)
1452
- total_removed += 1
1453
- end
1454
- for component in changes.tag_removed do
1455
- server_replicator.write_component_id(server, c, component)
1456
- total_removed += 1
1457
- end
1458
- changed_mask = write_vlq_bitmask(c, total_removed, changed_mask, 2)
1459
-
1460
- -- tags/components set
1461
-
1462
- local total_components = 0
1463
- for component, value in changes.component_changed do
1464
- server_replicator.write_component_value(server, c, component, value, variants)
1465
- server_replicator.write_component_id(server, c, component)
1466
- total_components += 1
1467
- end
1468
- for component in changes.unreliable_added do
1469
- local value = WORLD_GET(world, entity, component)
1470
-
1471
- server_replicator.write_component_value(server, c, component, value, variants)
1472
- server_replicator.write_component_id(server, c, component)
1473
- total_components += 1
1474
- end
1475
- changed_mask = write_vlq_bitmask(c, total_components, changed_mask, 1)
1476
-
1477
- local total_tagged = 0
1478
- for tag in changes.tag_added do
1479
- server_replicator.write_component_id(server, c, tag)
1480
- total_tagged += 1
1481
- end
1482
- changed_mask = write_vlq_bitmask(c, total_tagged, changed_mask, 0)
1483
-
1484
- if changed_mask + total_relations_removed ~= 0 then
1485
- cursor.writeu8(c, changed_mask)
1486
- server_replicator.write_entity_id(server, c, entity)
1487
- changed += 1
1488
- end
1489
- end
1490
- table.clear(storage_changes.changed)
1491
- storage_mask = write_vlq_bitmask(c, changed, storage_mask, 2)
1492
-
1493
- local total_components_added = 0
1494
- for entity, components in storage_changes.added_components do
1495
- local entity_storage = server.storage[entity]
1496
- local added_mask = 0
1497
-
1498
- local total_relation_values = 0
1499
- for relation in components[COMPONENT_TYPES.relation_component] do
1500
- server_replicator.write_entity_relations_values(server, entity_storage, c, relation, variants)
1501
- total_relation_values += 1
1502
- end
1503
- added_mask = write_vlq_bitmask(c, total_relation_values, added_mask, 5)
1504
-
1505
- local total_relations = 0
1506
- for relation in components[COMPONENT_TYPES.relation] do
1507
- server_replicator.write_entity_relations(server, entity_storage, c, relation)
1508
- total_relations += 1
1509
- end
1510
- added_mask = write_vlq_bitmask(c, total_relations, added_mask, 4)
1511
-
1512
- local total_pair_values = 0
1513
- for id in components[COMPONENT_TYPES.pair_component] do
1514
- local value = entity_storage.pair_components[id]
1515
-
1516
- server_replicator.write_entity_pair_value(server, world, c, id, value, variants)
1517
- total_pair_values += 1
1518
- end
1519
- added_mask = write_vlq_bitmask(c, total_pair_values, added_mask, 3)
1520
-
1521
- local total_pairs = 0
1522
- for id in components[COMPONENT_TYPES.pair_tag] do
1523
- server_replicator.write_entity_pair(server, world, c, id)
1524
- total_pairs += 1
1525
- end
1526
- added_mask = write_vlq_bitmask(c, total_pairs, added_mask, 2)
1527
-
1528
- local total_components = 0
1529
- for component in components[COMPONENT_TYPES.component] do
1530
- local value = entity_storage.components[component]
1531
-
1532
- server_replicator.write_component_value(server, c, component, value, variants)
1533
- server_replicator.write_component_id(server, c, component)
1534
- total_components += 1
1535
- end
1536
- for component in components[COMPONENT_TYPES.unreliable] do
1537
- local value = WORLD_GET(world, entity, component)
1538
-
1539
- server_replicator.write_component_value(server, c, component, value, variants)
1540
- server_replicator.write_component_id(server, c, component)
1541
- total_components += 1
1542
- end
1543
- added_mask = write_vlq_bitmask(c, total_components, added_mask, 1)
1544
-
1545
- local total_tags = 0
1546
- for component in components[COMPONENT_TYPES.tag] do
1547
- local has_tag = entity_storage.tags[component]
1548
- if has_tag then
1549
- server_replicator.write_component_id(server, c, component)
1550
- total_tags += 1
1551
- end
1552
- end
1553
- added_mask = write_vlq_bitmask(c, total_tags, added_mask, 0)
1554
-
1555
- if added_mask ~= 0 then
1556
- cursor.writeu8(c, added_mask)
1557
- server_replicator.write_entity_id(server, c, entity)
1558
- total_components_added += 1
1559
- end
1560
- end
1561
- table.clear(storage_changes.added_components)
1562
- storage_mask = write_vlq_bitmask(c, total_components_added, storage_mask, 1)
1563
-
1564
- local total_added = 0
1565
- for entity in storage_changes.added do
1566
- local active = storage.active[entity]
1567
- if not active then
1568
- continue
1569
- end
1570
-
1571
- server_replicator.write_entity(server, c, entity, active, variants)
1572
- server_replicator.write_entity_id(server, c, entity)
1573
- total_added += 1
1574
- end
1575
- table.clear(storage_changes.added)
1576
- storage_mask = write_vlq_bitmask(c, total_added, storage_mask, 0)
1577
-
1578
- if storage_mask ~= 0 then
1579
- cursor.writeu8(c, storage_mask)
1580
- local output = cursor.close(c)
1581
- append_packet(packets, storage.mask.members, output, variants)
1582
- end
1583
- end
1584
- table.clear(server.additions)
1585
- return create_packet_iterator(packets, PACKET_TYPES.updates)
1586
- end
1587
-
1588
- function server_replicator.collect_unreliable(server: Server)
1589
- server_replicator.resolve_dirty(server)
1590
- local world = server.world
1591
- local packets: { [Player]: MemberPackets } = {}
1592
-
1593
- for _, mask_storage in server.masking.storages do
1594
- if mask_storage.active_count == 0 then
1595
- continue
1596
- end
1597
- local active = mask_storage.active
1598
-
1599
- local c = cursor.new()
1600
- local variants = {} :: Array<{ any }>
1601
- local total_entities = 0
1602
-
1603
- local checkpoint_offset = 0
1604
- local checkpoint_variants_count = 0
1605
- local checkpoint_total_entities = 0
1606
-
1607
- local function create_checkpoint()
1608
- checkpoint_offset = c.offset
1609
- checkpoint_variants_count = #variants
1610
- checkpoint_total_entities = total_entities
1611
- end
1612
-
1613
- local function rollback_checkpoint()
1614
- local new_cursor = cursor.new()
1615
- cursor.write_buffer(new_cursor, c.buffer, checkpoint_offset, c.offset - checkpoint_offset)
1616
- c.offset = checkpoint_offset
1617
- c = new_cursor
1618
-
1619
- local new_variants = {} :: Array<{ any }>
1620
- for _ = #variants, checkpoint_variants_count + 1, -1 do
1621
- table.insert(new_variants, 1, table.remove(variants) :: { any })
1622
- end
1623
-
1624
- variants = new_variants
1625
- total_entities = total_entities - checkpoint_total_entities
1626
- end
1627
-
1628
- local function commit_checkpoint(commit_c, commit_variants, commit_total_entities)
1629
- if commit_total_entities <= 0 then
1630
- return
1631
- end
1632
-
1633
- cursor.write_vlq(commit_c, commit_total_entities)
1634
- local output = cursor.close(commit_c)
1635
- append_packet(packets, mask_storage.mask.members, output, commit_variants)
1636
- end
1637
-
1638
- for entity, actives in active do
1639
- create_checkpoint()
1640
-
1641
- local total_unreliable = 0
1642
- for component in actives.components[COMPONENT_TYPES.unreliable] do
1643
- local has = WORLD_HAS(world, entity, component)
1644
- if not has then
1645
- continue
1646
- end
1647
- local value = WORLD_GET(world, entity, component)
1648
-
1649
- server_replicator.write_component_value(server, c, component, value, variants)
1650
- server_replicator.write_component_id(server, c, component)
1651
-
1652
- total_unreliable += 1
1653
- end
1654
-
1655
- if total_unreliable <= 0 then
1656
- continue
1657
- end
1658
- total_entities += 1
1659
- cursor.write_vlq(c, total_unreliable)
1660
- server_replicator.write_entity_id(server, c, entity)
1661
-
1662
- if c.offset > MAX_PACKET_SIZE then
1663
- local commit_cursor = c
1664
- local commit_variants = variants
1665
-
1666
- rollback_checkpoint()
1667
- commit_checkpoint(commit_cursor, commit_variants, checkpoint_total_entities)
1668
- end
1669
- end
1670
- commit_checkpoint(c, variants, total_entities)
1671
- end
1672
-
1673
- return create_unreliable_packet_iterator(packets)
1674
- end
1675
-
1676
- function server_replicator.start_networked(server: Server, entity: Entity, filter: AnyFilter?)
1677
- local masking = server.masking
1678
-
1679
- masking:deallocate_entity_stop(entity)
1680
- masking:start_entity(entity, filter)
1681
- masking:allocate_propagated_entity_start(entity)
1682
-
1683
- server.additions[entity] = true
1684
- server.track_info.networked[entity] = true
1685
- track_entity_lifetime(server, entity)
1686
- end
1687
-
1688
- function server_replicator.start_reliable(server: Server, entity: Entity, component: Component, filter: AnyFilter?)
1689
- local masking = server.masking
1690
-
1691
- local track_type = track_entity_component(server, entity, component)
1692
- masking:deallocate_component_stop(entity, component, track_type)
1693
- masking:start_component(entity, component, track_type, filter)
1694
-
1695
- if server.additions[entity] then
1696
- masking:allocate_shared_entity_start(entity, component, track_type)
1697
- elseif server.track_info.networked[entity] then
1698
- masking:allocate_component_start(entity, component, track_type)
1699
- end
1700
- end
1701
-
1702
- function server_replicator.start_unreliable(server: Server, entity: Entity, component: Component, filter: AnyFilter?)
1703
- local masking = server.masking
1704
- local UNRELIABLE_TYPE = COMPONENT_TYPES.unreliable
1705
-
1706
- track_entity_unreliable(server, entity, component)
1707
- masking:deallocate_component_stop(entity, component, UNRELIABLE_TYPE)
1708
- masking:start_component(entity, component, UNRELIABLE_TYPE, filter)
1709
-
1710
- if server.additions[entity] then
1711
- masking:allocate_shared_entity_start(entity, component, UNRELIABLE_TYPE)
1712
- elseif server.track_info.networked[entity] then
1713
- masking:allocate_component_start(entity, component, UNRELIABLE_TYPE)
1714
- end
1715
- end
1716
-
1717
- function server_replicator.start_pair(server: Server, entity: Entity, id: Component, filter: AnyFilter?)
1718
- local masking = server.masking
1719
-
1720
- local track_type = track_entity_pair(server :: Server, entity, id)
1721
- masking:deallocate_component_stop(entity, id, track_type)
1722
- masking:start_component(entity, id, track_type, filter)
1723
-
1724
- if server.additions[entity] then
1725
- masking:allocate_shared_entity_start(entity, id, track_type)
1726
- elseif server.track_info.networked[entity] then
1727
- masking:allocate_component_start(entity, id, track_type)
1728
- end
1729
- end
1730
-
1731
- function server_replicator.start_relation(server: Server, entity: Entity, relation: Component, filter: AnyFilter?)
1732
- local masking = server.masking
1733
-
1734
- local track_type = track_entity_relation(server, entity, relation)
1735
- masking:deallocate_component_stop(entity, relation, track_type)
1736
- masking:start_component(entity, relation, track_type, filter)
1737
-
1738
- if server.additions[entity] then
1739
- masking:allocate_shared_entity_start(entity, relation, track_type)
1740
- elseif server.track_info.networked[entity] then
1741
- masking:allocate_component_start(entity, relation, track_type)
1742
- end
1743
- end
1744
-
1745
- function server_replicator.change_networked(server: Server, entity: Entity, filter: AnyFilter?)
1746
- local masking = server.masking
1747
- masking:set_entity(entity, filter)
1748
- end
1749
-
1750
- function server_replicator.change_reliable(server: Server, entity: Entity, component: Component, filter: AnyFilter?)
1751
- local world = server.world
1752
- local masking = server.masking
1753
-
1754
- if IS_COMPONENT(world, component) then
1755
- masking:set_component(entity, component, COMPONENT_TYPES.component, filter)
1756
- else
1757
- masking:set_component(entity, component, COMPONENT_TYPES.tag, filter)
1758
- end
1759
- end
1760
-
1761
- function server_replicator.change_unreliable(server: Server, entity: Entity, component: Component, filter: AnyFilter?)
1762
- local masking = server.masking
1763
- masking:set_component(entity, component, COMPONENT_TYPES.unreliable, filter)
1764
- end
1765
-
1766
- function server_replicator.change_pair(server: Server, entity: Entity, id: Component, filter: AnyFilter?)
1767
- local world = server.world
1768
- local masking = server.masking
1769
-
1770
- if IS_COMPONENT(world, id) then
1771
- masking:set_component(entity, id, COMPONENT_TYPES.pair_component, filter)
1772
- else
1773
- masking:set_component(entity, id, COMPONENT_TYPES.pair_tag, filter)
1774
- end
1775
- end
1776
-
1777
- function server_replicator.change_relation(server: Server, entity: Entity, relation: Component, filter: AnyFilter?)
1778
- local world = server.world
1779
- local masking = server.masking
1780
-
1781
- if IS_COMPONENT(world, relation) then
1782
- masking:set_component(entity, relation, COMPONENT_TYPES.relation_component, filter)
1783
- else
1784
- masking:set_component(entity, relation, COMPONENT_TYPES.relation, filter)
1785
- end
1786
- end
1787
-
1788
- local function stop_tracked_component(
1789
- server: Server,
1790
- entity: Entity,
1791
- component: Component,
1792
- track_type: number,
1793
- keep: boolean?
1794
- )
1795
- local masking = server.masking
1796
- if server.track_info.networked[entity] then
1797
- masking:deallocate_component_start(entity, component, track_type)
1798
- if not keep then
1799
- masking:allocate_component_stop(entity, component, track_type)
1800
- end
1801
- end
1802
- masking:stop_component(entity, component, track_type)
1803
- end
1804
-
1805
- function server_replicator.stop_networked(server: Server, entity: Entity, keep: boolean?)
1806
- if not server.track_info.networked[entity] then
1807
- return
1808
- end
1809
-
1810
- local masking = server.masking
1811
- if not keep then
1812
- masking:allocate_entity_stop(entity)
1813
- end
1814
- masking:stop_entity(entity)
1815
-
1816
- server.additions[entity] = nil
1817
- server.track_info.networked[entity] = nil
1818
- end
1819
-
1820
- function server_replicator.stop_reliable(server: Server, entity: Entity, component: Component, keep: boolean?)
1821
- if not server.track_info.entities[entity] then
1822
- return
1823
- end
1824
-
1825
- local track_type = untrack_entity_component(server, entity, component)
1826
- if not track_type then
1827
- return
1828
- end
1829
-
1830
- stop_tracked_component(server, entity, component, track_type, keep)
1831
- end
1832
-
1833
- function server_replicator.stop_unreliable(server: Server, entity: Entity, component: Component, keep: boolean?)
1834
- if not server.track_info.entities[entity] then
1835
- return
1836
- end
1837
-
1838
- local track_type = untrack_entity_component(server, entity, component)
1839
- if not track_type then
1840
- return
1841
- end
1842
-
1843
- stop_tracked_component(server, entity, component, COMPONENT_TYPES.unreliable, keep)
1844
- end
1845
-
1846
- function server_replicator.stop_pair(server: Server, entity: Entity, id: Component, keep: boolean?)
1847
- if not server.track_info.entities[entity] then
1848
- return
1849
- end
1850
-
1851
- local track_type = untrack_entity_pair(server, entity, id)
1852
- if not track_type then
1853
- return
1854
- end
1855
-
1856
- stop_tracked_component(server, entity, id, track_type, keep)
1857
- end
1858
-
1859
- function server_replicator.stop_relation(server: Server, entity: Entity, relation: Component, keep: boolean?)
1860
- if not server.track_info.entities[entity] then
1861
- return
1862
- end
1863
-
1864
- local track_type = untrack_entity_relation(server, entity, relation)
1865
- if not track_type then
1866
- return
1867
- end
1868
-
1869
- stop_tracked_component(server, entity, relation, track_type, keep)
1870
- end
1871
-
1872
- function server_replicator.set_networked(server: Server, entity: Entity, filter: AnyFilter?)
1873
- if server.track_info.networked[entity] then
1874
- server_replicator.change_networked(server, entity, filter)
1875
- else
1876
- server_replicator.start_networked(server, entity, filter)
1877
- end
1878
- end
1879
-
1880
- function server_replicator.set_reliable(server: Server, entity: Entity, component: Component, filter: AnyFilter?)
1881
- local entity_tracked = server.track_info.entities[entity]
1882
- if entity_tracked and entity_tracked.components[component] then
1883
- server_replicator.change_reliable(server, entity, component, filter)
1884
- else
1885
- server_replicator.start_reliable(server, entity, component, filter)
1886
- end
1887
- end
1888
-
1889
- function server_replicator.set_unreliable(server: Server, entity: Entity, component: Component, filter: AnyFilter?)
1890
- local entity_tracked = server.track_info.entities[entity]
1891
- if entity_tracked and entity_tracked.components[component] then
1892
- server_replicator.change_unreliable(server, entity, component, filter)
1893
- else
1894
- server_replicator.start_unreliable(server, entity, component, filter)
1895
- end
1896
- end
1897
-
1898
- function server_replicator.set_pair(server: Server, entity: Entity, id: Component, filter: AnyFilter?)
1899
- local entity_tracked = server.track_info.entities[entity]
1900
- if entity_tracked and entity_tracked.pairs[id] then
1901
- server_replicator.change_pair(server, entity, id, filter)
1902
- else
1903
- server_replicator.start_pair(server, entity, id, filter)
1904
- end
1905
- end
1906
-
1907
- function server_replicator.set_relation(server: Server, entity: Entity, relation: Component, filter: AnyFilter?)
1908
- local entity_tracked = server.track_info.entities[entity]
1909
- if entity_tracked and entity_tracked.components[relation] then
1910
- server_replicator.change_relation(server, entity, relation, filter)
1911
- else
1912
- server_replicator.start_relation(server, entity, relation, filter)
1913
- end
1914
- end
1915
-
1916
- function server_replicator.set_custom(server: Server, entity: Entity, handler: Component | CustomId)
1917
- if server.custom_ids[entity] then
1918
- common.log_warn("attempted to register a custom_id twice for the same entity", debug.traceback())
1919
- return
1920
- end
1921
- server.custom_ids[entity] = handler
1922
- end
1923
-
1924
- function server_replicator.remove_custom(server: Server, entity: Entity)
1925
- server.custom_ids[entity] = nil
1926
- end
1927
-
1928
- function server_replicator.set_serdes(server: Server, component: Component, serdes: types.Serdes)
1929
- server.component_serdes[component] = serdes
1930
- server.is_shared_dirty = true
1931
- end
1932
-
1933
- function server_replicator.remove_serdes(server: Server, component: Component)
1934
- server.component_serdes[component] = nil
1935
- server.is_shared_dirty = true
1936
- end
1937
-
1938
- local function check_created(server: Server)
1939
- if server.inited == true then
1940
- warn "attempted to init a server twice"
1941
- return false
1942
- end
1943
- if server.inited == nil then
1944
- warn "attempted to init a destroyed server"
1945
- return false
1946
- end
1947
- return true
1948
- end
1949
-
1950
- function server_replicator.init(server: Server, wrd: World?)
1951
- if not check_created(server) then
1952
- return
1953
- end
1954
- server.inited = true :: any
1955
-
1956
- local world = wrd or server.world
1957
- server.world = world
1958
-
1959
- if not world then
1960
- error "Providing a world is required to start replecs"
1961
- end
1962
-
1963
- if not server.components then
1964
- server.components = utils.create_components(utils.tag_factory(world), utils.component_factory(world))
1965
- utils.add_component_names(server.components, function(component, name)
1966
- common.add_name(world, component, name)
1967
- end)
1968
- end
1969
-
1970
- local components = server.components
1971
-
1972
- local function hook(unhook: () -> ())
1973
- table.insert(server.hooked, unhook)
1974
- end
1975
-
1976
- hook(HOOK_ADDED(world, components.networked, function(entity, _, filter)
1977
- server_replicator.start_networked(server, entity, filter)
1978
- end))
1979
- hook(HOOK_CHANGED(world, components.networked, function(entity, _, filter)
1980
- server_replicator.change_networked(server, entity, filter)
1981
- end))
1982
- hook(HOOK_REMOVED(world, components.networked, function(entity)
1983
- server_replicator.stop_networked(server, entity)
1984
- end))
1985
-
1986
- if RELATIONSHIPS then
1987
- hook(HOOK_ADDED(world, LISTEN_RELATION(components.reliable), function(entity, id, filter)
1988
- local component = PAIR_SECOND(world, id)
1989
- server_replicator.start_reliable(server, entity, component, filter)
1990
- end))
1991
- hook(HOOK_CHANGED(world, LISTEN_RELATION(components.reliable), function(entity, id, filter)
1992
- local component = PAIR_SECOND(world, id)
1993
- server_replicator.change_reliable(server, entity, component, filter)
1994
- end))
1995
- hook(HOOK_REMOVED(world, LISTEN_RELATION(components.reliable), function(entity, id)
1996
- local component = PAIR_SECOND(world, id)
1997
- server_replicator.stop_reliable(server, entity, component)
1998
- end))
1999
-
2000
- hook(HOOK_ADDED(world, LISTEN_RELATION(components.relation), function(entity, id, filter)
2001
- local relation = PAIR_SECOND(world, id)
2002
- server_replicator.start_relation(server, entity, relation, filter)
2003
- end))
2004
- hook(HOOK_CHANGED(world, LISTEN_RELATION(components.relation), function(entity, id, filter)
2005
- local relation = PAIR_SECOND(world, id)
2006
- server_replicator.change_relation(server, entity, relation, filter)
2007
- end))
2008
- hook(HOOK_REMOVED(world, LISTEN_RELATION(components.relation), function(entity, id)
2009
- local relation = PAIR_SECOND(world, id)
2010
- server_replicator.stop_relation(server, entity, relation)
2011
- end))
2012
-
2013
- hook(HOOK_ADDED(world, LISTEN_RELATION(components.unreliable), function(entity, id, filter)
2014
- local component = PAIR_SECOND(world, id)
2015
- server_replicator.start_unreliable(server, entity, component, filter)
2016
- end))
2017
- hook(HOOK_CHANGED(world, LISTEN_RELATION(components.unreliable), function(entity, id, filter)
2018
- local component = PAIR_SECOND(world, id)
2019
- server_replicator.change_unreliable(server, entity, component, filter)
2020
- end))
2021
- hook(HOOK_REMOVED(world, LISTEN_RELATION(components.unreliable), function(entity, id)
2022
- local component = PAIR_SECOND(world, id)
2023
- server_replicator.stop_unreliable(server, entity, component)
2024
- end))
2025
-
2026
- hook(HOOK_ADDED(world, LISTEN_RELATION(components.custom), function(entity, id)
2027
- if not IS_PAIR(id) then
2028
- common.log_error "replecs.custom should be used with a relationship in the server"
2029
- end
2030
- local target = PAIR_SECOND(world, id)
2031
- server_replicator.set_custom(server, entity, target)
2032
- end))
2033
- hook(HOOK_REMOVED(world, LISTEN_RELATION(components.custom), function(entity)
2034
- server_replicator.remove_custom(server, entity)
2035
- end))
2036
- end
2037
- hook(HOOK_ADDED(world, components.global, function(entity, _, value)
2038
- if value > 245 then
2039
- common.log_error "global id size exceeded, max is 245"
2040
- end
2041
- server.global_ids[entity] = value
2042
- end))
2043
-
2044
- hook(HOOK_CHANGED(world, components.global, function(entity, _, value)
2045
- if value > 245 then
2046
- common.log_error "global id size exceeded, max is 245"
2047
- end
2048
- server.global_ids[entity] = value
2049
- end))
2050
- hook(HOOK_REMOVED(world, components.global, function(entity)
2051
- server.global_ids[entity] = nil
2052
- end))
2053
-
2054
- hook(HOOK_ADDED(world, components.serdes, function(component, _, serdes)
2055
- server_replicator.set_serdes(server, component, serdes)
2056
- end))
2057
- hook(HOOK_CHANGED(world, components.serdes, function(component, _, serdes)
2058
- server_replicator.set_serdes(server, component, serdes)
2059
- end))
2060
- hook(HOOK_REMOVED(world, components.serdes, function(component)
2061
- server_replicator.remove_serdes(server, component)
2062
- end))
2063
-
2064
- hook(HOOK_REMOVED(world, components.__alive_tracking__, function(entity)
2065
- if server.track_info.networked[entity] then
2066
- server_replicator.stop_networked(server, entity)
2067
- end
2068
- cleanup_entity(server, entity)
2069
- end))
2070
-
2071
- for _, component in server.requires_shared_lookup do
2072
- hook(HOOK_ADDED(world, component, function()
2073
- server.is_shared_dirty = true
2074
- end))
2075
- hook(HOOK_CHANGED(world, component, function()
2076
- server.is_shared_dirty = true
2077
- end))
2078
- hook(HOOK_REMOVED(world, component, function()
2079
- server.is_shared_dirty = true
2080
- end))
2081
- end
2082
-
2083
- QUERY_CURRENT_COMPONENTS(server)
2084
- QUERY_CURRENT_NETWORKED(server)
2085
-
2086
- server.shared = utils.resolved_shared(world, components, server.registered_custom_ids, server.component_serdes)
2087
-
2088
- if game and game:GetService("RunService"):IsServer() then
2089
- local Players = game:GetService "Players"
2090
-
2091
- local added = Players.PlayerAdded:Connect(function(player)
2092
- server.masking:register_client(player)
2093
- end)
2094
- local removed = Players.PlayerRemoving:Connect(function(player)
2095
- server.masking:unregister_client(player)
2096
- end)
2097
- for _, player in Players:GetPlayers() do
2098
- server.masking:register_client(player)
2099
- end
2100
-
2101
- table.insert(server.connections, added)
2102
- table.insert(server.connections, removed)
2103
- end
2104
- end
2105
-
2106
- function server_replicator.encode_component(server: Server, component: Entity): number
2107
- server_replicator.resolve_dirty(server)
2108
- local encoded = server.shared.components.members[component]
2109
- if not encoded then
2110
- common.log_error(`attempted to encode a non-shared component `, common.log_component(server.world, component))
2111
- return 0
2112
- end
2113
- return encoded
2114
- end
2115
-
2116
- function server_replicator.decode_component(server: Server, encoded: number): Entity?
2117
- server_replicator.resolve_dirty(server)
2118
- local component = server.shared.components.indexes[encoded]
2119
- return component
2120
- end
2121
-
2122
- function server_replicator.get_shared_count(server: Server): number
2123
- server_replicator.resolve_dirty(server)
2124
- return #server.shared.components.keys
2125
- end
2126
-
2127
- function server_replicator.mark_player_ready(server: Server, player: Player)
2128
- server.masking:activate_client(player)
2129
- end
2130
-
2131
- function server_replicator.is_player_ready(server: Server, player: Player): boolean
2132
- return server.masking:member_is_active(player)
2133
- end
2134
-
2135
- function server_replicator.add_player_alias(server: Server, client: Player, alias: any)
2136
- server.masking.client_aliases[alias] = client
2137
- end
2138
-
2139
- function server_replicator.remove_player_alias(server: Server, alias: any)
2140
- server.masking.client_aliases[alias] = nil
2141
- end
2142
-
2143
- function server_replicator.register_custom_id(server: Server, custom_id: CustomId)
2144
- server.registered_custom_ids[custom_id] = true
2145
- server.is_shared_dirty = true
2146
- end
2147
-
2148
- function server_replicator.generate_handshake(server: Server): types.HandshakeInfo
2149
- server_replicator.resolve_dirty(server)
2150
- return utils.generate_handshake(server.shared)
2151
- end
2152
-
2153
- function server_replicator.verify_handshake(server: Server, handshake: types.HandshakeInfo): (boolean, string?)
2154
- server_replicator.resolve_dirty(server)
2155
- return utils.verify_handshake(server.shared, handshake, "client", "server")
2156
- end
2157
-
2158
- function server_replicator.destroy(server: Server)
2159
- if server.inited == nil then
2160
- return warn "attempted to destroy a server twice"
2161
- end
2162
- server.inited = nil :: any
2163
-
2164
- for _, unhook in server.hooked do
2165
- unhook()
2166
- end
2167
- for _, connection in server.connections do
2168
- connection:Disconnect()
2169
- end
2170
- end
2171
-
2172
- local function create(world: World?, components: types.Components?): Server
2173
- local self = {} :: Server
2174
-
2175
- if components then
2176
- self.components = components
2177
- elseif world then
2178
- self.components = utils.create_components(utils.tag_factory(world), utils.component_factory(world))
2179
- utils.add_component_names(self.components, function(component, name)
2180
- common.add_name(world, component, name)
2181
- end)
2182
- end
2183
-
2184
- self.shared = {} :: types.Shared
2185
- self.world = world :: any
2186
- self.additions = {}
2187
- self.storage = {}
2188
- self.hooked = {}
2189
- self.is_shared_dirty = false
2190
- self.global_ids = {}
2191
- self.pending_cleanups = {}
2192
- self.track_info = {
2193
- networked = {},
2194
- entities = {},
2195
- components = {},
2196
- pairs = {},
2197
- }
2198
- self.connections = {}
2199
- self.inited = false
2200
- self.masking = masking_controller.create()
2201
- self.alive_tracked = {}
2202
- self.custom_ids = {}
2203
- self.registered_custom_ids = {}
2204
- self.component_serdes = {}
2205
- self.requires_shared_lookup = {
2206
- self.components.shared,
2207
- ECS_NAME,
2208
- }
2209
-
2210
- return setmetatable(self, server_replicator) :: any
2211
- end
2212
-
2213
- return {
2214
- create = create,
2215
- server_replicator = server_replicator,
2216
- }