iter51-卡2

This commit is contained in:
DKChan committed 2026-11-04 05:08:31 +08:00
1 parent 1cd6e2b1b0
commit 372b4fdc31
27 files changed
+1231 -356

No files matched your search

+33 -13
View File
@@ -48,7 +48,7 @@ func _init(path: String = "") -> void:
# 无激活态(注入路径空,一切写盘路径拒绝并返回 false);玩家侧经选档界面显式进档/新档后才可写。
# 旧隐式单档一次性迁入槽 1(Q1 甲,sv12)在本口执行。
func _ready() -> void:
slots._migrate_legacy_save(LEGACY_SAVE_PATH, slots.slot_path(1), LEGACY_SAVE_PATH + LEGACY_MIGRATED_SUFFIX)
slots.migrate_legacy_save(LEGACY_SAVE_PATH, slots.slot_path(1), LEGACY_SAVE_PATH + LEGACY_MIGRATED_SUFFIX)
# 迁移注册口:from_version → from_version+1 的升级函数(读档时链式调用)。fn 契约:
@@ -63,10 +63,10 @@ func register_migration(from_version: int, fn: Callable) -> void:
# 损坏兜底:原文件改名 <path>.corrupt.bak(已存在则覆盖)+ push_warning + 默认数据继续——不静默丢档。
func load_from_disk() -> bool:
_read_only = false
if not FileAccess.file_exists(slots._path):
if not FileAccess.file_exists(slots.active_path()):
_data = _default_data() # 新档合法态
return true
var f := FileAccess.open(slots._path, FileAccess.READ)
var f := FileAccess.open(slots.active_path(), FileAccess.READ)
if f == null:
return _corrupt_fallback("读打开失败(%s)" % error_string(FileAccess.get_open_error()))
return _load_parsed(f)
@@ -102,21 +102,21 @@ func _load_parsed(f: FileAccess) -> bool:
# 无激活态一律拒绝并返回 false(sv3:启动态不隐式激活,盘面零触碰);
# 高版本拒读态一律拒绝(契约 4 禁写);写失败返回 false。
func write_to_disk() -> bool:
if slots._path == "":
if slots.active_path() == "":
push_error("[存档序列化] 写盘拒绝——无激活存档位(启动态不隐式激活;经选档进档/新档后落盘)")
return false
if _read_only:
push_error("[存档序列化] 写盘拒绝——档案版本高于当前(拒读禁写态)")
return false
var tmp := slots._path + ".tmp"
var tmp := slots.active_path() + ".tmp"
var f := FileAccess.open(tmp, FileAccess.WRITE)
if f == null:
push_error("[存档序列化] 临时文件打开失败:%s(%s)" % [tmp, error_string(FileAccess.get_open_error())])
return false
f.store_string(JSON.stringify(_data, "\t", true))
f.close()
if not _rename_overwrite(tmp, slots._path):
push_error("[存档序列化] 原子改名失败(tmp 保留待查):%s → %s" % [tmp, slots._path])
if not rename_overwrite(tmp, slots.active_path()):
push_error("[存档序列化] 原子改名失败(tmp 保留待查):%s → %s" % [tmp, slots.active_path()])
return false
return true
@@ -214,7 +214,7 @@ func _peek_migrated(parsed: Variant, fail: Array) -> Variant:
## 摘要窥视内核(只读推演单点——SlotStore 两 peek 方法经槽路径派生委托至此;
## 迁移链在此只读推演——生产迁移 Callable 为纯函数,零盘面副作用)
func _peek_summary_at(path: String) -> Dictionary:
func peek_summary_at(path: String) -> Dictionary:
var out := {"readable": false, "has_file": false, "keystone": 0, "cleared": 0, "total": 0}
if not FileAccess.file_exists(path):
out["readable"] = true # 空槽=可读零值合法态
@@ -275,15 +275,35 @@ func _default_data() -> Dictionary[String, Variant]:
}
# 原地重置默认态(SlotStore 槽位原语的协作口——激活/建删/换注回默认数据)
func _reset_to_default() -> void:
# 原地重置默认态(SlotStore 槽位原语的协作口——激活/建删/换注回默认数据;
# 公开化〔5.1 封装修复——SlotStore 反向私取承接,_reset_to_default 更名非并存〕)
func reset_to_default() -> void:
_data = _default_data()
# 禁写位公开面(SlotStore 激活/换注三态恢复消费——一行转发自有成员,零逻辑增量)
func set_read_only(v: bool) -> void:
_read_only = v
func read_only() -> bool:
return _read_only
# 数据快照还原公开面(SlotStore 激活/新建失败回退三态恢复消费——零拷贝语义:snapshot 返 _data
# 本引用、restore 直还引用,行为与原 _data 直读写逐位等价)
func data_snapshot() -> Dictionary[String, Variant]:
return _data
func restore_data(data: Dictionary[String, Variant]) -> void:
_data = data
# 损坏兜底:坏档改名 .corrupt.bak(已存在则覆盖)→ 默认数据继续。不静默丢档(警告留痕)、不 crash。
func _corrupt_fallback(reason: String) -> bool:
var bak := slots._path + ".corrupt.bak"
if not _rename_overwrite(slots._path, bak):
var bak := slots.active_path() + ".corrupt.bak"
if not rename_overwrite(slots.active_path(), bak):
push_warning("[存档序列化] 坏档备份改名失败(原文件保留原地):%s——%s" % [bak, reason])
else:
push_warning("[存档序列化] 检测到损坏档案,已备份为 %s——%s(用默认新档继续)" % [bak, reason])
@@ -314,7 +334,7 @@ func _normalize(data: Dictionary) -> Dictionary[String, Variant]:
# 覆盖式改名(Windows 原生 rename 目标已存在时会失败——先删后改,显式覆盖语义;IO 原语单点——
# SlotStore 迁移流经本件调用)
func _rename_overwrite(from: String, to: String) -> bool:
func rename_overwrite(from: String, to: String) -> bool:
var dir := DirAccess.open(from.get_base_dir())
if dir == null:
return false