class_name RegionalChunkedFileStore extends RefCounted const SCHEMA_VERSION := 1 const FORMAT_ID := "regional_chunked_file_store" const GENERATIONS_DIRECTORY := "generations" const MANIFEST_FILE_NAME := "manifest.bin" const CURRENT_POINTER_FILE_NAME := "current.bin" const PREVIOUS_POINTER_FILE_NAME := "current.previous.bin" const TEMP_POINTER_FILE_NAME := "current.next.bin" const GENERATION_PREFIX := "generation_" const GENERATION_DIGITS := 20 const MAX_BASE_PATH_LENGTH := 2048 const MAX_CHUNK_ID_LENGTH := 256 const MAX_CHUNKS := 100_000 const MAX_GENERATIONS := 4096 const MAX_MANIFEST_BYTES := 8 * 1024 * 1024 const MAX_CHUNK_BYTES := 32 * 1024 * 1024 const MAX_TOTAL_GENERATION_BYTES := 64 * 1024 * 1024 const MAX_POINTER_BYTES := 4096 var _base_directory: String var _absolute_base_directory := "" var _last_error := "" var _last_telemetry: Dictionary = {} func _init(base_directory: String) -> void: _base_directory = base_directory _absolute_base_directory = ProjectSettings.globalize_path(base_directory).simplify_path() _begin_telemetry("idle") func save(archive: RegionalChunkedPersistence) -> bool: _last_error = "" _begin_telemetry("save") if not _base_directory_is_safe(): return _fail("The caller-supplied regional save directory is unsafe") if archive == null: return _fail("Regional chunk archive is missing") var validation_started := Time.get_ticks_usec() var archive_bundle := archive.to_dictionary() var revalidated := RegionalChunkedPersistence.from_dictionary(archive_bundle) _add_validation_time(validation_started) if revalidated == null or revalidated.checksum() != archive.checksum(): return _fail("Regional chunk archive failed pre-write validation") var chunk_ids := archive.get_chunk_ids() if chunk_ids.is_empty() or chunk_ids.size() > MAX_CHUNKS: return _fail("Regional chunk count exceeds the filesystem contract") if not _ensure_directories(): return false var generation_ids := _list_generation_ids() if generation_ids.size() >= MAX_GENERATIONS: return _fail("Regional generation limit reached; explicit maintenance is required") var generation_id := _next_generation_id(generation_ids) if generation_id.is_empty(): return _fail("Could not allocate a bounded regional generation ID") var final_generation_path := _generation_path(generation_id) var temporary_generation_path := _allocate_temporary_generation_path(generation_id) if temporary_generation_path.is_empty(): return _fail("Could not allocate a temporary regional generation directory") var directory_error := DirAccess.make_dir_recursive_absolute(temporary_generation_path) if directory_error != OK and directory_error != ERR_ALREADY_EXISTS: return _fail("Could not create the temporary regional generation directory") var serialized_chunks: Array[PackedByteArray] = [] var chunk_files: Array[Dictionary] = [] var generation_bytes := 0 var archive_manifest := archive.get_manifest() var archive_descriptors: Array = archive_manifest["chunks"] for index in range(chunk_ids.size()): var chunk_id := chunk_ids[index] if chunk_id.length() > MAX_CHUNK_ID_LENGTH: return _fail("Regional chunk ID exceeds the bounded file-store contract") var chunk := archive.get_chunk(StringName(chunk_id)) if chunk.is_empty() or not _is_primitive_tree(chunk): return _fail("Regional chunk payload is not primitive-only") var serialized := var_to_bytes(chunk) if serialized.is_empty() or serialized.size() > MAX_CHUNK_BYTES: return _fail("Regional chunk exceeds the per-file size limit") generation_bytes += serialized.size() if generation_bytes > MAX_TOTAL_GENERATION_BYTES: return _fail("Regional generation exceeds the total size limit") serialized_chunks.append(serialized) var archive_descriptor: Dictionary = archive_descriptors[index] ( chunk_files . append( { "chunk_id": chunk_id, "file_name": _chunk_file_name(index), "serialized_bytes": serialized.size(), "file_checksum": _bytes_checksum(serialized), "canonical_checksum": String(archive_descriptor["checksum"]), } ) ) _last_telemetry["serialized_bytes"] += serialized.size() var generation_manifest := { "schema_version": SCHEMA_VERSION, "format_id": FORMAT_ID, "generation_id": generation_id, "archive_checksum": archive.checksum(), "envelope_checksum": String(archive_manifest["envelope_checksum"]), "archive_manifest": archive_manifest, "chunk_files": chunk_files, } if not _is_primitive_tree(generation_manifest): return _fail("Regional generation manifest is not primitive-only") var manifest_bytes := var_to_bytes(generation_manifest) if manifest_bytes.is_empty() or manifest_bytes.size() > MAX_MANIFEST_BYTES: return _fail("Regional generation manifest exceeds the size limit") generation_bytes += manifest_bytes.size() if generation_bytes > MAX_TOTAL_GENERATION_BYTES: return _fail("Regional generation exceeds the total size limit") _last_telemetry["serialized_bytes"] += manifest_bytes.size() for index in range(serialized_chunks.size()): var chunk_path := temporary_generation_path.path_join(_chunk_file_name(index)) if not _write_bytes(chunk_path, serialized_chunks[index]): return _fail("Could not write regional chunk file %d" % index) var manifest_path := temporary_generation_path.path_join(MANIFEST_FILE_NAME) if not _write_bytes(manifest_path, manifest_bytes): return _fail("Could not write the regional generation manifest") var readback := _read_generation_at_path(temporary_generation_path, generation_id, "") if readback == null or readback.checksum() != archive.checksum(): return _fail("Temporary regional generation failed exact readback validation") if DirAccess.rename_absolute(temporary_generation_path, final_generation_path) != OK: return _fail("Could not atomically install the regional generation") var pointer := { "schema_version": SCHEMA_VERSION, "format_id": FORMAT_ID, "generation_id": generation_id, "manifest_checksum": _bytes_checksum(manifest_bytes), "archive_checksum": archive.checksum(), } if not _install_current_pointer(pointer): return false _last_telemetry["generation_id"] = generation_id _last_telemetry["succeeded"] = true return true func load_archive() -> RegionalChunkedPersistence: _last_error = "" _begin_telemetry("load_archive") if not _base_directory_is_safe(): _fail("The caller-supplied regional save directory is unsafe") return null var pointer := _read_current_pointer() var pointer_generation_id := String(pointer.get("generation_id", "")) var pointer_manifest_checksum := String(pointer.get("manifest_checksum", "")) var pointer_archive_checksum := String(pointer.get("archive_checksum", "")) var generation_ids := _list_generation_ids() generation_ids.reverse() for generation_id: String in generation_ids: var expected_manifest_checksum := ( pointer_manifest_checksum if generation_id == pointer_generation_id else "" ) var archive := _read_generation(generation_id, expected_manifest_checksum) if archive == null: continue _last_telemetry["generation_id"] = generation_id _last_telemetry["recovered_generation"] = ( generation_id != pointer_generation_id or pointer_archive_checksum != archive.checksum() or _last_telemetry["pointer_mismatch"] ) _last_telemetry["succeeded"] = true return archive _fail("No valid regional generation could be recovered") return null func load_active_location_metadata(location_id: StringName) -> Dictionary: _last_error = "" _begin_telemetry("load_active_location_metadata") _last_telemetry["partial_load"] = true if not _base_directory_is_safe() or location_id.is_empty(): _fail("Regional active-location request is invalid") return {} var pointer := _read_current_pointer() var pointer_generation_id := String(pointer.get("generation_id", "")) var pointer_manifest_checksum := String(pointer.get("manifest_checksum", "")) var pointer_archive_checksum := String(pointer.get("archive_checksum", "")) var generation_ids := _list_generation_ids() generation_ids.reverse() for generation_id: String in generation_ids: var expected_manifest_checksum := ( pointer_manifest_checksum if generation_id == pointer_generation_id else "" ) var partial := _read_active_location_at_generation( generation_id, location_id, expected_manifest_checksum ) if bool(partial.get("location_absent", false)): _fail("The latest recoverable regional generation does not contain the location") return {} if partial.is_empty(): continue _last_telemetry["generation_id"] = generation_id _last_telemetry["recovered_generation"] = ( generation_id != pointer_generation_id or pointer_archive_checksum != String(partial["archive_checksum"]) or _last_telemetry["pointer_mismatch"] ) _last_telemetry["succeeded"] = true return partial _fail("No regional generation contains valid metadata for the active location") return {} func prune_old_generations(keep_valid_generations: int = 2) -> int: _last_error = "" _begin_telemetry("prune_old_generations") if not _base_directory_is_safe(): _fail("The caller-supplied regional save directory is unsafe") return 0 if keep_valid_generations < 2: _fail("Conservative pruning must keep at least two valid generations") return 0 var pointer := _read_current_pointer() var pointer_generation_id := String(pointer.get("generation_id", "")) var valid_generations: Array[Dictionary] = [] var generation_ids := _list_generation_ids() generation_ids.reverse() for generation_id: String in generation_ids: var archive := _read_generation(generation_id, "") if archive != null: ( valid_generations . append( { "generation_id": generation_id, "archive": archive, } ) ) var protected_ids: Dictionary = {} for index in range(mini(keep_valid_generations, valid_generations.size())): protected_ids[String(valid_generations[index]["generation_id"])] = true if not pointer_generation_id.is_empty(): protected_ids[pointer_generation_id] = true var pruned := 0 for candidate: Dictionary in valid_generations: var generation_id := String(candidate["generation_id"]) if protected_ids.has(generation_id): continue var archive: RegionalChunkedPersistence = candidate["archive"] if not _remove_valid_generation(generation_id, archive): _fail("Conservative regional generation pruning stopped on an unexpected layout") _last_telemetry["generations_pruned"] = pruned return pruned pruned += 1 _last_telemetry["generations_pruned"] = pruned _last_telemetry["succeeded"] = true return pruned func get_base_directory() -> String: return _base_directory func get_generations_directory() -> String: return _base_directory.path_join(GENERATIONS_DIRECTORY) func get_current_pointer_path() -> String: return _base_directory.path_join(CURRENT_POINTER_FILE_NAME) func get_generation_ids() -> Array[String]: return _list_generation_ids() if _base_directory_is_safe() else [] func get_generation_directory(generation_id: String) -> String: if not _is_generation_id(generation_id): return "" return get_generations_directory().path_join(generation_id) func get_last_error() -> String: return _last_error func get_last_telemetry() -> Dictionary: return _last_telemetry.duplicate(true) func _read_generation( generation_id: String, expected_manifest_checksum: String ) -> RegionalChunkedPersistence: if not _is_generation_id(generation_id): return null return _read_generation_at_path( _generation_path(generation_id), generation_id, expected_manifest_checksum ) func _read_generation_at_path( generation_path: String, generation_id: String, expected_manifest_checksum: String ) -> RegionalChunkedPersistence: _last_telemetry["candidates_validated"] += 1 var manifest_bytes := _read_bytes( generation_path.path_join(MANIFEST_FILE_NAME), MAX_MANIFEST_BYTES ) if manifest_bytes.is_empty(): return null if ( not expected_manifest_checksum.is_empty() and _bytes_checksum(manifest_bytes) != expected_manifest_checksum ): _last_telemetry["pointer_mismatch"] = true var validation_started := Time.get_ticks_usec() var decoded_manifest: Variant = bytes_to_var(manifest_bytes) if ( not decoded_manifest is Dictionary or not _is_primitive_tree(decoded_manifest) or not _generation_manifest_is_valid(decoded_manifest, generation_id) ): _add_validation_time(validation_started) return null var generation_manifest: Dictionary = decoded_manifest _add_validation_time(validation_started) var chunks: Array[Dictionary] = [] var generation_bytes := manifest_bytes.size() for raw_entry: Variant in generation_manifest["chunk_files"]: var entry: Dictionary = raw_entry var chunk := _read_chunk_file(generation_path, entry) if chunk.is_empty(): return null generation_bytes += int(entry["serialized_bytes"]) if generation_bytes > MAX_TOTAL_GENERATION_BYTES: return null chunks.append(chunk) var archive_manifest: Dictionary = generation_manifest["archive_manifest"] var bundle := { "schema_version": RegionalChunkedPersistence.SCHEMA_VERSION, "manifest": archive_manifest.duplicate(true), "chunks": chunks, } validation_started = Time.get_ticks_usec() var archive := RegionalChunkedPersistence.from_dictionary(bundle) _add_validation_time(validation_started) if ( archive == null or archive.checksum() != String(generation_manifest["archive_checksum"]) or ( String(archive.get_manifest()["envelope_checksum"]) != String(generation_manifest["envelope_checksum"]) ) ): return null return archive func _read_active_location_at_generation( generation_id: StringName, location_id: StringName, expected_manifest_checksum: String ) -> Dictionary: if not _is_generation_id(String(generation_id)): return {} _last_telemetry["candidates_validated"] += 1 var generation_path := _generation_path(String(generation_id)) var manifest_bytes := _read_bytes( generation_path.path_join(MANIFEST_FILE_NAME), MAX_MANIFEST_BYTES ) if manifest_bytes.is_empty(): return {} if ( not expected_manifest_checksum.is_empty() and _bytes_checksum(manifest_bytes) != expected_manifest_checksum ): _last_telemetry["pointer_mismatch"] = true var validation_started := Time.get_ticks_usec() var decoded_manifest: Variant = bytes_to_var(manifest_bytes) if ( not decoded_manifest is Dictionary or not _is_primitive_tree(decoded_manifest) or not _generation_manifest_is_valid(decoded_manifest, String(generation_id)) ): _add_validation_time(validation_started) return {} var generation_manifest: Dictionary = decoded_manifest var archive_manifest: Dictionary = generation_manifest["archive_manifest"] var archive_descriptors: Array = archive_manifest["chunks"] var chunk_entries: Array = generation_manifest["chunk_files"] var location_chunk_id := "location:%s" % location_id var global_entry: Dictionary = {} var location_entry: Dictionary = {} for index in range(archive_descriptors.size()): var descriptor: Dictionary = archive_descriptors[index] if String(descriptor["chunk_id"]) == RegionalChunkedPersistence.GLOBAL_CHUNK_ID: global_entry = chunk_entries[index] elif String(descriptor["chunk_id"]) == location_chunk_id: location_entry = chunk_entries[index] _add_validation_time(validation_started) if global_entry.is_empty(): return {} var global_chunk := _read_chunk_file(generation_path, global_entry) if ( global_chunk.is_empty() or not _chunk_header_is_valid(global_chunk) or String(global_chunk.get("chunk_type", "")) != RegionalChunkedPersistence.CHUNK_GLOBAL or not global_chunk.get("payload") is Dictionary ): return {} var global_payload: Dictionary = global_chunk["payload"] if not global_payload.get("location_ids") is Array: return {} if String(location_id) not in global_payload["location_ids"]: return {"location_absent": true} if location_entry.is_empty(): return {} var location_chunk := _read_chunk_file(generation_path, location_entry) if ( location_chunk.is_empty() or not _chunk_header_is_valid(location_chunk) or String(location_chunk.get("chunk_type", "")) != RegionalChunkedPersistence.CHUNK_LOCATION or String(location_chunk.get("scope_id", "")) != String(location_id) or not location_chunk.get("payload") is Dictionary ): return {} var location_payload: Dictionary = location_chunk["payload"] if ( String(global_payload.get("world_id", "")) != String(archive_manifest["world_id"]) or String(location_payload.get("world_id", "")) != String(archive_manifest["world_id"]) or String(location_payload.get("location_id", "")) != String(location_id) ): return {} var loaded_chunk_ids: Array[String] = [ RegionalChunkedPersistence.GLOBAL_CHUNK_ID, location_chunk_id ] var unloaded_chunk_ids: Array[String] = [] var mobile_group_refs: Array[Dictionary] = [] for raw_descriptor: Variant in archive_descriptors: var descriptor: Dictionary = raw_descriptor var chunk_id := String(descriptor["chunk_id"]) if chunk_id not in loaded_chunk_ids: unloaded_chunk_ids.append(chunk_id) if ( String(descriptor["chunk_type"]) == RegionalChunkedPersistence.CHUNK_MOBILE_GROUP and String(descriptor["location_id"]) == String(location_id) ): ( mobile_group_refs . append( { "group_id": String(descriptor["scope_id"]), "chunk_id": chunk_id, } ) ) return { "schema_version": RegionalChunkedPersistence.SCHEMA_VERSION, "world_id": String(archive_manifest["world_id"]), "active_location_id": String(location_id), "loaded_chunk_ids": loaded_chunk_ids, "unloaded_chunk_ids": unloaded_chunk_ids, "global_index": global_payload.duplicate(true), "active_location": location_payload.duplicate(true), "mobile_group_refs": mobile_group_refs, "envelope_checksum": String(archive_manifest["envelope_checksum"]), "generation_id": String(generation_id), "archive_checksum": String(generation_manifest["archive_checksum"]), "full_generation_validated": false, } func _read_chunk_file(generation_path: String, entry: Dictionary) -> Dictionary: var serialized_bytes := int(entry["serialized_bytes"]) if serialized_bytes <= 0 or serialized_bytes > MAX_CHUNK_BYTES: return {} var chunk_bytes := _read_bytes( generation_path.path_join(String(entry["file_name"])), MAX_CHUNK_BYTES ) if ( chunk_bytes.size() != serialized_bytes or _bytes_checksum(chunk_bytes) != String(entry["file_checksum"]) ): return {} var validation_started := Time.get_ticks_usec() var decoded_chunk: Variant = bytes_to_var(chunk_bytes) if not decoded_chunk is Dictionary or not _is_primitive_tree(decoded_chunk): _add_validation_time(validation_started) return {} var chunk: Dictionary = decoded_chunk if ( String(chunk.get("chunk_id", "")) != String(entry["chunk_id"]) or JSON.stringify(chunk).sha256_text() != String(entry["canonical_checksum"]) ): _add_validation_time(validation_started) return {} _add_validation_time(validation_started) return chunk func _generation_manifest_is_valid(manifest: Dictionary, generation_id: String) -> bool: var fields := [ "schema_version", "format_id", "generation_id", "archive_checksum", "envelope_checksum", "archive_manifest", "chunk_files", ] if manifest.size() != fields.size() or not manifest.has_all(fields): return false if ( not manifest["schema_version"] is int or int(manifest["schema_version"]) != SCHEMA_VERSION or not manifest["format_id"] is String or String(manifest["format_id"]) != FORMAT_ID or not manifest["generation_id"] is String or String(manifest["generation_id"]) != generation_id or not _is_generation_id(generation_id) or not _is_sha256(manifest["archive_checksum"]) or not _is_sha256(manifest["envelope_checksum"]) or not manifest["archive_manifest"] is Dictionary or not manifest["chunk_files"] is Array ): return false var archive_manifest: Dictionary = manifest["archive_manifest"] var archive_fields := [ "schema_version", "format_id", "world_id", "envelope_checksum", "event_segment_size", "chunk_count", "chunks", ] if ( archive_manifest.size() != archive_fields.size() or not archive_manifest.has_all(archive_fields) or not archive_manifest["schema_version"] is int or not archive_manifest["format_id"] is String or not archive_manifest["world_id"] is String or String(archive_manifest["world_id"]).is_empty() or not archive_manifest["envelope_checksum"] is String or not archive_manifest["event_segment_size"] is int or not archive_manifest["chunks"] is Array or not archive_manifest["chunk_count"] is int or int(archive_manifest["chunk_count"]) <= 0 or int(archive_manifest["chunk_count"]) > MAX_CHUNKS or (archive_manifest["chunks"] as Array).size() != int(archive_manifest["chunk_count"]) or (manifest["chunk_files"] as Array).size() != int(archive_manifest["chunk_count"]) or String(archive_manifest["format_id"]) != RegionalChunkedPersistence.FORMAT_ID or int(archive_manifest["schema_version"]) != RegionalChunkedPersistence.SCHEMA_VERSION or String(archive_manifest["envelope_checksum"]) != String(manifest["envelope_checksum"]) ): return false var ids: Dictionary = {} var archive_descriptors: Array = archive_manifest["chunks"] var chunk_files: Array = manifest["chunk_files"] for index in range(archive_descriptors.size()): var descriptor: Variant = archive_descriptors[index] var entry: Variant = chunk_files[index] if not descriptor is Dictionary or not entry is Dictionary: return false var descriptor_fields := [ "chunk_id", "chunk_type", "scope_id", "location_id", "route_id", "record_count", "byte_size", "checksum", ] var entry_fields := [ "chunk_id", "file_name", "serialized_bytes", "file_checksum", "canonical_checksum", ] if ( descriptor.size() != descriptor_fields.size() or not descriptor.has_all(descriptor_fields) or entry.size() != entry_fields.size() or not entry.has_all(entry_fields) ): return false var chunk_id := String(entry["chunk_id"]) if ( not descriptor["chunk_id"] is String or not descriptor["chunk_type"] is String or not descriptor["scope_id"] is String or not descriptor["location_id"] is String or not descriptor["route_id"] is String or not descriptor["record_count"] is int or not descriptor["byte_size"] is int or not descriptor["checksum"] is String or not entry["chunk_id"] is String or not entry["file_name"] is String or not entry["file_checksum"] is String or not entry["canonical_checksum"] is String or chunk_id.is_empty() or chunk_id.length() > MAX_CHUNK_ID_LENGTH or ids.has(chunk_id) or String(descriptor.get("chunk_id", "")) != chunk_id or String(entry["file_name"]) != _chunk_file_name(index) or not _is_safe_file_name(entry["file_name"]) or not entry["serialized_bytes"] is int or int(entry["serialized_bytes"]) <= 0 or int(entry["serialized_bytes"]) > MAX_CHUNK_BYTES or not _is_sha256(entry["file_checksum"]) or not _is_sha256(entry["canonical_checksum"]) or String(descriptor.get("checksum", "")) != String(entry["canonical_checksum"]) ): return false ids[chunk_id] = true return true func _chunk_header_is_valid(chunk: Dictionary) -> bool: var fields := [ "schema_version", "chunk_id", "chunk_type", "scope_id", "location_id", "route_id", "payload" ] return ( chunk.size() == fields.size() and chunk.has_all(fields) and chunk["schema_version"] is int and int(chunk["schema_version"]) == RegionalChunkedPersistence.SCHEMA_VERSION and chunk["chunk_id"] is String and chunk["chunk_type"] is String and chunk["scope_id"] is String and chunk["location_id"] is String and chunk["route_id"] is String and chunk["payload"] is Dictionary ) func _install_current_pointer(pointer: Dictionary) -> bool: if not _pointer_is_valid(pointer): return _fail("Regional current pointer is invalid") var pointer_bytes := var_to_bytes(pointer) if pointer_bytes.is_empty() or pointer_bytes.size() > MAX_POINTER_BYTES: return _fail("Regional current pointer exceeds the size limit") _last_telemetry["serialized_bytes"] += pointer_bytes.size() var temporary_path := _absolute_base_directory.path_join(TEMP_POINTER_FILE_NAME) var current_path := _absolute_base_directory.path_join(CURRENT_POINTER_FILE_NAME) var previous_path := _absolute_base_directory.path_join(PREVIOUS_POINTER_FILE_NAME) _remove_file_if_present(temporary_path) if not _write_bytes(temporary_path, pointer_bytes): return _fail("Could not write the temporary regional current pointer") var readback_bytes := _read_bytes(temporary_path, MAX_POINTER_BYTES) var readback: Variant = bytes_to_var(readback_bytes) if not readback_bytes.is_empty() else null if not readback is Dictionary or readback != pointer or not _pointer_is_valid(readback): return _fail("Regional current pointer failed readback validation") if DirAccess.rename_absolute(temporary_path, current_path) == OK: return true _remove_file_if_present(previous_path) var had_current := FileAccess.file_exists(current_path) if had_current and DirAccess.rename_absolute(current_path, previous_path) != OK: return _fail("Could not preserve the previous regional current pointer") if DirAccess.rename_absolute(temporary_path, current_path) == OK: return true if had_current: DirAccess.rename_absolute(previous_path, current_path) return _fail("Could not atomically install the regional current pointer") func _read_current_pointer() -> Dictionary: var pointer_bytes := _read_bytes( _absolute_base_directory.path_join(CURRENT_POINTER_FILE_NAME), MAX_POINTER_BYTES ) if pointer_bytes.is_empty(): return {} var validation_started := Time.get_ticks_usec() var decoded_pointer: Variant = bytes_to_var(pointer_bytes) if ( not decoded_pointer is Dictionary or not _is_primitive_tree(decoded_pointer) or not _pointer_is_valid(decoded_pointer) ): _add_validation_time(validation_started) return {} _add_validation_time(validation_started) return decoded_pointer func _pointer_is_valid(pointer: Dictionary) -> bool: var fields := [ "schema_version", "format_id", "generation_id", "manifest_checksum", "archive_checksum" ] return ( pointer.size() == fields.size() and pointer.has_all(fields) and pointer["schema_version"] is int and int(pointer["schema_version"]) == SCHEMA_VERSION and pointer["format_id"] is String and String(pointer["format_id"]) == FORMAT_ID and pointer["generation_id"] is String and _is_generation_id(String(pointer["generation_id"])) and _is_sha256(pointer["manifest_checksum"]) and _is_sha256(pointer["archive_checksum"]) ) func _ensure_directories() -> bool: var base_error := DirAccess.make_dir_recursive_absolute(_absolute_base_directory) if base_error != OK and base_error != ERR_ALREADY_EXISTS: return _fail("Could not create the caller-supplied regional save directory") var generations_error := DirAccess.make_dir_recursive_absolute(_generations_path()) if generations_error != OK and generations_error != ERR_ALREADY_EXISTS: return _fail("Could not create the regional generations directory") return true func _base_directory_is_safe() -> bool: if ( _base_directory.is_empty() or _base_directory.length() > MAX_BASE_PATH_LENGTH or _base_directory.to_utf8_buffer().has(0) ): return false var normalized := _base_directory.replace("\\", "/") if normalized == "user://" or normalized == "res://": return false if not ( normalized.begins_with("user://") or normalized.begins_with("res://") or normalized.is_absolute_path() ): return false for segment: String in normalized.split("/", false): if segment == "." or segment == "..": return false if ( _absolute_base_directory.is_empty() or not _absolute_base_directory.is_absolute_path() or _absolute_base_directory == "/" or _absolute_base_directory.get_file().is_empty() ): return false return true func _list_generation_ids() -> Array[String]: var ids: Array[String] = [] var directory := DirAccess.open(_generations_path()) if directory == null: return ids for raw_name: String in directory.get_directories(): if _is_generation_id(raw_name): ids.append(raw_name) ids.sort() return ids func _next_generation_id(existing_ids: Array[String]) -> String: var next_sequence := 1 if not existing_ids.is_empty(): var last_id := existing_ids[-1] var last_sequence_text := last_id.substr(GENERATION_PREFIX.length()) var last_sequence := last_sequence_text.to_int() if last_sequence < 0 or last_sequence == 9_223_372_036_854_775_807: return "" next_sequence = last_sequence + 1 return GENERATION_PREFIX + str(next_sequence).pad_zeros(GENERATION_DIGITS) func _allocate_temporary_generation_path(generation_id: String) -> String: for attempt in range(16): var temporary_name := ( "temporary_%s_%016d_%02d" % [generation_id, Time.get_ticks_usec(), attempt] ) var candidate := _generations_path().path_join(temporary_name) if DirAccess.open(candidate) == null and not FileAccess.file_exists(candidate): return candidate return "" func _is_generation_id(generation_id: String) -> bool: if generation_id.length() != GENERATION_PREFIX.length() + GENERATION_DIGITS: return false if not generation_id.begins_with(GENERATION_PREFIX): return false var sequence_text := generation_id.substr(GENERATION_PREFIX.length()) for character: String in sequence_text: if character < "0" or character > "9": return false return sequence_text.to_int() > 0 func _chunk_file_name(index: int) -> String: return "chunk_%05d.bin" % index func _is_safe_file_name(file_name: Variant) -> bool: if not file_name is String: return false var value := String(file_name) if value.is_empty() or value.length() > 64 or value.get_file() != value: return false var allowed := "abcdefghijklmnopqrstuvwxyz0123456789_.-" for character: String in value: if not allowed.contains(character): return false return true func _is_sha256(value: Variant) -> bool: if not value is String or String(value).length() != 64: return false for character: String in String(value): if not "0123456789abcdef".contains(character): return false return true func _write_bytes(path: String, bytes: PackedByteArray) -> bool: var started_usec := Time.get_ticks_usec() var file := FileAccess.open(path, FileAccess.WRITE) if file == null: _last_telemetry["write_usec"] += Time.get_ticks_usec() - started_usec return false file.store_buffer(bytes) file.flush() var write_error := file.get_error() file.close() _last_telemetry["write_usec"] += Time.get_ticks_usec() - started_usec if write_error != OK: return false _last_telemetry["bytes_written"] += bytes.size() _last_telemetry["files_written"] += 1 return true func _read_bytes(path: String, maximum_bytes: int) -> PackedByteArray: var started_usec := Time.get_ticks_usec() var file := FileAccess.open(path, FileAccess.READ) if file == null: _last_telemetry["read_usec"] += Time.get_ticks_usec() - started_usec return PackedByteArray() var length := file.get_length() if length <= 0 or length > maximum_bytes: file.close() _last_telemetry["read_usec"] += Time.get_ticks_usec() - started_usec return PackedByteArray() var bytes := file.get_buffer(length) var read_error := file.get_error() file.close() _last_telemetry["read_usec"] += Time.get_ticks_usec() - started_usec if read_error != OK or bytes.size() != length: return PackedByteArray() _last_telemetry["bytes_read"] += bytes.size() _last_telemetry["files_read"] += 1 return bytes func _bytes_checksum(bytes: PackedByteArray) -> String: var hashing_context := HashingContext.new() hashing_context.start(HashingContext.HASH_SHA256) hashing_context.update(bytes) return hashing_context.finish().hex_encode() func _generations_path() -> String: return _absolute_base_directory.path_join(GENERATIONS_DIRECTORY) func _generation_path(generation_id: String) -> String: return _generations_path().path_join(generation_id) func _remove_file_if_present(path: String) -> void: if FileAccess.file_exists(path): DirAccess.remove_absolute(path) func _remove_valid_generation(generation_id: String, archive: RegionalChunkedPersistence) -> bool: if not _is_generation_id(generation_id) or archive == null: return false var generation_path := _generation_path(generation_id) if not generation_path.begins_with(_generations_path() + "/"): return false var directory := DirAccess.open(generation_path) if directory == null: return false directory.include_hidden = true if not directory.get_directories().is_empty(): return false var expected_files: Array[String] = [MANIFEST_FILE_NAME] for index in range(archive.get_chunk_ids().size()): expected_files.append(_chunk_file_name(index)) expected_files.sort() var actual_files: Array[String] = [] for file_name: String in directory.get_files(): actual_files.append(file_name) actual_files.sort() if actual_files != expected_files: return false var started_usec := Time.get_ticks_usec() for file_name: String in actual_files: if DirAccess.remove_absolute(generation_path.path_join(file_name)) != OK: _last_telemetry["write_usec"] += Time.get_ticks_usec() - started_usec return false _last_telemetry["files_deleted"] += 1 var remove_error := DirAccess.remove_absolute(generation_path) _last_telemetry["write_usec"] += Time.get_ticks_usec() - started_usec return remove_error == OK func _begin_telemetry(operation: String) -> void: _last_telemetry = { "operation": operation, "generation_id": "", "serialized_bytes": 0, "bytes_written": 0, "bytes_read": 0, "files_written": 0, "files_read": 0, "files_deleted": 0, "write_usec": 0, "read_usec": 0, "validation_usec": 0, "candidates_validated": 0, "recovered_generation": false, "pointer_mismatch": false, "generations_pruned": 0, "partial_load": false, "succeeded": false, } func _add_validation_time(started_usec: int) -> void: _last_telemetry["validation_usec"] += Time.get_ticks_usec() - started_usec func _fail(message: String) -> bool: _last_error = message return false static func _is_primitive_tree(value: Variant) -> bool: match typeof(value): TYPE_NIL, TYPE_BOOL, TYPE_INT, TYPE_STRING: return true TYPE_FLOAT: return is_finite(float(value)) TYPE_ARRAY: for item: Variant in value: if not _is_primitive_tree(item): return false return true TYPE_DICTIONARY: for key: Variant in value: if not key is String or not _is_primitive_tree(value[key]): return false return true return false