SessionZero-Client/sessionzero-client/scripts/helpers/datapack_creator.gd

114 lines
3.5 KiB
GDScript

# datapack_creator.gd
class_name DatapackCreator
extends RefCounted
# --- UPDATED CONSTANTS ---
const BASE_DATAPACKS_PATH = "user://datapacks/"
const CONTENT_SUBDIR = "objects"
const METADATA_FILENAME = "config.szpack" # Renamed from METADATA_FILENAME
const DATAPACK_RESOURCE_FILENAME = "datapack.tres" # Renamed from DATAPACK_RESOURCE_FILENAME
const ASSETS_SUBDIR = "assets" # Renamed from MEDIA_SUBDIR
# --- INTERNAL STATE ---
var _saved_resources: Dictionary = {}
var _pack_base_path: String = ""
# --- PUBLIC METHOD ---
## Saves a DatapackModel and all its content resources to the file system.
## 'pack_name' is used to create the final folder structure: user://datapacks/[pack_name]/
func save_datapack(datapack: DatapackModel, pack_name: String) -> bool:
var full_pack_name = pack_name.validate_node_name()
if full_pack_name.is_empty():
push_error("DatapackCreator: Invalid pack_name provided.")
return false
_pack_base_path = BASE_DATAPACKS_PATH + full_pack_name + "/"
var content_path = _pack_base_path + CONTENT_SUBDIR
var assets_path = _pack_base_path + ASSETS_SUBDIR
var success_dirs = true
success_dirs &= _make_dir_recursive_safe(_pack_base_path)
success_dirs &= _make_dir_recursive_safe(content_path)
success_dirs &= _make_dir_recursive_safe(assets_path)
if not success_dirs:
push_error("DatapackCreator: Failed to create necessary directories.")
return false
_saved_resources.clear()
if not _save_content_objects(datapack.content_objects, content_path + "/"):
return false
var main_resource_path = _pack_base_path + DATAPACK_RESOURCE_FILENAME
if not _save_single_resource(datapack, main_resource_path):
return false
if not _write_metadata_file(datapack, _pack_base_path + METADATA_FILENAME):
return false
print("Datapack saved successfully to: %s" % _pack_base_path)
return true
# --- PRIVATE HELPER METHODS ---
func _make_dir_recursive_safe(path: String) -> bool:
var error = DirAccess.make_dir_recursive_absolute(path)
if error != OK and error != ERR_ALREADY_EXISTS:
push_error("DirAccess: Failed to create directory: %s (Error: %s)" % [path, error])
return false
return true
func _save_content_objects(objects: Array, save_path: String) -> bool:
var success = true
for obj in objects:
if not obj is SzObject:
push_error("DatapackCreator: Content array contains non-SzObject: %s" % obj)
success = false
continue
# Filename format: [class_name]_[id].tres
var filename = "%s_%s.tres" % [obj.get_class().to_lower(), obj.id.to_lower()]
var full_path = save_path + filename
if not _save_single_resource(obj, full_path):
success = false
return success
func _save_single_resource(resource: Resource, path: String) -> bool:
if _saved_resources.has(resource):
return true
var error = ResourceSaver.save(resource, path, ResourceSaver.FLAG_COMPRESS | ResourceSaver.FLAG_CHANGE_PATH)
if error != OK:
push_error("DatapackCreator: Failed to save resource at path '%s'. Error: %s" % [path, error])
return false
_saved_resources[resource] = path
return true
func _write_metadata_file(datapack: DatapackModel, path: String) -> bool:
var config = ConfigFile.new()
var section = "Datapack"
config.set_value(section, "guid", datapack.guid.to_string())
config.set_value(section, "name", datapack.name)
config.set_value(section, "version", datapack.version)
config.set_value(section, "entry_point", DATAPACK_RESOURCE_FILENAME)
var error = config.save(path)
if error != OK:
push_error("DatapackCreator: Failed to save metadata file at path '%s'. Error: %s" % [path, error])
return false
return true