Merge branch 'master' of http://82.157.175.59:3000/GenarrativeAI/Genarrative
This commit is contained in:
@@ -11,6 +11,7 @@ module-big-fish = { path = "../module-big-fish" }
|
||||
module-combat = { path = "../module-combat" }
|
||||
module-custom-world = { path = "../module-custom-world" }
|
||||
module-inventory = { path = "../module-inventory" }
|
||||
module-match3d = { path = "../module-match3d" }
|
||||
module-npc = { path = "../module-npc" }
|
||||
module-puzzle = { path = "../module-puzzle" }
|
||||
module-runtime = { path = "../module-runtime" }
|
||||
|
||||
@@ -32,6 +32,14 @@ pub use mapper::{
|
||||
PuzzleAgentSessionRecord, PuzzleAgentSuggestedActionRecord, PuzzleAnchorItemRecord,
|
||||
PuzzleAnchorPackRecord, PuzzleBoardRecord, PuzzleCellPositionRecord, PuzzleCreatorIntentRecord,
|
||||
PuzzleDraftLevelRecord, PuzzleFormDraftRecord, PuzzleFormDraftSaveRecordInput,
|
||||
Match3DAgentMessageFinalizeRecordInput, Match3DAgentMessageRecord,
|
||||
Match3DAgentMessageSubmitRecordInput, Match3DAgentSessionCreateRecordInput,
|
||||
Match3DAgentSessionRecord, Match3DAnchorItemRecord, Match3DAnchorPackRecord,
|
||||
Match3DClickConfirmationRecord, Match3DCompileDraftRecordInput, Match3DCreatorConfigRecord,
|
||||
Match3DItemSnapshotRecord, Match3DResultDraftRecord, Match3DRunClickRecordInput,
|
||||
Match3DRunRecord, Match3DRunRestartRecordInput, Match3DRunStartRecordInput,
|
||||
Match3DRunStopRecordInput, Match3DRunTimeUpRecordInput, Match3DTraySlotRecord,
|
||||
Match3DWorkProfileRecord, Match3DWorkUpdateRecordInput,
|
||||
PuzzleGeneratedImageCandidateRecord, PuzzleGeneratedImagesSaveRecordInput,
|
||||
PuzzleLeaderboardEntryRecord, PuzzleLeaderboardSubmitRecordInput, PuzzleMergedGroupRecord,
|
||||
PuzzlePieceStateRecord, PuzzlePublishRecordInput, PuzzleRecommendedNextWorkRecord,
|
||||
@@ -51,6 +59,7 @@ pub mod big_fish;
|
||||
pub mod combat;
|
||||
pub mod custom_world;
|
||||
pub mod inventory;
|
||||
pub mod match3d;
|
||||
pub mod npc;
|
||||
pub mod puzzle;
|
||||
pub mod runtime;
|
||||
@@ -124,7 +133,7 @@ use module_puzzle::{
|
||||
};
|
||||
use module_runtime::{
|
||||
RuntimeBrowseHistoryRecord, RuntimePlatformTheme as DomainRuntimePlatformTheme,
|
||||
RuntimeProfileDashboardRecord, RuntimeProfilePlayStatsRecord,
|
||||
RuntimeProfileDashboardRecord, RuntimeProfileInviteCodeRecord, RuntimeProfilePlayStatsRecord,
|
||||
RuntimeProfileRechargeCenterRecord, RuntimeProfileRechargeOrderRecord,
|
||||
RuntimeProfileRedeemCodeMode as DomainRuntimeProfileRedeemCodeMode,
|
||||
RuntimeProfileRedeemCodeRecord, RuntimeProfileRewardCodeRedeemRecord,
|
||||
@@ -133,7 +142,8 @@ use module_runtime::{
|
||||
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_dashboard_record, build_runtime_profile_invite_code_admin_upsert_input,
|
||||
build_runtime_profile_invite_code_record, build_runtime_profile_play_stats_get_input,
|
||||
build_runtime_profile_play_stats_record, build_runtime_profile_recharge_center_get_input,
|
||||
build_runtime_profile_recharge_center_record,
|
||||
build_runtime_profile_recharge_order_create_input,
|
||||
|
||||
@@ -203,6 +203,19 @@ impl From<module_runtime::RuntimeProfileRedeemCodeAdminDisableInput>
|
||||
}
|
||||
}
|
||||
|
||||
impl From<module_runtime::RuntimeProfileInviteCodeAdminUpsertInput>
|
||||
for RuntimeProfileInviteCodeAdminUpsertInput
|
||||
{
|
||||
fn from(input: module_runtime::RuntimeProfileInviteCodeAdminUpsertInput) -> Self {
|
||||
Self {
|
||||
admin_user_id: input.admin_user_id,
|
||||
invite_code: input.invite_code,
|
||||
metadata_json: input.metadata_json,
|
||||
updated_at_micros: input.updated_at_micros,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<module_runtime::RuntimeReferralInviteCenterGetInput>
|
||||
for RuntimeReferralInviteCenterGetInput
|
||||
{
|
||||
@@ -886,6 +899,26 @@ pub(crate) fn map_runtime_profile_redeem_code_admin_procedure_result(
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_profile_invite_code_admin_procedure_result(
|
||||
result: RuntimeProfileInviteCodeAdminProcedureResult,
|
||||
) -> Result<RuntimeProfileInviteCodeRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
let snapshot = result.record.ok_or_else(|| {
|
||||
SpacetimeClientError::Procedure("SpacetimeDB procedure 未返回 invite code 快照".to_string())
|
||||
})?;
|
||||
|
||||
Ok(build_runtime_profile_invite_code_record(
|
||||
map_runtime_profile_invite_code_snapshot(snapshot),
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_profile_play_stats_procedure_result(
|
||||
result: RuntimeProfilePlayStatsProcedureResult,
|
||||
) -> Result<RuntimeProfilePlayStatsRecord, SpacetimeClientError> {
|
||||
@@ -1388,6 +1421,132 @@ pub(crate) fn map_big_fish_works_procedure_result(
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub(crate) fn map_match3d_agent_session_procedure_result(
|
||||
result: Match3DAgentSessionProcedureResult,
|
||||
) -> Result<Match3DAgentSessionRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
let session_json = result.session_json.ok_or_else(|| {
|
||||
SpacetimeClientError::Procedure(
|
||||
"SpacetimeDB procedure 未返回 match3d agent session 快照".to_string(),
|
||||
)
|
||||
})?;
|
||||
let session =
|
||||
serde_json::from_str::<Match3DAgentSessionJsonRecord>(&session_json).map_err(|error| {
|
||||
SpacetimeClientError::Runtime(format!("match3d session_json 非法: {error}"))
|
||||
})?;
|
||||
|
||||
Ok(map_match3d_agent_session_snapshot(session))
|
||||
}
|
||||
|
||||
pub(crate) fn map_match3d_work_procedure_result(
|
||||
result: Match3DWorkProcedureResult,
|
||||
) -> Result<Match3DWorkProfileRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
let work_json = result.work_json.ok_or_else(|| {
|
||||
SpacetimeClientError::Procedure(
|
||||
"SpacetimeDB procedure 未返回 match3d work 快照".to_string(),
|
||||
)
|
||||
})?;
|
||||
let work = serde_json::from_str::<Match3DWorkJsonRecord>(&work_json).map_err(|error| {
|
||||
SpacetimeClientError::Runtime(format!("match3d work_json 非法: {error}"))
|
||||
})?;
|
||||
|
||||
Ok(map_match3d_work_snapshot(work))
|
||||
}
|
||||
|
||||
pub(crate) fn map_match3d_works_procedure_result(
|
||||
result: Match3DWorksProcedureResult,
|
||||
) -> Result<Vec<Match3DWorkProfileRecord>, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
let items_json = result.items_json.ok_or_else(|| {
|
||||
SpacetimeClientError::Procedure(
|
||||
"SpacetimeDB procedure 未返回 match3d works 快照".to_string(),
|
||||
)
|
||||
})?;
|
||||
let items =
|
||||
serde_json::from_str::<Vec<Match3DWorkJsonRecord>>(&items_json).map_err(|error| {
|
||||
SpacetimeClientError::Runtime(format!("match3d works items_json 非法: {error}"))
|
||||
})?;
|
||||
|
||||
Ok(items.into_iter().map(map_match3d_work_snapshot).collect())
|
||||
}
|
||||
|
||||
pub(crate) fn map_match3d_run_procedure_result(
|
||||
result: Match3DRunProcedureResult,
|
||||
) -> Result<Match3DRunRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
let run_json = result.run_json.ok_or_else(|| {
|
||||
SpacetimeClientError::Procedure("SpacetimeDB procedure 未返回 match3d run 快照".to_string())
|
||||
})?;
|
||||
map_match3d_run_json(run_json)
|
||||
}
|
||||
|
||||
pub(crate) fn map_match3d_click_item_procedure_result(
|
||||
result: Match3DClickItemProcedureResult,
|
||||
) -> Result<Match3DClickConfirmationRecord, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::Procedure(
|
||||
result
|
||||
.error_message
|
||||
.unwrap_or_else(|| "SpacetimeDB procedure 返回未知错误".to_string()),
|
||||
));
|
||||
}
|
||||
|
||||
let run_json = result.run_json.ok_or_else(|| {
|
||||
SpacetimeClientError::Procedure(
|
||||
"SpacetimeDB procedure 未返回 match3d click run 快照".to_string(),
|
||||
)
|
||||
})?;
|
||||
let run = map_match3d_run_json(run_json)?;
|
||||
let accepted = result.status == "Accepted";
|
||||
let accepted_item_instance_id = result.accepted_item_instance_id.clone();
|
||||
let entered_slot_index = accepted_item_instance_id.as_deref().and_then(|item_id| {
|
||||
run.items
|
||||
.iter()
|
||||
.find(|item| item.item_instance_id == item_id)
|
||||
.and_then(|item| item.tray_slot_index)
|
||||
});
|
||||
|
||||
Ok(Match3DClickConfirmationRecord {
|
||||
status: result.status.clone(),
|
||||
accepted,
|
||||
reject_reason: if accepted { None } else { Some(result.status) },
|
||||
accepted_item_instance_id,
|
||||
entered_slot_index,
|
||||
cleared_item_instance_ids: result.cleared_item_instance_ids,
|
||||
failure_reason: result.failure_reason,
|
||||
run,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn map_story_session_procedure_result(
|
||||
result: StorySessionProcedureResult,
|
||||
) -> Result<StorySessionResultRecord, SpacetimeClientError> {
|
||||
@@ -1784,6 +1943,18 @@ pub(crate) fn map_runtime_profile_redeem_code_snapshot(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_profile_invite_code_snapshot(
|
||||
snapshot: RuntimeProfileInviteCodeSnapshot,
|
||||
) -> module_runtime::RuntimeProfileInviteCodeSnapshot {
|
||||
module_runtime::RuntimeProfileInviteCodeSnapshot {
|
||||
user_id: snapshot.user_id,
|
||||
invite_code: snapshot.invite_code,
|
||||
metadata_json: snapshot.metadata_json,
|
||||
created_at_micros: snapshot.created_at_micros,
|
||||
updated_at_micros: snapshot.updated_at_micros,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_runtime_profile_played_world_snapshot(
|
||||
snapshot: RuntimeProfilePlayedWorldSnapshot,
|
||||
) -> module_runtime::RuntimeProfilePlayedWorldSnapshot {
|
||||
@@ -2363,6 +2534,236 @@ pub(crate) fn map_puzzle_agent_message_snapshot(
|
||||
}
|
||||
}
|
||||
|
||||
fn map_match3d_agent_session_snapshot(
|
||||
snapshot: Match3DAgentSessionJsonRecord,
|
||||
) -> Match3DAgentSessionRecord {
|
||||
let config = map_match3d_creator_config(snapshot.config);
|
||||
Match3DAgentSessionRecord {
|
||||
session_id: snapshot.session_id,
|
||||
current_turn: snapshot.current_turn,
|
||||
progress_percent: snapshot.progress_percent,
|
||||
stage: normalize_match3d_stage(&snapshot.stage).to_string(),
|
||||
anchor_pack: build_match3d_anchor_pack(&config),
|
||||
draft: snapshot
|
||||
.draft
|
||||
.map(|draft| map_match3d_result_draft(draft, config.reference_image_src.clone())),
|
||||
config: Some(config),
|
||||
messages: snapshot
|
||||
.messages
|
||||
.into_iter()
|
||||
.map(map_match3d_agent_message_snapshot)
|
||||
.collect(),
|
||||
last_assistant_reply: empty_string_to_none(snapshot.last_assistant_reply),
|
||||
published_profile_id: snapshot.published_profile_id,
|
||||
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_match3d_creator_config(
|
||||
snapshot: Match3DCreatorConfigJsonRecord,
|
||||
) -> Match3DCreatorConfigRecord {
|
||||
Match3DCreatorConfigRecord {
|
||||
theme_text: snapshot.theme_text,
|
||||
reference_image_src: snapshot.reference_image_src,
|
||||
clear_count: snapshot.clear_count,
|
||||
difficulty: snapshot.difficulty,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_match3d_result_draft(
|
||||
snapshot: Match3DDraftJsonRecord,
|
||||
reference_image_src: Option<String>,
|
||||
) -> Match3DResultDraftRecord {
|
||||
Match3DResultDraftRecord {
|
||||
profile_id: snapshot.profile_id,
|
||||
game_name: snapshot.game_name,
|
||||
theme_text: snapshot.theme_text,
|
||||
summary_text: snapshot.summary_text,
|
||||
tags: snapshot.tags,
|
||||
cover_image_src: None,
|
||||
reference_image_src,
|
||||
clear_count: snapshot.clear_count,
|
||||
difficulty: snapshot.difficulty,
|
||||
total_item_count: snapshot.clear_count.saturating_mul(3),
|
||||
publish_ready: false,
|
||||
blockers: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_match3d_agent_message_snapshot(
|
||||
snapshot: Match3DAgentMessageJsonRecord,
|
||||
) -> Match3DAgentMessageRecord {
|
||||
Match3DAgentMessageRecord {
|
||||
message_id: snapshot.message_id,
|
||||
role: snapshot.role,
|
||||
kind: normalize_match3d_message_kind(&snapshot.kind).to_string(),
|
||||
text: snapshot.text,
|
||||
created_at: format_timestamp_micros(snapshot.created_at_micros),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_match3d_work_snapshot(snapshot: Match3DWorkJsonRecord) -> Match3DWorkProfileRecord {
|
||||
let config = map_match3d_creator_config(snapshot.config);
|
||||
Match3DWorkProfileRecord {
|
||||
work_id: snapshot.profile_id.clone(),
|
||||
profile_id: snapshot.profile_id,
|
||||
owner_user_id: snapshot.owner_user_id,
|
||||
source_session_id: empty_string_to_none(snapshot.source_session_id),
|
||||
author_display_name: snapshot.author_display_name,
|
||||
game_name: snapshot.game_name,
|
||||
theme_text: snapshot.theme_text,
|
||||
summary: snapshot.summary_text,
|
||||
tags: snapshot.tags,
|
||||
cover_image_src: empty_string_to_none(snapshot.cover_image_src),
|
||||
cover_asset_id: empty_string_to_none(snapshot.cover_asset_id),
|
||||
reference_image_src: config.reference_image_src,
|
||||
clear_count: snapshot.clear_count,
|
||||
difficulty: snapshot.difficulty,
|
||||
publication_status: normalize_match3d_publication_status(&snapshot.publication_status)
|
||||
.to_string(),
|
||||
play_count: snapshot.play_count,
|
||||
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||
published_at: snapshot.published_at_micros.map(format_timestamp_micros),
|
||||
publish_ready: snapshot.publish_ready,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_match3d_run_json(run_json: String) -> Result<Match3DRunRecord, SpacetimeClientError> {
|
||||
let run = serde_json::from_str::<Match3DRunJsonRecord>(&run_json).map_err(|error| {
|
||||
SpacetimeClientError::Runtime(format!("match3d run_json 非法: {error}"))
|
||||
})?;
|
||||
Ok(map_match3d_run_snapshot(run))
|
||||
}
|
||||
|
||||
fn map_match3d_run_snapshot(snapshot: Match3DRunJsonRecord) -> Match3DRunRecord {
|
||||
let tray_slots = snapshot
|
||||
.tray_slots
|
||||
.into_iter()
|
||||
.map(map_match3d_tray_slot_snapshot)
|
||||
.collect::<Vec<_>>();
|
||||
let items = snapshot
|
||||
.items
|
||||
.into_iter()
|
||||
.map(|item| {
|
||||
let tray_slot_index = tray_slots
|
||||
.iter()
|
||||
.find(|slot| {
|
||||
slot.item_instance_id.as_deref() == Some(item.item_instance_id.as_str())
|
||||
})
|
||||
.map(|slot| slot.slot_index);
|
||||
map_match3d_item_snapshot(item, tray_slot_index)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Match3DRunRecord {
|
||||
run_id: snapshot.run_id,
|
||||
profile_id: snapshot.profile_id,
|
||||
owner_user_id: String::new(),
|
||||
status: snapshot.status,
|
||||
snapshot_version: u64::from(snapshot.snapshot_version),
|
||||
started_at_ms: i64_to_u64_ms(snapshot.started_at_ms),
|
||||
duration_limit_ms: i64_to_u64_ms(snapshot.duration_limit_ms),
|
||||
server_now_ms: Some(i64_to_u64_ms(snapshot.server_now_ms)),
|
||||
remaining_ms: i64_to_u64_ms(snapshot.remaining_ms),
|
||||
clear_count: snapshot.clear_count,
|
||||
total_item_count: snapshot.total_item_count,
|
||||
cleared_item_count: snapshot.cleared_item_count,
|
||||
items,
|
||||
tray_slots,
|
||||
failure_reason: snapshot.failure_reason,
|
||||
last_confirmed_action_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_match3d_item_snapshot(
|
||||
snapshot: Match3DItemJsonRecord,
|
||||
tray_slot_index: Option<u32>,
|
||||
) -> Match3DItemSnapshotRecord {
|
||||
Match3DItemSnapshotRecord {
|
||||
item_instance_id: snapshot.item_instance_id,
|
||||
item_type_id: snapshot.item_type_id,
|
||||
visual_key: snapshot.visual_key,
|
||||
x: snapshot.x,
|
||||
y: snapshot.y,
|
||||
radius: snapshot.radius,
|
||||
layer: snapshot.layer,
|
||||
state: snapshot.state,
|
||||
clickable: snapshot.clickable,
|
||||
tray_slot_index,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_match3d_tray_slot_snapshot(snapshot: Match3DTraySlotJsonRecord) -> Match3DTraySlotRecord {
|
||||
Match3DTraySlotRecord {
|
||||
slot_index: snapshot.slot_index,
|
||||
item_instance_id: snapshot.item_instance_id,
|
||||
item_type_id: snapshot.item_type_id,
|
||||
visual_key: snapshot.visual_key,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_match3d_anchor_pack(config: &Match3DCreatorConfigRecord) -> Match3DAnchorPackRecord {
|
||||
let clear_count = config.clear_count.to_string();
|
||||
let difficulty = config.difficulty.to_string();
|
||||
Match3DAnchorPackRecord {
|
||||
theme: build_match3d_anchor_item("theme", "题材主题", config.theme_text.as_str()),
|
||||
clear_count: build_match3d_anchor_item("clearCount", "需要消除次数", clear_count.as_str()),
|
||||
difficulty: build_match3d_anchor_item("difficulty", "难度", difficulty.as_str()),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_match3d_anchor_item(key: &str, label: &str, value: &str) -> Match3DAnchorItemRecord {
|
||||
Match3DAnchorItemRecord {
|
||||
key: key.to_string(),
|
||||
label: label.to_string(),
|
||||
value: value.to_string(),
|
||||
status: if value.trim().is_empty() {
|
||||
"missing"
|
||||
} else {
|
||||
"confirmed"
|
||||
}
|
||||
.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_match3d_stage(value: &str) -> &str {
|
||||
match value {
|
||||
"Collecting" | "collecting" | "collecting_config" => "collecting_config",
|
||||
"ReadyToCompile" | "ready_to_compile" => "ready_to_compile",
|
||||
"DraftCompiled" | "draft_compiled" | "draft_ready" => "draft_ready",
|
||||
"Published" | "published" => "published",
|
||||
_ => value,
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_match3d_publication_status(value: &str) -> &str {
|
||||
match value {
|
||||
"Draft" | "draft" => "draft",
|
||||
"Published" | "published" => "published",
|
||||
_ => value,
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_match3d_message_kind(value: &str) -> &str {
|
||||
match value {
|
||||
"text" => "chat",
|
||||
_ => value,
|
||||
}
|
||||
}
|
||||
|
||||
fn empty_string_to_none(value: String) -> Option<String> {
|
||||
let trimmed = value.trim();
|
||||
if trimmed.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(trimmed.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn i64_to_u64_ms(value: i64) -> u64 {
|
||||
value.max(0) as u64
|
||||
}
|
||||
|
||||
pub(crate) fn map_puzzle_suggested_action(
|
||||
snapshot: DomainPuzzleAgentSuggestedAction,
|
||||
) -> PuzzleAgentSuggestedActionRecord {
|
||||
@@ -2493,9 +2894,9 @@ fn map_puzzle_recommended_next_work(
|
||||
pub(crate) fn map_puzzle_runtime_level_snapshot(
|
||||
snapshot: DomainPuzzleRuntimeLevelSnapshot,
|
||||
) -> PuzzleRuntimeLevelRecord {
|
||||
// 中文注释:历史 run_json 可能缺 started_at_ms,领域 serde 会回填为 0;API 层继续补成 1,避免前端计时器拿到无效开局时间。
|
||||
let started_at_ms = if snapshot.started_at_ms == 0 {
|
||||
1
|
||||
// 中文注释:旧 run_json 没有计时字段时只补一个可用开始时间,其余限时字段保持旧默认值。
|
||||
current_unix_millis_for_legacy_puzzle_snapshot()
|
||||
} else {
|
||||
snapshot.started_at_ms
|
||||
};
|
||||
@@ -2530,6 +2931,13 @@ pub(crate) fn map_puzzle_runtime_level_snapshot(
|
||||
}
|
||||
}
|
||||
|
||||
fn current_unix_millis_for_legacy_puzzle_snapshot() -> u64 {
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.map(|duration| duration.as_millis().min(u128::from(u64::MAX)) as u64)
|
||||
.unwrap_or(1)
|
||||
}
|
||||
|
||||
pub(crate) fn map_puzzle_leaderboard_entry(
|
||||
snapshot: module_puzzle::PuzzleLeaderboardEntry,
|
||||
) -> PuzzleLeaderboardEntryRecord {
|
||||
@@ -4574,6 +4982,367 @@ pub struct BigFishWorkRemixRecordInput {
|
||||
pub remixed_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DAgentSessionCreateRecordInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub seed_text: String,
|
||||
pub welcome_message_id: String,
|
||||
pub welcome_message_text: String,
|
||||
pub config_json: Option<String>,
|
||||
pub created_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DAgentMessageSubmitRecordInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub user_message_id: String,
|
||||
pub user_message_text: String,
|
||||
pub submitted_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DAgentMessageFinalizeRecordInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub assistant_message_id: Option<String>,
|
||||
pub assistant_reply_text: Option<String>,
|
||||
pub config_json: Option<String>,
|
||||
pub progress_percent: u32,
|
||||
pub stage: String,
|
||||
pub updated_at_micros: i64,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DCompileDraftRecordInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub author_display_name: String,
|
||||
pub game_name: Option<String>,
|
||||
pub summary_text: Option<String>,
|
||||
pub tags_json: Option<String>,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub cover_asset_id: Option<String>,
|
||||
pub compiled_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DWorkUpdateRecordInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub game_name: String,
|
||||
pub theme_text: String,
|
||||
pub summary_text: String,
|
||||
pub tags_json: String,
|
||||
pub cover_image_src: String,
|
||||
pub cover_asset_id: String,
|
||||
pub clear_count: u32,
|
||||
pub difficulty: u32,
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DRunStartRecordInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub started_at_ms: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DRunClickRecordInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub item_instance_id: String,
|
||||
pub client_snapshot_version: u32,
|
||||
pub client_event_id: String,
|
||||
pub clicked_at_ms: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DRunStopRecordInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub stopped_at_ms: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DRunRestartRecordInput {
|
||||
pub source_run_id: String,
|
||||
pub next_run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub restarted_at_ms: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DRunTimeUpRecordInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub finished_at_ms: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DAnchorItemRecord {
|
||||
pub key: String,
|
||||
pub label: String,
|
||||
pub value: String,
|
||||
pub status: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DAnchorPackRecord {
|
||||
pub theme: Match3DAnchorItemRecord,
|
||||
pub clear_count: Match3DAnchorItemRecord,
|
||||
pub difficulty: Match3DAnchorItemRecord,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DCreatorConfigRecord {
|
||||
pub theme_text: String,
|
||||
pub reference_image_src: Option<String>,
|
||||
pub clear_count: u32,
|
||||
pub difficulty: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DResultDraftRecord {
|
||||
pub profile_id: String,
|
||||
pub game_name: String,
|
||||
pub theme_text: String,
|
||||
pub summary_text: String,
|
||||
pub tags: Vec<String>,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub reference_image_src: Option<String>,
|
||||
pub clear_count: u32,
|
||||
pub difficulty: u32,
|
||||
pub total_item_count: u32,
|
||||
pub publish_ready: bool,
|
||||
pub blockers: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DAgentMessageRecord {
|
||||
pub message_id: String,
|
||||
pub role: String,
|
||||
pub kind: String,
|
||||
pub text: String,
|
||||
pub created_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DAgentSessionRecord {
|
||||
pub session_id: String,
|
||||
pub current_turn: u32,
|
||||
pub progress_percent: u32,
|
||||
pub stage: String,
|
||||
pub anchor_pack: Match3DAnchorPackRecord,
|
||||
pub config: Option<Match3DCreatorConfigRecord>,
|
||||
pub draft: Option<Match3DResultDraftRecord>,
|
||||
pub messages: Vec<Match3DAgentMessageRecord>,
|
||||
pub last_assistant_reply: Option<String>,
|
||||
pub published_profile_id: Option<String>,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DWorkProfileRecord {
|
||||
pub work_id: String,
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub source_session_id: Option<String>,
|
||||
pub author_display_name: String,
|
||||
pub game_name: String,
|
||||
pub theme_text: String,
|
||||
pub summary: String,
|
||||
pub tags: Vec<String>,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub cover_asset_id: Option<String>,
|
||||
pub reference_image_src: Option<String>,
|
||||
pub clear_count: u32,
|
||||
pub difficulty: u32,
|
||||
pub publication_status: String,
|
||||
pub play_count: u32,
|
||||
pub updated_at: String,
|
||||
pub published_at: Option<String>,
|
||||
pub publish_ready: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Match3DItemSnapshotRecord {
|
||||
pub item_instance_id: String,
|
||||
pub item_type_id: String,
|
||||
pub visual_key: String,
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub radius: f32,
|
||||
pub layer: u32,
|
||||
pub state: String,
|
||||
pub clickable: bool,
|
||||
pub tray_slot_index: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Match3DTraySlotRecord {
|
||||
pub slot_index: u32,
|
||||
pub item_instance_id: Option<String>,
|
||||
pub item_type_id: Option<String>,
|
||||
pub visual_key: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Match3DRunRecord {
|
||||
pub run_id: String,
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub status: String,
|
||||
pub snapshot_version: u64,
|
||||
pub started_at_ms: u64,
|
||||
pub duration_limit_ms: u64,
|
||||
pub server_now_ms: Option<u64>,
|
||||
pub remaining_ms: u64,
|
||||
pub clear_count: u32,
|
||||
pub total_item_count: u32,
|
||||
pub cleared_item_count: u32,
|
||||
pub items: Vec<Match3DItemSnapshotRecord>,
|
||||
pub tray_slots: Vec<Match3DTraySlotRecord>,
|
||||
pub failure_reason: Option<String>,
|
||||
pub last_confirmed_action_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Match3DClickConfirmationRecord {
|
||||
pub status: String,
|
||||
pub accepted: bool,
|
||||
pub reject_reason: Option<String>,
|
||||
pub accepted_item_instance_id: Option<String>,
|
||||
pub entered_slot_index: Option<u32>,
|
||||
pub cleared_item_instance_ids: Vec<String>,
|
||||
pub failure_reason: Option<String>,
|
||||
pub run: Match3DRunRecord,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Match3DCreatorConfigJsonRecord {
|
||||
theme_text: String,
|
||||
reference_image_src: Option<String>,
|
||||
clear_count: u32,
|
||||
difficulty: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Match3DAgentMessageJsonRecord {
|
||||
message_id: String,
|
||||
#[allow(dead_code)]
|
||||
session_id: String,
|
||||
role: String,
|
||||
kind: String,
|
||||
text: String,
|
||||
created_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Match3DDraftJsonRecord {
|
||||
profile_id: String,
|
||||
game_name: String,
|
||||
theme_text: String,
|
||||
summary_text: String,
|
||||
tags: Vec<String>,
|
||||
clear_count: u32,
|
||||
difficulty: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Match3DAgentSessionJsonRecord {
|
||||
session_id: String,
|
||||
#[allow(dead_code)]
|
||||
owner_user_id: String,
|
||||
#[allow(dead_code)]
|
||||
seed_text: String,
|
||||
current_turn: u32,
|
||||
progress_percent: u32,
|
||||
stage: String,
|
||||
config: Match3DCreatorConfigJsonRecord,
|
||||
draft: Option<Match3DDraftJsonRecord>,
|
||||
messages: Vec<Match3DAgentMessageJsonRecord>,
|
||||
last_assistant_reply: String,
|
||||
published_profile_id: Option<String>,
|
||||
#[allow(dead_code)]
|
||||
created_at_micros: i64,
|
||||
updated_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Match3DWorkJsonRecord {
|
||||
profile_id: String,
|
||||
owner_user_id: String,
|
||||
source_session_id: String,
|
||||
author_display_name: String,
|
||||
game_name: String,
|
||||
theme_text: String,
|
||||
summary_text: String,
|
||||
tags: Vec<String>,
|
||||
cover_image_src: String,
|
||||
cover_asset_id: String,
|
||||
clear_count: u32,
|
||||
difficulty: u32,
|
||||
config: Match3DCreatorConfigJsonRecord,
|
||||
publication_status: String,
|
||||
publish_ready: bool,
|
||||
play_count: u32,
|
||||
updated_at_micros: i64,
|
||||
published_at_micros: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Match3DItemJsonRecord {
|
||||
item_instance_id: String,
|
||||
item_type_id: String,
|
||||
visual_key: String,
|
||||
x: f32,
|
||||
y: f32,
|
||||
radius: f32,
|
||||
layer: u32,
|
||||
state: String,
|
||||
clickable: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Match3DTraySlotJsonRecord {
|
||||
slot_index: u32,
|
||||
item_instance_id: Option<String>,
|
||||
item_type_id: Option<String>,
|
||||
visual_key: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Match3DRunJsonRecord {
|
||||
run_id: String,
|
||||
profile_id: String,
|
||||
status: String,
|
||||
snapshot_version: u32,
|
||||
started_at_ms: i64,
|
||||
duration_limit_ms: i64,
|
||||
server_now_ms: i64,
|
||||
remaining_ms: i64,
|
||||
clear_count: u32,
|
||||
total_item_count: u32,
|
||||
cleared_item_count: u32,
|
||||
tray_slots: Vec<Match3DTraySlotJsonRecord>,
|
||||
items: Vec<Match3DItemJsonRecord>,
|
||||
failure_reason: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct PuzzleAnchorItemRecord {
|
||||
pub key: String,
|
||||
|
||||
466
server-rs/crates/spacetime-client/src/match3d.rs
Normal file
466
server-rs/crates/spacetime-client/src/match3d.rs
Normal file
@@ -0,0 +1,466 @@
|
||||
use super::*;
|
||||
use crate::mapper::*;
|
||||
|
||||
impl SpacetimeClient {
|
||||
pub async fn create_match3d_agent_session(
|
||||
&self,
|
||||
input: Match3DAgentSessionCreateRecordInput,
|
||||
) -> Result<Match3DAgentSessionRecord, SpacetimeClientError> {
|
||||
let procedure_input = Match3DAgentSessionCreateInput {
|
||||
session_id: input.session_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
seed_text: input.seed_text,
|
||||
welcome_message_id: input.welcome_message_id,
|
||||
welcome_message_text: input.welcome_message_text,
|
||||
config_json: input.config_json,
|
||||
created_at_micros: input.created_at_micros,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().create_match_3_d_agent_session_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_agent_session_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_match3d_agent_session(
|
||||
&self,
|
||||
session_id: String,
|
||||
owner_user_id: String,
|
||||
) -> Result<Match3DAgentSessionRecord, SpacetimeClientError> {
|
||||
let procedure_input = Match3DAgentSessionGetInput {
|
||||
session_id,
|
||||
owner_user_id,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().get_match_3_d_agent_session_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_agent_session_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn submit_match3d_agent_message(
|
||||
&self,
|
||||
input: Match3DAgentMessageSubmitRecordInput,
|
||||
) -> Result<Match3DAgentSessionRecord, SpacetimeClientError> {
|
||||
let procedure_input = Match3DAgentMessageSubmitInput {
|
||||
session_id: input.session_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
user_message_id: input.user_message_id,
|
||||
user_message_text: input.user_message_text,
|
||||
submitted_at_micros: input.submitted_at_micros,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().submit_match_3_d_agent_message_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_agent_session_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn finalize_match3d_agent_message(
|
||||
&self,
|
||||
input: Match3DAgentMessageFinalizeRecordInput,
|
||||
) -> Result<Match3DAgentSessionRecord, SpacetimeClientError> {
|
||||
let procedure_input = Match3DAgentMessageFinalizeInput {
|
||||
session_id: input.session_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
assistant_message_id: input.assistant_message_id,
|
||||
assistant_reply_text: input.assistant_reply_text,
|
||||
config_json: input.config_json,
|
||||
progress_percent: input.progress_percent,
|
||||
stage: input.stage,
|
||||
updated_at_micros: input.updated_at_micros,
|
||||
error_message: input.error_message,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.finalize_match_3_d_agent_message_turn_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_agent_session_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn compile_match3d_draft(
|
||||
&self,
|
||||
input: Match3DCompileDraftRecordInput,
|
||||
) -> Result<Match3DAgentSessionRecord, SpacetimeClientError> {
|
||||
let procedure_input = Match3DDraftCompileInput {
|
||||
session_id: input.session_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
profile_id: input.profile_id,
|
||||
author_display_name: input.author_display_name,
|
||||
game_name: input.game_name,
|
||||
summary_text: input.summary_text,
|
||||
tags_json: input.tags_json,
|
||||
cover_image_src: input.cover_image_src,
|
||||
cover_asset_id: input.cover_asset_id,
|
||||
compiled_at_micros: input.compiled_at_micros,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().compile_match_3_d_draft_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_agent_session_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn update_match3d_work(
|
||||
&self,
|
||||
input: Match3DWorkUpdateRecordInput,
|
||||
) -> Result<Match3DWorkProfileRecord, SpacetimeClientError> {
|
||||
let procedure_input = Match3DWorkUpdateInput {
|
||||
profile_id: input.profile_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
game_name: input.game_name,
|
||||
theme_text: input.theme_text,
|
||||
summary_text: input.summary_text,
|
||||
tags_json: input.tags_json,
|
||||
cover_image_src: input.cover_image_src,
|
||||
cover_asset_id: input.cover_asset_id,
|
||||
clear_count: input.clear_count,
|
||||
difficulty: input.difficulty,
|
||||
updated_at_micros: input.updated_at_micros,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().update_match_3_d_work_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_work_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn publish_match3d_work(
|
||||
&self,
|
||||
profile_id: String,
|
||||
owner_user_id: String,
|
||||
published_at_micros: i64,
|
||||
) -> Result<Match3DWorkProfileRecord, SpacetimeClientError> {
|
||||
let procedure_input = Match3DWorkPublishInput {
|
||||
profile_id,
|
||||
owner_user_id,
|
||||
published_at_micros,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().publish_match_3_d_work_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_work_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn list_match3d_works(
|
||||
&self,
|
||||
owner_user_id: String,
|
||||
) -> Result<Vec<Match3DWorkProfileRecord>, SpacetimeClientError> {
|
||||
self.list_match3d_works_with_input(Match3DWorksListInput {
|
||||
owner_user_id,
|
||||
published_only: false,
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn list_match3d_gallery(
|
||||
&self,
|
||||
) -> Result<Vec<Match3DWorkProfileRecord>, SpacetimeClientError> {
|
||||
self.list_match3d_works_with_input(Match3DWorksListInput {
|
||||
// 中文注释:公开广场读取只依赖 published_only,owner_user_id 保持非空便于兼容校验。
|
||||
owner_user_id: "match3d-public-gallery".to_string(),
|
||||
published_only: true,
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn list_match3d_works_with_input(
|
||||
&self,
|
||||
procedure_input: Match3DWorksListInput,
|
||||
) -> Result<Vec<Match3DWorkProfileRecord>, SpacetimeClientError> {
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.list_match_3_d_works_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_works_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_match3d_work_detail(
|
||||
&self,
|
||||
profile_id: String,
|
||||
owner_user_id: String,
|
||||
) -> Result<Match3DWorkProfileRecord, SpacetimeClientError> {
|
||||
let procedure_input = Match3DWorkGetInput {
|
||||
profile_id,
|
||||
owner_user_id,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().get_match_3_d_work_detail_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_work_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn delete_match3d_work(
|
||||
&self,
|
||||
profile_id: String,
|
||||
owner_user_id: String,
|
||||
) -> Result<Vec<Match3DWorkProfileRecord>, SpacetimeClientError> {
|
||||
let procedure_input = Match3DWorkDeleteInput {
|
||||
profile_id,
|
||||
owner_user_id,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().delete_match_3_d_work_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_works_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn start_match3d_run(
|
||||
&self,
|
||||
input: Match3DRunStartRecordInput,
|
||||
) -> Result<Match3DRunRecord, SpacetimeClientError> {
|
||||
let owner_user_id = input.owner_user_id.clone();
|
||||
let procedure_input = Match3DRunStartInput {
|
||||
run_id: input.run_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
profile_id: input.profile_id,
|
||||
started_at_ms: input.started_at_ms,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.start_match_3_d_run_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_run_procedure_result)
|
||||
.map(|mut run| {
|
||||
run.owner_user_id = owner_user_id;
|
||||
run
|
||||
});
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_match3d_run(
|
||||
&self,
|
||||
run_id: String,
|
||||
owner_user_id: String,
|
||||
) -> Result<Match3DRunRecord, SpacetimeClientError> {
|
||||
let procedure_owner_user_id = owner_user_id.clone();
|
||||
let procedure_input = Match3DRunGetInput {
|
||||
run_id,
|
||||
owner_user_id,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.get_match_3_d_run_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_run_procedure_result)
|
||||
.map(|mut run| {
|
||||
run.owner_user_id = procedure_owner_user_id;
|
||||
run
|
||||
});
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn click_match3d_item(
|
||||
&self,
|
||||
input: Match3DRunClickRecordInput,
|
||||
) -> Result<Match3DClickConfirmationRecord, SpacetimeClientError> {
|
||||
let owner_user_id = input.owner_user_id.clone();
|
||||
let client_event_id = input.client_event_id.clone();
|
||||
let procedure_input = Match3DRunClickInput {
|
||||
run_id: input.run_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
item_instance_id: input.item_instance_id,
|
||||
client_snapshot_version: input.client_snapshot_version,
|
||||
client_event_id: input.client_event_id,
|
||||
clicked_at_ms: input.clicked_at_ms,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.click_match_3_d_item_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_click_item_procedure_result)
|
||||
.map(|mut confirmation| {
|
||||
confirmation.run.owner_user_id = owner_user_id;
|
||||
if confirmation.accepted {
|
||||
confirmation.run.last_confirmed_action_id = Some(client_event_id);
|
||||
}
|
||||
confirmation
|
||||
});
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn stop_match3d_run(
|
||||
&self,
|
||||
input: Match3DRunStopRecordInput,
|
||||
) -> Result<Match3DRunRecord, SpacetimeClientError> {
|
||||
let owner_user_id = input.owner_user_id.clone();
|
||||
let procedure_input = Match3DRunStopInput {
|
||||
run_id: input.run_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
stopped_at_ms: input.stopped_at_ms,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.stop_match_3_d_run_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_run_procedure_result)
|
||||
.map(|mut run| {
|
||||
run.owner_user_id = owner_user_id;
|
||||
run
|
||||
});
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn restart_match3d_run(
|
||||
&self,
|
||||
input: Match3DRunRestartRecordInput,
|
||||
) -> Result<Match3DRunRecord, SpacetimeClientError> {
|
||||
let owner_user_id = input.owner_user_id.clone();
|
||||
let procedure_input = Match3DRunRestartInput {
|
||||
source_run_id: input.source_run_id,
|
||||
next_run_id: input.next_run_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
restarted_at_ms: input.restarted_at_ms,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().restart_match_3_d_run_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_run_procedure_result)
|
||||
.map(|mut run| {
|
||||
run.owner_user_id = owner_user_id;
|
||||
run
|
||||
});
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn finish_match3d_time_up(
|
||||
&self,
|
||||
input: Match3DRunTimeUpRecordInput,
|
||||
) -> Result<Match3DRunRecord, SpacetimeClientError> {
|
||||
let owner_user_id = input.owner_user_id.clone();
|
||||
let procedure_input = Match3DRunTimeUpInput {
|
||||
run_id: input.run_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
finished_at_ms: input.finished_at_ms,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection.procedures().finish_match_3_d_time_up_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_match3d_run_procedure_result)
|
||||
.map(|mut run| {
|
||||
run.owner_user_id = owner_user_id;
|
||||
run
|
||||
});
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
})
|
||||
.await
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::runtime_profile_invite_code_admin_procedure_result_type::RuntimeProfileInviteCodeAdminProcedureResult;
|
||||
use super::runtime_profile_invite_code_admin_upsert_input_type::RuntimeProfileInviteCodeAdminUpsertInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct AdminUpsertProfileInviteCodeArgs {
|
||||
pub input: RuntimeProfileInviteCodeAdminUpsertInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for AdminUpsertProfileInviteCodeArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `admin_upsert_profile_invite_code`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait admin_upsert_profile_invite_code {
|
||||
fn admin_upsert_profile_invite_code(&self, input: RuntimeProfileInviteCodeAdminUpsertInput) {
|
||||
self.admin_upsert_profile_invite_code_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn admin_upsert_profile_invite_code_then(
|
||||
&self,
|
||||
input: RuntimeProfileInviteCodeAdminUpsertInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileInviteCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl admin_upsert_profile_invite_code for super::RemoteProcedures {
|
||||
fn admin_upsert_profile_invite_code_then(
|
||||
&self,
|
||||
input: RuntimeProfileInviteCodeAdminUpsertInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<RuntimeProfileInviteCodeAdminProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, RuntimeProfileInviteCodeAdminProcedureResult>(
|
||||
"admin_upsert_profile_invite_code",
|
||||
AdminUpsertProfileInviteCodeArgs { input },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -335,6 +335,9 @@ pub mod runtime_platform_theme_type;
|
||||
pub mod runtime_profile_dashboard_get_input_type;
|
||||
pub mod runtime_profile_dashboard_procedure_result_type;
|
||||
pub mod runtime_profile_dashboard_snapshot_type;
|
||||
pub mod runtime_profile_invite_code_admin_procedure_result_type;
|
||||
pub mod runtime_profile_invite_code_admin_upsert_input_type;
|
||||
pub mod runtime_profile_invite_code_snapshot_type;
|
||||
pub mod runtime_profile_membership_benefit_snapshot_type;
|
||||
pub mod runtime_profile_membership_snapshot_type;
|
||||
pub mod runtime_profile_membership_status_type;
|
||||
@@ -431,6 +434,7 @@ pub mod upsert_custom_world_profile_reducer;
|
||||
pub mod upsert_npc_state_reducer;
|
||||
pub mod custom_world_gallery_entry_table;
|
||||
pub mod admin_disable_profile_redeem_code_procedure;
|
||||
pub mod admin_upsert_profile_invite_code_procedure;
|
||||
pub mod admin_upsert_profile_redeem_code_procedure;
|
||||
pub mod advance_puzzle_next_level_procedure;
|
||||
pub mod append_ai_text_chunk_and_return_procedure;
|
||||
@@ -895,6 +899,9 @@ pub use runtime_platform_theme_type::RuntimePlatformTheme;
|
||||
pub use runtime_profile_dashboard_get_input_type::RuntimeProfileDashboardGetInput;
|
||||
pub use runtime_profile_dashboard_procedure_result_type::RuntimeProfileDashboardProcedureResult;
|
||||
pub use runtime_profile_dashboard_snapshot_type::RuntimeProfileDashboardSnapshot;
|
||||
pub use runtime_profile_invite_code_admin_procedure_result_type::RuntimeProfileInviteCodeAdminProcedureResult;
|
||||
pub use runtime_profile_invite_code_admin_upsert_input_type::RuntimeProfileInviteCodeAdminUpsertInput;
|
||||
pub use runtime_profile_invite_code_snapshot_type::RuntimeProfileInviteCodeSnapshot;
|
||||
pub use runtime_profile_membership_benefit_snapshot_type::RuntimeProfileMembershipBenefitSnapshot;
|
||||
pub use runtime_profile_membership_snapshot_type::RuntimeProfileMembershipSnapshot;
|
||||
pub use runtime_profile_membership_status_type::RuntimeProfileMembershipStatus;
|
||||
@@ -991,6 +998,7 @@ pub use upsert_chapter_progression_reducer::upsert_chapter_progression;
|
||||
pub use upsert_custom_world_profile_reducer::upsert_custom_world_profile;
|
||||
pub use upsert_npc_state_reducer::upsert_npc_state;
|
||||
pub use admin_disable_profile_redeem_code_procedure::admin_disable_profile_redeem_code;
|
||||
pub use admin_upsert_profile_invite_code_procedure::admin_upsert_profile_invite_code;
|
||||
pub use admin_upsert_profile_redeem_code_procedure::admin_upsert_profile_redeem_code;
|
||||
pub use advance_puzzle_next_level_procedure::advance_puzzle_next_level;
|
||||
pub use append_ai_text_chunk_and_return_procedure::append_ai_text_chunk_and_return;
|
||||
|
||||
@@ -15,6 +15,7 @@ use spacetimedb_sdk::__codegen::{
|
||||
pub struct ProfileInviteCode {
|
||||
pub user_id: String,
|
||||
pub invite_code: String,
|
||||
pub metadata_json: String,
|
||||
pub created_at: __sdk::Timestamp,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
}
|
||||
@@ -31,6 +32,7 @@ impl __sdk::InModule for ProfileInviteCode {
|
||||
pub struct ProfileInviteCodeCols {
|
||||
pub user_id: __sdk::__query_builder::Col<ProfileInviteCode, String>,
|
||||
pub invite_code: __sdk::__query_builder::Col<ProfileInviteCode, String>,
|
||||
pub metadata_json: __sdk::__query_builder::Col<ProfileInviteCode, String>,
|
||||
pub created_at: __sdk::__query_builder::Col<ProfileInviteCode, __sdk::Timestamp>,
|
||||
pub updated_at: __sdk::__query_builder::Col<ProfileInviteCode, __sdk::Timestamp>,
|
||||
}
|
||||
@@ -41,6 +43,7 @@ impl __sdk::__query_builder::HasCols for ProfileInviteCode {
|
||||
ProfileInviteCodeCols {
|
||||
user_id: __sdk::__query_builder::Col::new(table_name, "user_id"),
|
||||
invite_code: __sdk::__query_builder::Col::new(table_name, "invite_code"),
|
||||
metadata_json: __sdk::__query_builder::Col::new(table_name, "metadata_json"),
|
||||
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
|
||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::runtime_profile_invite_code_snapshot_type::RuntimeProfileInviteCodeSnapshot;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct RuntimeProfileInviteCodeAdminProcedureResult {
|
||||
pub ok: bool,
|
||||
pub record: Option<RuntimeProfileInviteCodeSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for RuntimeProfileInviteCodeAdminProcedureResult {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct RuntimeProfileInviteCodeAdminUpsertInput {
|
||||
pub admin_user_id: String,
|
||||
pub invite_code: String,
|
||||
pub metadata_json: String,
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for RuntimeProfileInviteCodeAdminUpsertInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct RuntimeProfileInviteCodeSnapshot {
|
||||
pub user_id: String,
|
||||
pub invite_code: String,
|
||||
pub metadata_json: String,
|
||||
pub created_at_micros: i64,
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for RuntimeProfileInviteCodeSnapshot {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -346,6 +346,35 @@ impl SpacetimeClient {
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn admin_upsert_profile_invite_code(
|
||||
&self,
|
||||
admin_user_id: String,
|
||||
invite_code: String,
|
||||
metadata_json: String,
|
||||
updated_at_micros: i64,
|
||||
) -> Result<RuntimeProfileInviteCodeRecord, SpacetimeClientError> {
|
||||
let procedure_input = build_runtime_profile_invite_code_admin_upsert_input(
|
||||
admin_user_id,
|
||||
invite_code,
|
||||
metadata_json,
|
||||
updated_at_micros,
|
||||
)
|
||||
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
|
||||
.into();
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.admin_upsert_profile_invite_code_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_runtime_profile_invite_code_admin_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_profile_play_stats(
|
||||
&self,
|
||||
user_id: String,
|
||||
|
||||
Reference in New Issue
Block a user