extends _BaseSnapshotSerializer class_name _DenseSnapshotSerializer static func _static_init(): _logger = NetfoxLogger._for_netfox("DenseSnapshotSerializer") func write_for(peer: int, snapshot: _Snapshot, properties: _PropertyPool, filter: Callable = _default_filter, buffer: StreamPeerBuffer = null) -> PackedByteArray: if buffer == null: buffer = StreamPeerBuffer.new() var netref := NetworkSchemas._netref() var varuint := NetworkSchemas.varuint() var node_buffer := StreamPeerBuffer.new() var has_data := false # Write tick buffer.put_u32(snapshot.tick) # For each node for subject in properties.get_subjects(): if not filter.call(subject): continue if not snapshot.is_auth(subject): continue var node := subject as Node assert(node.is_multiplayer_authority(), "Trying to serialize state for non-owned node!") assert(snapshot.is_auth(node), "Trying to serialize non-auth state node!") # Write identifier if _write_identifier(node, peer, buffer) != OK: continue # Write properties as-is # First into a buffer, so we can start with the state size node_buffer.clear() for property in properties.get_properties_of(node): assert(snapshot.has_property(node, property), "Trying to serialize missing property %s on subject %s!" % [property, node]) var value := snapshot.get_property(node, property) _write_property(node, property, value, node_buffer) # Indicate state size for the node varuint.encode(node_buffer.data_array.size(), buffer) # Write node state buffer.put_data(node_buffer.data_array) has_data = true if has_data: return buffer.data_array else: return PackedByteArray() func read_from(peer: int, properties: _PropertyPool, buffer: StreamPeerBuffer, is_auth: bool = true) -> _Snapshot: var netref := NetworkSchemas._netref() var varuint := NetworkSchemas.varuint() var node_buffer := StreamPeerBuffer.new() # Read tick var tick := buffer.get_u32() var snapshot := _Snapshot.new(tick) while buffer.get_available_bytes() > 0: # Read identity reference, data size, and data var idref := netref.decode(buffer) as _NetworkIdentityReference var node_data_size := varuint.decode(buffer) as int node_buffer.data_array = buffer.get_partial_data(node_data_size)[1] # Resolve to identifier var identifier := _get_identity_server()._resolve_reference(peer, idref) if not identifier: # TODO(#563): Handle unknown IDs gracefully _logger.warning("Received unknown identity reference %s, skipping data", [idref]) continue var node := identifier.get_subject() as Node # Read properties for property in properties.get_properties_of(node): if node_buffer.get_available_bytes() == 0: break var value := _read_property(node, property, node_buffer) snapshot.set_property(node, property, value) snapshot.set_auth(node, is_auth) return snapshot