1
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
use module_inventory::{RuntimeInventorySlotRecord, RuntimeInventoryStateRecord};
|
||||
use module_runtime_story::StoryRuntimeProjectionSource;
|
||||
use serde_json::{Map, Value, json};
|
||||
use shared_contracts::{
|
||||
runtime_story::RuntimeStoryOptionView,
|
||||
story::{StoryEventPayload, StorySessionPayload},
|
||||
};
|
||||
use shared_contracts::story::{StoryEventPayload, StorySessionPayload};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::*;
|
||||
@@ -43,7 +40,10 @@ impl SpacetimeClient {
|
||||
)?;
|
||||
let current_story = runtime_snapshot.current_story.as_ref();
|
||||
let latest_narrative_text = story_state.session.latest_narrative_text.clone();
|
||||
let server_version = runtime_snapshot.version.max(story_state.session.version);
|
||||
let server_version =
|
||||
resolve_story_runtime_server_version(&game_state, story_state.session.version);
|
||||
|
||||
let options = module_runtime_story::build_runtime_story_options(current_story, &game_state);
|
||||
|
||||
Ok(StoryRuntimeProjectionSource {
|
||||
story_session: build_story_session_payload(story_state.session),
|
||||
@@ -53,7 +53,7 @@ impl SpacetimeClient {
|
||||
.map(build_story_event_payload)
|
||||
.collect(),
|
||||
game_state,
|
||||
options: read_runtime_story_options(current_story)?,
|
||||
options,
|
||||
server_version,
|
||||
current_narrative_text: read_current_story_text(current_story)
|
||||
.or(Some(latest_narrative_text)),
|
||||
@@ -311,20 +311,6 @@ fn build_story_event_payload(record: StoryEventRecord) -> StoryEventPayload {
|
||||
}
|
||||
}
|
||||
|
||||
fn read_runtime_story_options(
|
||||
current_story: Option<&Value>,
|
||||
) -> Result<Vec<RuntimeStoryOptionView>, SpacetimeClientError> {
|
||||
let Some(options) = current_story.and_then(|story| story.get("options")) else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
|
||||
serde_json::from_value::<Vec<RuntimeStoryOptionView>>(options.clone()).map_err(|error| {
|
||||
SpacetimeClientError::Runtime(format!(
|
||||
"currentStory.options 无法映射为后端选项投影: {error}"
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
fn read_current_story_text(current_story: Option<&Value>) -> Option<String> {
|
||||
read_current_story_string(current_story, "text")
|
||||
.or_else(|| read_current_story_string(current_story, "storyText"))
|
||||
@@ -340,6 +326,20 @@ fn read_current_story_string(current_story: Option<&Value>, field: &str) -> Opti
|
||||
.map(ToOwned::to_owned)
|
||||
}
|
||||
|
||||
fn read_current_runtime_action_version(game_state: &Value) -> Option<u32> {
|
||||
game_state
|
||||
.as_object()?
|
||||
.get("runtimeActionVersion")?
|
||||
.as_u64()
|
||||
.and_then(|value| u32::try_from(value).ok())
|
||||
}
|
||||
|
||||
fn resolve_story_runtime_server_version(game_state: &Value, story_session_version: u32) -> u32 {
|
||||
read_current_runtime_action_version(game_state)
|
||||
.or(Some(story_session_version))
|
||||
.unwrap_or(1)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
@@ -434,16 +434,26 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn current_story_options_parse_runtime_story_options() {
|
||||
let options = read_runtime_story_options(Some(&json!({
|
||||
fn runtime_projection_source_uses_runtime_action_version() {
|
||||
let game_state = json!({
|
||||
"runtimeSessionId": "runtime_1",
|
||||
"runtimeActionVersion": 1
|
||||
});
|
||||
|
||||
assert_eq!(resolve_story_runtime_server_version(&game_state, 3), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn current_story_options_infer_scope_for_legacy_story_options() {
|
||||
let current_story = json!({
|
||||
"text": "守火人抬眼看着你。",
|
||||
"options": [{
|
||||
"functionId": "npc_chat",
|
||||
"actionText": "继续交谈",
|
||||
"scope": "npc"
|
||||
"actionText": "继续交谈"
|
||||
}]
|
||||
})))
|
||||
.expect("options should parse");
|
||||
});
|
||||
let options =
|
||||
module_runtime_story::build_runtime_story_options(Some(¤t_story), &json!({}));
|
||||
|
||||
assert_eq!(options[0].function_id, "npc_chat");
|
||||
assert_eq!(options[0].action_text, "继续交谈");
|
||||
|
||||
Reference in New Issue
Block a user