fix: stabilize rpg publish and launch

This commit is contained in:
kdletters
2026-05-21 20:20:06 +08:00
parent 224a26d318
commit a9d23a8a44
14 changed files with 614 additions and 82 deletions

View File

@@ -544,7 +544,7 @@ pub fn build_custom_world_published_profile_compile_snapshot(
let subtitle = resolve_text_field(&draft, &legacy, "subtitle").unwrap_or_default();
let summary_text = resolve_text_field(&draft, &legacy, "summary").unwrap_or_default();
let cover_image_src = resolve_cover_image_src(&draft, &legacy);
let theme_mode = resolve_theme_mode(&legacy);
let theme_mode = resolve_theme_mode(&draft, &legacy);
let playable_npc_count =
count_distinct_roles(draft.get("playableNpcs"), draft.get("storyNpcs"));
let landmark_count = to_array(draft.get("landmarks")).len() as u32;
@@ -912,11 +912,17 @@ fn resolve_text_field(
legacy: &Map<String, Value>,
key: &str,
) -> Option<String> {
// 中文注释:发布链路的草稿真相来自 session.draft_profile_json
// legacyResultProfile 只补历史草稿缺失字段,不能覆盖结果页刚保存的内容。
to_text(draft.get(key)).or_else(|| to_text(legacy.get(key)))
}
fn resolve_theme_mode(legacy: &Map<String, Value>) -> CustomWorldThemeMode {
to_text(legacy.get("themeMode"))
fn resolve_theme_mode(
draft: &Map<String, Value>,
legacy: &Map<String, Value>,
) -> CustomWorldThemeMode {
to_text(draft.get("themeMode"))
.or_else(|| to_text(legacy.get("themeMode")))
.and_then(|value| CustomWorldThemeMode::from_client_str(&value))
.unwrap_or(CustomWorldThemeMode::Mythic)
}
@@ -1067,6 +1073,47 @@ mod tests {
assert_eq!(error, CustomWorldFieldError::InvalidLegacyResultProfileJson);
}
#[test]
fn published_profile_compile_prefers_saved_draft_over_legacy_profile() {
let input = CustomWorldPublishedProfileCompileInput {
draft_profile_json: json!({
"name": "结果页保存后的世界",
"summary": "发布前最后一次填写的摘要。",
"themeMode": "tide",
"playableNpcs": [],
"storyNpcs": [],
"landmarks": []
})
.to_string(),
legacy_result_profile_json: Some(
json!({
"name": "旧结果页世界",
"summary": "旧摘要不应覆盖保存草稿。",
"themeMode": "mythic"
})
.to_string(),
),
..build_test_compile_input(None)
};
let snapshot = build_custom_world_published_profile_compile_snapshot(input)
.expect("compile should prefer saved draft");
let payload: Value = serde_json::from_str(&snapshot.compiled_profile_payload_json)
.expect("compiled payload should be json");
assert_eq!(snapshot.world_name, "结果页保存后的世界");
assert_eq!(snapshot.summary_text, "发布前最后一次填写的摘要。");
assert_eq!(snapshot.theme_mode, CustomWorldThemeMode::Tide);
assert_eq!(
payload.get("name").and_then(Value::as_str),
Some("结果页保存后的世界")
);
assert_eq!(
payload.get("summary").and_then(Value::as_str),
Some("发布前最后一次填写的摘要。")
);
}
#[test]
fn publish_setting_text_falls_back_to_draft_profile_when_seed_is_empty() {
let payload = Map::new();
@@ -1079,8 +1126,7 @@ mod tests {
.cloned()
.expect("draft profile should be object");
let setting_text =
resolve_custom_world_publish_setting_text(&payload, &draft_profile, "");
let setting_text = resolve_custom_world_publish_setting_text(&payload, &draft_profile, "");
assert_eq!(setting_text, "海雾会吞掉记错航线的人。");
}