feat: complete M3 runtime snapshot and profile save archive
This commit is contained in:
@@ -49,14 +49,19 @@ use module_npc::{
|
||||
use module_runtime::{
|
||||
RuntimeBrowseHistoryRecord, RuntimeBrowseHistoryThemeMode, RuntimePlatformTheme,
|
||||
RuntimeProfileDashboardRecord, RuntimeProfilePlayStatsRecord,
|
||||
RuntimeProfileSaveArchiveRecord,
|
||||
RuntimeProfileWalletLedgerEntryRecord, RuntimeProfileWalletLedgerSourceType,
|
||||
RuntimeSettingsRecord, build_runtime_browse_history_clear_input,
|
||||
RuntimeSettingsRecord, RuntimeSnapshotRecord, build_runtime_browse_history_clear_input,
|
||||
build_runtime_browse_history_list_input, build_runtime_browse_history_record,
|
||||
build_runtime_browse_history_sync_input, build_runtime_profile_dashboard_get_input,
|
||||
build_runtime_profile_dashboard_record, build_runtime_profile_play_stats_get_input,
|
||||
build_runtime_profile_play_stats_record, build_runtime_profile_wallet_ledger_entry_record,
|
||||
build_runtime_profile_play_stats_record, build_runtime_profile_save_archive_list_input,
|
||||
build_runtime_profile_save_archive_record, build_runtime_profile_save_archive_resume_input,
|
||||
build_runtime_profile_wallet_ledger_entry_record,
|
||||
build_runtime_profile_wallet_ledger_list_input, build_runtime_setting_get_input,
|
||||
build_runtime_setting_record, build_runtime_setting_upsert_input,
|
||||
build_runtime_snapshot_delete_input, build_runtime_snapshot_get_input,
|
||||
build_runtime_snapshot_record, build_runtime_snapshot_upsert_input,
|
||||
};
|
||||
use module_runtime_item::{
|
||||
RuntimeItemEquipmentSlot as DomainRuntimeItemEquipmentSlot,
|
||||
@@ -160,6 +165,10 @@ use crate::module_bindings::{
|
||||
RuntimeProfileDashboardGetInput as BindingRuntimeProfileDashboardGetInput,
|
||||
RuntimeProfileDashboardProcedureResult as BindingRuntimeProfileDashboardProcedureResult,
|
||||
RuntimeProfileDashboardSnapshot as BindingRuntimeProfileDashboardSnapshot,
|
||||
RuntimeProfileSaveArchiveListInput as BindingRuntimeProfileSaveArchiveListInput,
|
||||
RuntimeProfileSaveArchiveProcedureResult as BindingRuntimeProfileSaveArchiveProcedureResult,
|
||||
RuntimeProfileSaveArchiveResumeInput as BindingRuntimeProfileSaveArchiveResumeInput,
|
||||
RuntimeProfileSaveArchiveSnapshot as BindingRuntimeProfileSaveArchiveSnapshot,
|
||||
RuntimeProfilePlayStatsGetInput as BindingRuntimeProfilePlayStatsGetInput,
|
||||
RuntimeProfilePlayStatsProcedureResult as BindingRuntimeProfilePlayStatsProcedureResult,
|
||||
RuntimeProfilePlayStatsSnapshot as BindingRuntimeProfilePlayStatsSnapshot,
|
||||
@@ -172,6 +181,11 @@ use crate::module_bindings::{
|
||||
RuntimeSettingProcedureResult as BindingRuntimeSettingProcedureResult,
|
||||
RuntimeSettingSnapshot as BindingRuntimeSettingSnapshot,
|
||||
RuntimeSettingUpsertInput as BindingRuntimeSettingUpsertInput,
|
||||
RuntimeSnapshotDeleteInput as BindingRuntimeSnapshotDeleteInput,
|
||||
RuntimeSnapshotGetInput as BindingRuntimeSnapshotGetInput,
|
||||
RuntimeSnapshotProcedureResult as BindingRuntimeSnapshotProcedureResult,
|
||||
RuntimeSnapshot as BindingRuntimeSnapshot,
|
||||
RuntimeSnapshotUpsertInput as BindingRuntimeSnapshotUpsertInput,
|
||||
StoryContinueInput as BindingStoryContinueInput, StoryEventKind as BindingStoryEventKind,
|
||||
StoryEventSnapshot as BindingStoryEventSnapshot, StorySessionInput as BindingStorySessionInput,
|
||||
StorySessionProcedureResult as BindingStorySessionProcedureResult,
|
||||
@@ -192,6 +206,7 @@ use crate::module_bindings::{
|
||||
create_ai_task_and_return_procedure::create_ai_task_and_return as _,
|
||||
create_battle_state_and_return_procedure::create_battle_state_and_return as _,
|
||||
create_custom_world_agent_session_procedure::create_custom_world_agent_session as _,
|
||||
delete_runtime_snapshot_and_return_procedure::delete_runtime_snapshot_and_return as _,
|
||||
fail_ai_task_and_return_procedure::fail_ai_task_and_return as _,
|
||||
get_battle_state_procedure::get_battle_state as _,
|
||||
get_custom_world_agent_operation_procedure::get_custom_world_agent_operation as _,
|
||||
@@ -202,15 +217,18 @@ use crate::module_bindings::{
|
||||
get_profile_play_stats_procedure::get_profile_play_stats as _,
|
||||
get_runtime_inventory_state_procedure::get_runtime_inventory_state as _,
|
||||
get_runtime_setting_or_default_procedure::get_runtime_setting_or_default as _,
|
||||
get_runtime_snapshot_procedure::get_runtime_snapshot as _,
|
||||
get_story_session_state_procedure::get_story_session_state as _,
|
||||
list_custom_world_gallery_entries_procedure::list_custom_world_gallery_entries as _,
|
||||
list_custom_world_profiles_procedure::list_custom_world_profiles as _,
|
||||
list_platform_browse_history_procedure::list_platform_browse_history as _,
|
||||
list_profile_save_archives_procedure::list_profile_save_archives as _,
|
||||
list_profile_wallet_ledger_procedure::list_profile_wallet_ledger as _,
|
||||
publish_custom_world_profile_and_return_procedure::publish_custom_world_profile_and_return as _,
|
||||
publish_custom_world_world_procedure::publish_custom_world_world as _,
|
||||
resolve_combat_action_and_return_procedure::resolve_combat_action_and_return as _,
|
||||
resolve_npc_battle_interaction_and_return_procedure::resolve_npc_battle_interaction_and_return as _,
|
||||
resume_profile_save_archive_and_return_procedure::resume_profile_save_archive_and_return as _,
|
||||
start_ai_task_reducer::start_ai_task as _,
|
||||
start_ai_task_stage_reducer::start_ai_task_stage as _,
|
||||
submit_custom_world_agent_message_procedure::submit_custom_world_agent_message as _,
|
||||
@@ -218,6 +236,7 @@ use crate::module_bindings::{
|
||||
upsert_custom_world_profile_and_return_procedure::upsert_custom_world_profile_and_return as _,
|
||||
upsert_platform_browse_history_and_return_procedure::upsert_platform_browse_history_and_return as _,
|
||||
upsert_runtime_setting_and_return_procedure::upsert_runtime_setting_and_return as _,
|
||||
upsert_runtime_snapshot_and_return_procedure::upsert_runtime_snapshot_and_return as _,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -888,6 +907,136 @@ impl SpacetimeClient {
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_runtime_snapshot(
|
||||
&self,
|
||||
user_id: String,
|
||||
) -> Result<Option<RuntimeSnapshotRecord>, SpacetimeClientError> {
|
||||
let procedure_input = map_runtime_snapshot_get_input(
|
||||
build_runtime_snapshot_get_input(user_id)
|
||||
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
|
||||
);
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().get_runtime_snapshot_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_runtime_snapshot_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn put_runtime_snapshot(
|
||||
&self,
|
||||
user_id: String,
|
||||
saved_at_micros: i64,
|
||||
bottom_tab: String,
|
||||
game_state: serde_json::Value,
|
||||
current_story: Option<serde_json::Value>,
|
||||
updated_at_micros: i64,
|
||||
) -> Result<RuntimeSnapshotRecord, SpacetimeClientError> {
|
||||
let procedure_input = map_runtime_snapshot_upsert_input(
|
||||
build_runtime_snapshot_upsert_input(
|
||||
user_id,
|
||||
saved_at_micros,
|
||||
bottom_tab,
|
||||
game_state,
|
||||
current_story,
|
||||
updated_at_micros,
|
||||
)
|
||||
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
|
||||
);
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().upsert_runtime_snapshot_and_return_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_runtime_snapshot_required_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn delete_runtime_snapshot(
|
||||
&self,
|
||||
user_id: String,
|
||||
) -> Result<bool, SpacetimeClientError> {
|
||||
let procedure_input = map_runtime_snapshot_delete_input(
|
||||
build_runtime_snapshot_delete_input(user_id)
|
||||
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
|
||||
);
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().delete_runtime_snapshot_and_return_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_runtime_snapshot_delete_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn list_profile_save_archives(
|
||||
&self,
|
||||
user_id: String,
|
||||
) -> Result<Vec<RuntimeProfileSaveArchiveRecord>, SpacetimeClientError> {
|
||||
let procedure_input = map_runtime_profile_save_archive_list_input(
|
||||
build_runtime_profile_save_archive_list_input(user_id)
|
||||
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
|
||||
);
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().list_profile_save_archives_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_runtime_profile_save_archive_list_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn resume_profile_save_archive(
|
||||
&self,
|
||||
user_id: String,
|
||||
world_key: String,
|
||||
) -> Result<(RuntimeProfileSaveArchiveRecord, RuntimeSnapshotRecord), SpacetimeClientError> {
|
||||
let procedure_input = map_runtime_profile_save_archive_resume_input(
|
||||
build_runtime_profile_save_archive_resume_input(user_id, world_key)
|
||||
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
|
||||
);
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.resume_profile_save_archive_and_return_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_runtime_profile_save_archive_resume_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn begin_story_session(
|
||||
&self,
|
||||
story_session_id: String,
|
||||
@@ -1411,6 +1560,52 @@ fn map_runtime_profile_play_stats_get_input(
|
||||
}
|
||||
}
|
||||
|
||||
fn map_runtime_snapshot_get_input(
|
||||
input: module_runtime::RuntimeSnapshotGetInput,
|
||||
) -> BindingRuntimeSnapshotGetInput {
|
||||
BindingRuntimeSnapshotGetInput {
|
||||
user_id: input.user_id,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_runtime_snapshot_upsert_input(
|
||||
input: module_runtime::RuntimeSnapshotUpsertInput,
|
||||
) -> BindingRuntimeSnapshotUpsertInput {
|
||||
BindingRuntimeSnapshotUpsertInput {
|
||||
user_id: input.user_id,
|
||||
saved_at_micros: input.saved_at_micros,
|
||||
bottom_tab: input.bottom_tab,
|
||||
game_state_json: input.game_state_json,
|
||||
current_story_json: input.current_story_json,
|
||||
updated_at_micros: input.updated_at_micros,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_runtime_snapshot_delete_input(
|
||||
input: module_runtime::RuntimeSnapshotDeleteInput,
|
||||
) -> BindingRuntimeSnapshotDeleteInput {
|
||||
BindingRuntimeSnapshotDeleteInput {
|
||||
user_id: input.user_id,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_runtime_profile_save_archive_list_input(
|
||||
input: module_runtime::RuntimeProfileSaveArchiveListInput,
|
||||
) -> BindingRuntimeProfileSaveArchiveListInput {
|
||||
BindingRuntimeProfileSaveArchiveListInput {
|
||||
user_id: input.user_id,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_runtime_profile_save_archive_resume_input(
|
||||
input: module_runtime::RuntimeProfileSaveArchiveResumeInput,
|
||||
) -> BindingRuntimeProfileSaveArchiveResumeInput {
|
||||
BindingRuntimeProfileSaveArchiveResumeInput {
|
||||
user_id: input.user_id,
|
||||
world_key: input.world_key,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_ai_task_create_input(input: DomainAiTaskCreateInput) -> BindingAiTaskCreateInput {
|
||||
BindingAiTaskCreateInput {
|
||||
task_id: input.task_id,
|
||||
@@ -1786,6 +1981,89 @@ fn map_runtime_profile_play_stats_procedure_result(
|
||||
))
|
||||
}
|
||||
|
||||
fn map_runtime_snapshot_procedure_result(
|
||||
result: BindingRuntimeSnapshotProcedureResult,
|
||||
) -> Result<Option<RuntimeSnapshotRecord>, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
result
|
||||
.record
|
||||
.map(|snapshot| {
|
||||
build_runtime_snapshot_record(map_runtime_snapshot_snapshot(snapshot))
|
||||
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))
|
||||
})
|
||||
.transpose()
|
||||
}
|
||||
|
||||
fn map_runtime_snapshot_required_procedure_result(
|
||||
result: BindingRuntimeSnapshotProcedureResult,
|
||||
) -> Result<RuntimeSnapshotRecord, SpacetimeClientError> {
|
||||
map_runtime_snapshot_procedure_result(result)?.ok_or_else(|| {
|
||||
SpacetimeClientError::Procedure("SpacetimeDB procedure 未返回 runtime snapshot 快照".to_string())
|
||||
})
|
||||
}
|
||||
|
||||
fn map_runtime_snapshot_delete_procedure_result(
|
||||
result: BindingRuntimeSnapshotProcedureResult,
|
||||
) -> Result<bool, SpacetimeClientError> {
|
||||
map_runtime_snapshot_procedure_result(result).map(|record| record.is_some())
|
||||
}
|
||||
|
||||
fn map_runtime_profile_save_archive_list_procedure_result(
|
||||
result: BindingRuntimeProfileSaveArchiveProcedureResult,
|
||||
) -> Result<Vec<RuntimeProfileSaveArchiveRecord>, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
result
|
||||
.entries
|
||||
.into_iter()
|
||||
.map(|snapshot| {
|
||||
build_runtime_profile_save_archive_record(
|
||||
map_runtime_profile_save_archive_snapshot(snapshot),
|
||||
)
|
||||
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn map_runtime_profile_save_archive_resume_procedure_result(
|
||||
result: BindingRuntimeProfileSaveArchiveProcedureResult,
|
||||
) -> Result<(RuntimeProfileSaveArchiveRecord, RuntimeSnapshotRecord), SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
let archive = result.record.ok_or_else(|| {
|
||||
SpacetimeClientError::Procedure("SpacetimeDB procedure 未返回 save archive 快照".to_string())
|
||||
})?;
|
||||
let snapshot = result.current_snapshot.ok_or_else(|| {
|
||||
SpacetimeClientError::Procedure("SpacetimeDB procedure 未返回恢复后的 runtime snapshot".to_string())
|
||||
})?;
|
||||
|
||||
Ok((
|
||||
build_runtime_profile_save_archive_record(map_runtime_profile_save_archive_snapshot(archive))
|
||||
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
|
||||
build_runtime_snapshot_record(map_runtime_snapshot_snapshot(snapshot))
|
||||
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?,
|
||||
))
|
||||
}
|
||||
|
||||
fn map_ai_task_procedure_result(
|
||||
result: BindingAiTaskProcedureResult,
|
||||
) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
|
||||
@@ -2247,6 +2525,44 @@ fn map_runtime_profile_play_stats_snapshot(
|
||||
}
|
||||
}
|
||||
|
||||
fn map_runtime_snapshot_snapshot(
|
||||
snapshot: BindingRuntimeSnapshot,
|
||||
) -> module_runtime::RuntimeSnapshot {
|
||||
module_runtime::RuntimeSnapshot {
|
||||
user_id: snapshot.user_id,
|
||||
version: snapshot.version,
|
||||
saved_at_micros: snapshot.saved_at_micros,
|
||||
bottom_tab: snapshot.bottom_tab,
|
||||
game_state_json: snapshot.game_state_json,
|
||||
current_story_json: snapshot.current_story_json,
|
||||
created_at_micros: snapshot.created_at_micros,
|
||||
updated_at_micros: snapshot.updated_at_micros,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_runtime_profile_save_archive_snapshot(
|
||||
snapshot: BindingRuntimeProfileSaveArchiveSnapshot,
|
||||
) -> module_runtime::RuntimeProfileSaveArchiveSnapshot {
|
||||
module_runtime::RuntimeProfileSaveArchiveSnapshot {
|
||||
archive_id: snapshot.archive_id,
|
||||
user_id: snapshot.user_id,
|
||||
world_key: snapshot.world_key,
|
||||
owner_user_id: snapshot.owner_user_id,
|
||||
profile_id: snapshot.profile_id,
|
||||
world_type: snapshot.world_type,
|
||||
world_name: snapshot.world_name,
|
||||
subtitle: snapshot.subtitle,
|
||||
summary_text: snapshot.summary_text,
|
||||
cover_image_src: snapshot.cover_image_src,
|
||||
saved_at_micros: snapshot.saved_at_micros,
|
||||
bottom_tab: snapshot.bottom_tab,
|
||||
game_state_json: snapshot.game_state_json,
|
||||
current_story_json: snapshot.current_story_json,
|
||||
created_at_micros: snapshot.created_at_micros,
|
||||
updated_at_micros: snapshot.updated_at_micros,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_custom_world_library_entry_from_profile_snapshot(
|
||||
snapshot: BindingCustomWorldProfileSnapshot,
|
||||
) -> Result<CustomWorldLibraryEntryRecord, SpacetimeClientError> {
|
||||
|
||||
Reference in New Issue
Block a user