2025-01-16 12:24:21 +00:00
|
|
|
@tool
|
2024-12-23 01:29:31 +00:00
|
|
|
extends Node
|
|
|
|
|
2025-01-05 11:25:13 +00:00
|
|
|
signal archive_loaded
|
2025-01-03 08:07:35 +00:00
|
|
|
|
2025-01-21 07:58:21 +00:00
|
|
|
static var archive: AssembledArchive
|
|
|
|
# current archive
|
2025-01-20 13:45:47 +00:00
|
|
|
static var user_root_dir := "user://data/" # must end with "/"
|
|
|
|
static var archive_dir := "user://data/archives/"
|
|
|
|
static var archive_prefix := "save"
|
2024-12-23 01:29:31 +00:00
|
|
|
|
2025-01-21 12:41:24 +00:00
|
|
|
var archives := {}
|
2024-12-23 01:29:31 +00:00
|
|
|
|
|
|
|
var autosave_timer := Timer.new()
|
|
|
|
|
2024-12-24 01:16:06 +00:00
|
|
|
|
2025-01-16 12:24:21 +00:00
|
|
|
func _ready() -> void:
|
2025-01-14 10:20:31 +00:00
|
|
|
# 禁用默认退出行为,在 _notification 处理 NOTIFICATION_WM_CLOSE_REQUEST 时保存数据
|
2024-12-27 13:32:12 +00:00
|
|
|
get_tree().set_auto_accept_quit(false)
|
2024-12-24 11:24:55 +00:00
|
|
|
if not _check_dirs_and_archives():
|
2024-12-24 11:54:30 +00:00
|
|
|
_handle_load_error("存档目录", "读写")
|
2024-12-23 01:29:31 +00:00
|
|
|
return
|
|
|
|
autosave_timer.timeout.connect(_try_auto_save)
|
|
|
|
autosave_timer.stop()
|
2024-12-24 11:24:55 +00:00
|
|
|
add_child(autosave_timer)
|
|
|
|
# config should be loaded first
|
|
|
|
load_config()
|
2025-01-14 10:20:31 +00:00
|
|
|
# 在 debug or editor 模式下,直接保证有 archive
|
|
|
|
if GlobalConfig.DEBUG or Engine.is_editor_hint():
|
2024-12-24 11:24:55 +00:00
|
|
|
if archives.size() == 0:
|
|
|
|
create_and_use_new_archive()
|
|
|
|
else:
|
2025-01-21 12:41:24 +00:00
|
|
|
# debug 模式下默认使用 0 号存档
|
|
|
|
GlobalConfigManager.config.current_selected_archive_id = 0
|
2024-12-24 11:24:55 +00:00
|
|
|
|
|
|
|
|
2024-12-27 13:32:12 +00:00
|
|
|
func _notification(what):
|
|
|
|
# handle window close request
|
|
|
|
if what == NOTIFICATION_WM_CLOSE_REQUEST:
|
2025-01-07 10:54:50 +00:00
|
|
|
save_all()
|
2025-01-05 11:25:13 +00:00
|
|
|
if has_node("/root/Main"):
|
|
|
|
print("Saved all success before Quit")
|
2025-01-24 14:19:17 +00:00
|
|
|
# 已保存所有数据 [ID:ui_saved_all]
|
|
|
|
SceneManager.pop_notification(tr("ui_saved_all"))
|
2025-01-05 11:25:13 +00:00
|
|
|
var tree = get_tree()
|
|
|
|
tree.create_timer(1.5).timeout.connect(tree.quit)
|
|
|
|
else:
|
|
|
|
get_tree().quit()
|
2024-12-27 13:32:12 +00:00
|
|
|
|
|
|
|
|
2025-01-03 08:07:35 +00:00
|
|
|
func _on_archive_id_changed():
|
2024-12-24 11:24:55 +00:00
|
|
|
var selected_id = GlobalConfigManager.config.current_selected_archive_id
|
2025-01-21 12:41:24 +00:00
|
|
|
if selected_id < 0:
|
|
|
|
return
|
2024-12-24 11:24:55 +00:00
|
|
|
if archive:
|
|
|
|
if selected_id != archive.archive_id:
|
|
|
|
ResourceSaver.save(archive)
|
|
|
|
archive = null
|
|
|
|
else:
|
|
|
|
return
|
2025-01-21 12:41:24 +00:00
|
|
|
if not archives.has(selected_id):
|
2024-12-24 11:24:55 +00:00
|
|
|
create_and_use_new_archive(selected_id)
|
2025-01-24 14:19:17 +00:00
|
|
|
# 已创建新存档 [ID:ui_new_archive]
|
|
|
|
SceneManager.pop_notification(tr("ui_new_archive"))
|
2024-12-24 11:24:55 +00:00
|
|
|
else:
|
|
|
|
load_archive()
|
2024-12-23 01:29:31 +00:00
|
|
|
|
|
|
|
|
2025-01-16 12:24:21 +00:00
|
|
|
func check_autosave_options():
|
2025-01-21 12:41:24 +00:00
|
|
|
if (
|
|
|
|
GlobalConfigManager.config.auto_save_enabled
|
|
|
|
and archive
|
|
|
|
and GlobalConfigManager.config.auto_save_seconds > 1
|
|
|
|
):
|
2024-12-24 11:24:55 +00:00
|
|
|
# reset left time
|
|
|
|
autosave_timer.stop()
|
|
|
|
autosave_timer.one_shot = false
|
|
|
|
autosave_timer.wait_time = GlobalConfigManager.config.auto_save_seconds
|
2024-12-23 01:29:31 +00:00
|
|
|
autosave_timer.start()
|
2025-01-21 12:41:24 +00:00
|
|
|
else:
|
|
|
|
autosave_timer.stop()
|
|
|
|
|
2025-01-16 12:24:21 +00:00
|
|
|
if GlobalConfig.DEBUG:
|
|
|
|
print(
|
2025-01-21 10:08:16 +00:00
|
|
|
"check_autosave_option: ",
|
2025-01-16 12:24:21 +00:00
|
|
|
GlobalConfigManager.config.auto_save_enabled,
|
2025-01-21 10:08:16 +00:00
|
|
|
" wait_time=",
|
2025-01-16 12:24:21 +00:00
|
|
|
autosave_timer.wait_time
|
|
|
|
)
|
2024-12-23 01:29:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
func _try_auto_save():
|
2024-12-25 06:27:47 +00:00
|
|
|
if GlobalConfig.DEBUG:
|
|
|
|
print("Auto save")
|
2024-12-24 11:24:55 +00:00
|
|
|
if archive and GlobalConfigManager.config.auto_save_seconds > 1:
|
2024-12-23 01:29:31 +00:00
|
|
|
save_all()
|
2025-01-24 14:19:17 +00:00
|
|
|
# 自动保存成功 [ID:ui_auto_saved]
|
|
|
|
SceneManager.pop_notification(tr("ui_auto_saved"))
|
2024-12-23 01:29:31 +00:00
|
|
|
|
|
|
|
|
2024-12-24 11:24:55 +00:00
|
|
|
func _check_dirs_and_archives() -> bool:
|
|
|
|
if !DirAccess.dir_exists_absolute(user_root_dir):
|
|
|
|
DirAccess.make_dir_recursive_absolute(user_root_dir)
|
|
|
|
print("Create user_root_dir:", user_root_dir)
|
2024-12-23 01:29:31 +00:00
|
|
|
# Check if the archive directory is accessible
|
2024-12-24 11:24:55 +00:00
|
|
|
if !DirAccess.dir_exists_absolute(archive_dir):
|
|
|
|
DirAccess.make_dir_recursive_absolute(archive_dir)
|
|
|
|
print("Create archive_dir:", archive_dir)
|
|
|
|
var archive_dir_access = DirAccess.open(archive_dir)
|
2024-12-23 01:29:31 +00:00
|
|
|
if !archive_dir_access:
|
2024-12-24 11:24:55 +00:00
|
|
|
_handle_load_error("存档目录", "读取")
|
2024-12-23 01:29:31 +00:00
|
|
|
# TODO pop up a dialog to inform the user
|
|
|
|
return false
|
|
|
|
var files = archive_dir_access.get_files()
|
2025-01-21 12:41:24 +00:00
|
|
|
files.sort()
|
2024-12-23 01:29:31 +00:00
|
|
|
# get archive number
|
|
|
|
for file in files:
|
2025-01-21 12:41:24 +00:00
|
|
|
if file.begins_with(archive_prefix) and file.ends_with(GlobalConfig.RES_FILE_FORMAT):
|
|
|
|
var id_str = file.get_basename().substr(archive_prefix.length())
|
|
|
|
# 低于三位数的 id 会被忽略
|
|
|
|
if id_str.length() < 3:
|
|
|
|
continue
|
2024-12-23 01:29:31 +00:00
|
|
|
var id = int(id_str)
|
2025-01-21 12:41:24 +00:00
|
|
|
# 读取范围是 0-99
|
|
|
|
if id < 0 or id > 99:
|
|
|
|
continue
|
|
|
|
var path = archive_dir + file
|
|
|
|
if not archives.has(id):
|
|
|
|
archives[id] = ResourceLoader.load(
|
|
|
|
path, "AssembledArchive", ResourceLoader.CACHE_MODE_REPLACE_DEEP
|
|
|
|
)
|
2024-12-23 01:29:31 +00:00
|
|
|
return true
|
|
|
|
|
|
|
|
|
2024-12-24 11:24:55 +00:00
|
|
|
# id = -1 means create a new archive, otherwise create an archive with the given id
|
|
|
|
func create_and_use_new_archive(id := -1) -> void:
|
|
|
|
_check_dirs_and_archives()
|
|
|
|
archive = AssembledArchive.new()
|
2025-01-21 12:41:24 +00:00
|
|
|
var archive_path = _get_archive_path(id)
|
2024-12-24 11:24:55 +00:00
|
|
|
if id < 0:
|
|
|
|
id = 0
|
|
|
|
# find a new id
|
2025-01-21 12:41:24 +00:00
|
|
|
archive_path = _get_archive_path(id)
|
2024-12-24 11:24:55 +00:00
|
|
|
while FileAccess.file_exists(archive_path):
|
|
|
|
id += 1
|
2025-01-21 12:41:24 +00:00
|
|
|
archive_path = _get_archive_path(id)
|
2024-12-24 11:24:55 +00:00
|
|
|
archive.resource_path = archive_path
|
2024-12-24 11:54:30 +00:00
|
|
|
archive.archive_id = id
|
2024-12-24 11:24:55 +00:00
|
|
|
archive.created_time = Time.get_datetime_string_from_system(false, true)
|
|
|
|
ResourceSaver.save(archive, archive_path)
|
2025-01-21 12:41:24 +00:00
|
|
|
archives[id] = archive
|
2024-12-24 11:24:55 +00:00
|
|
|
# this will auto trigger signal and load the new archive
|
|
|
|
GlobalConfigManager.config.current_selected_archive_id = id
|
|
|
|
|
|
|
|
|
2025-01-21 12:41:24 +00:00
|
|
|
# 超过 999 个存档会出问题;不过这个游戏不会有这么多存档
|
|
|
|
func _get_archive_path(id: int) -> String:
|
|
|
|
var id_str := ""
|
|
|
|
if id < 10:
|
|
|
|
id_str = "00" + str(id)
|
|
|
|
elif id < 100:
|
|
|
|
id_str = "0" + str(id)
|
|
|
|
else:
|
|
|
|
id_str = str(id)
|
|
|
|
return archive_dir + archive_prefix + id_str + GlobalConfig.RES_FILE_FORMAT
|
|
|
|
|
|
|
|
|
2024-12-23 01:29:31 +00:00
|
|
|
func save_all() -> void:
|
|
|
|
# save config
|
|
|
|
var config = GlobalConfigManager.config
|
2024-12-24 11:24:55 +00:00
|
|
|
if config:
|
|
|
|
ResourceSaver.save(config)
|
2024-12-30 13:19:10 +00:00
|
|
|
|
|
|
|
# player_global_position
|
|
|
|
var player = SceneManager.get_player() as MainPlayer
|
2025-01-21 12:41:24 +00:00
|
|
|
# 在此处保存 player 的位置信息
|
2024-12-30 13:19:10 +00:00
|
|
|
if archive and player:
|
2025-01-20 13:45:47 +00:00
|
|
|
archive.player_global_position_x = player.global_position.x
|
2024-12-30 13:19:10 +00:00
|
|
|
archive.player_direction = player.facing_direction
|
2024-12-24 11:24:55 +00:00
|
|
|
if archive:
|
|
|
|
ResourceSaver.save(archive)
|
|
|
|
# reset autosave timer
|
2025-01-16 12:24:21 +00:00
|
|
|
check_autosave_options()
|
2024-12-24 11:24:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
func load_config() -> void:
|
|
|
|
if GlobalConfigManager.config:
|
2024-12-23 01:29:31 +00:00
|
|
|
return
|
2024-12-24 11:24:55 +00:00
|
|
|
var path = user_root_dir + "config" + GlobalConfig.RES_FILE_FORMAT
|
2024-12-23 01:29:31 +00:00
|
|
|
if FileAccess.file_exists(path):
|
2024-12-24 11:24:55 +00:00
|
|
|
var config = ResourceLoader.load(path)
|
|
|
|
GlobalConfigManager.config = config
|
2024-12-23 01:29:31 +00:00
|
|
|
else:
|
2024-12-24 11:24:55 +00:00
|
|
|
var config = GlobalConfig.new()
|
|
|
|
GlobalConfigManager.config = config
|
2024-12-23 01:29:31 +00:00
|
|
|
ResourceSaver.save(config, path)
|
2024-12-24 11:24:55 +00:00
|
|
|
GlobalConfigManager.config.resource_path = path
|
2025-01-17 10:45:40 +00:00
|
|
|
if Engine.is_editor_hint():
|
|
|
|
return
|
2024-12-24 11:24:55 +00:00
|
|
|
# connect signals
|
2025-01-03 08:07:35 +00:00
|
|
|
GlobalConfigManager.config.current_selected_archive_id_changed.connect(_on_archive_id_changed)
|
2025-01-16 12:24:21 +00:00
|
|
|
GlobalConfigManager.config.auto_save_seconds_changed.connect(check_autosave_options)
|
|
|
|
GlobalConfigManager.config.auto_save_enabled_changed.connect(check_autosave_options)
|
2024-12-24 11:24:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
func load_archive() -> void:
|
|
|
|
_check_dirs_and_archives()
|
|
|
|
var selected_id = GlobalConfigManager.config.current_selected_archive_id
|
2025-01-21 12:41:24 +00:00
|
|
|
if archive and selected_id == archive.archive_id:
|
|
|
|
return
|
2024-12-24 11:24:55 +00:00
|
|
|
if not archives.has(selected_id):
|
|
|
|
_handle_load_error(str(selected_id) + " 号存档", "查找")
|
|
|
|
return
|
2025-01-21 12:41:24 +00:00
|
|
|
archive = archives[selected_id]
|
|
|
|
# emit signal
|
|
|
|
archive_loaded.emit()
|
2025-01-16 12:24:21 +00:00
|
|
|
check_autosave_options()
|
2024-12-24 11:24:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
func _handle_load_error(target, action) -> void:
|
2024-12-24 11:54:30 +00:00
|
|
|
var msg = str(target) + " " + str(action) + " 失败,请检查文件访问权限"
|
2024-12-24 11:24:55 +00:00
|
|
|
SceneManager.pop_notification(msg)
|
|
|
|
printerr(msg)
|
|
|
|
# TODO handle error
|