1
This commit is contained in:
@@ -4,6 +4,7 @@ use axum::{
|
||||
http::StatusCode,
|
||||
response::Response,
|
||||
};
|
||||
use module_runtime::{SAVE_SNAPSHOT_VERSION, format_utc_micros};
|
||||
use serde::Deserialize;
|
||||
use serde_json::{Value, json};
|
||||
use shared_contracts::runtime::{
|
||||
@@ -70,8 +71,8 @@ pub async fn put_runtime_snapshot(
|
||||
let updated_at_micros = offset_datetime_to_unix_micros(now);
|
||||
let saved_at_micros = offset_datetime_to_unix_micros(saved_at);
|
||||
|
||||
let record = state
|
||||
.put_runtime_snapshot_record(
|
||||
let record = if is_non_persistent_runtime_snapshot(&payload.game_state) {
|
||||
build_transient_runtime_snapshot_record(
|
||||
user_id,
|
||||
saved_at_micros,
|
||||
payload.bottom_tab,
|
||||
@@ -79,10 +80,21 @@ pub async fn put_runtime_snapshot(
|
||||
payload.current_story,
|
||||
updated_at_micros,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
runtime_save_error_response(&request_context, map_runtime_save_client_error(error))
|
||||
})?;
|
||||
} else {
|
||||
state
|
||||
.put_runtime_snapshot_record(
|
||||
user_id,
|
||||
saved_at_micros,
|
||||
payload.bottom_tab,
|
||||
payload.game_state,
|
||||
payload.current_story,
|
||||
updated_at_micros,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
runtime_save_error_response(&request_context, map_runtime_save_client_error(error))
|
||||
})?
|
||||
};
|
||||
|
||||
Ok(json_success_body(
|
||||
Some(&request_context),
|
||||
@@ -184,6 +196,52 @@ fn build_saved_game_snapshot_response(
|
||||
}
|
||||
}
|
||||
|
||||
fn build_transient_runtime_snapshot_record(
|
||||
user_id: String,
|
||||
saved_at_micros: i64,
|
||||
bottom_tab: String,
|
||||
game_state: Value,
|
||||
current_story: Option<Value>,
|
||||
updated_at_micros: i64,
|
||||
) -> module_runtime::RuntimeSnapshotRecord {
|
||||
// 中文注释:预览/测试入口可得到本次响应,但不能覆盖用户正式当前快照。
|
||||
module_runtime::RuntimeSnapshotRecord {
|
||||
user_id,
|
||||
version: SAVE_SNAPSHOT_VERSION,
|
||||
saved_at: format_utc_micros(saved_at_micros),
|
||||
saved_at_micros,
|
||||
bottom_tab,
|
||||
game_state_json: game_state.to_string(),
|
||||
current_story_json: current_story.as_ref().map(Value::to_string),
|
||||
game_state,
|
||||
current_story,
|
||||
created_at_micros: updated_at_micros,
|
||||
updated_at_micros,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_non_persistent_runtime_snapshot(game_state: &Value) -> bool {
|
||||
let Some(game_state) = game_state.as_object() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
if game_state
|
||||
.get("runtimePersistenceDisabled")
|
||||
.and_then(Value::as_bool)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
matches!(
|
||||
game_state
|
||||
.get("runtimeMode")
|
||||
.and_then(Value::as_str)
|
||||
.map(str::trim),
|
||||
Some("preview") | Some("test")
|
||||
)
|
||||
}
|
||||
|
||||
fn build_profile_save_archive_summary_response(
|
||||
record: &module_runtime::RuntimeProfileSaveArchiveRecord,
|
||||
) -> ProfileSaveArchiveSummaryResponse {
|
||||
|
||||
Reference in New Issue
Block a user