feat: add puzzle clear template runtime
This commit is contained in:
@@ -163,6 +163,7 @@ mod tests {
|
||||
let row = BarkBattleGalleryViewRow {
|
||||
work_id: "BB-33333333".to_string(),
|
||||
owner_user_id: "user-3".to_string(),
|
||||
author_display_name: "声浪玩家".to_string(),
|
||||
source_draft_id: Some("bark-battle-draft-3".to_string()),
|
||||
config_version: 1,
|
||||
ruleset_version: "bark-battle-ruleset-v1".to_string(),
|
||||
|
||||
289
server-rs/crates/spacetime-client/src/mapper/puzzle_clear.rs
Normal file
289
server-rs/crates/spacetime-client/src/mapper/puzzle_clear.rs
Normal file
@@ -0,0 +1,289 @@
|
||||
use super::*;
|
||||
pub use shared_contracts::puzzle_clear::{
|
||||
PuzzleClearActionRequest, PuzzleClearActionResponse, PuzzleClearActionType,
|
||||
PuzzleClearBoardCell, PuzzleClearBoardSnapshot, PuzzleClearCardAsset, PuzzleClearDraftResponse,
|
||||
PuzzleClearGenerationStatus, PuzzleClearImageAsset, PuzzleClearNextLevelRequest,
|
||||
PuzzleClearPatternGroup, PuzzleClearRetryLevelRequest, PuzzleClearRunResponse,
|
||||
PuzzleClearRunStatus, PuzzleClearRuntimeSnapshotResponse, PuzzleClearSessionResponse,
|
||||
PuzzleClearSessionSnapshotResponse, PuzzleClearStartRunRequest, PuzzleClearSwapRequest,
|
||||
PuzzleClearTimeUpRequest, PuzzleClearWorkDetailResponse, PuzzleClearWorkMutationResponse,
|
||||
PuzzleClearWorkProfileResponse, PuzzleClearWorkSummaryResponse, PuzzleClearWorksResponse,
|
||||
PuzzleClearWorkspaceCreateRequest,
|
||||
};
|
||||
|
||||
pub(crate) fn map_puzzle_clear_agent_session_procedure_result(
|
||||
result: PuzzleClearAgentSessionProcedureResult,
|
||||
) -> Result<PuzzleClearSessionSnapshotResponse, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
let session = result
|
||||
.session
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle clear agent session 快照"))?;
|
||||
Ok(map_puzzle_clear_session_snapshot(session))
|
||||
}
|
||||
|
||||
pub(crate) fn map_puzzle_clear_work_procedure_result(
|
||||
result: PuzzleClearWorkProcedureResult,
|
||||
) -> Result<PuzzleClearWorkProfileResponse, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
let work = result
|
||||
.work
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle clear work 快照"))?;
|
||||
Ok(map_puzzle_clear_work_snapshot(work))
|
||||
}
|
||||
|
||||
pub(crate) fn map_puzzle_clear_works_procedure_result(
|
||||
result: PuzzleClearWorksProcedureResult,
|
||||
) -> Result<Vec<PuzzleClearWorkProfileResponse>, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
Ok(result
|
||||
.items
|
||||
.into_iter()
|
||||
.map(map_puzzle_clear_work_snapshot)
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub(crate) fn map_puzzle_clear_run_procedure_result(
|
||||
result: PuzzleClearRunProcedureResult,
|
||||
) -> Result<PuzzleClearRuntimeSnapshotResponse, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
let run = result
|
||||
.run
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle clear run 快照"))?;
|
||||
Ok(map_puzzle_clear_run_snapshot(run))
|
||||
}
|
||||
|
||||
pub(crate) fn map_puzzle_clear_gallery_card_view_row(
|
||||
row: PuzzleClearGalleryCardViewRow,
|
||||
) -> PuzzleClearWorkSummaryResponse {
|
||||
PuzzleClearWorkSummaryResponse {
|
||||
runtime_kind: "puzzle-clear".to_string(),
|
||||
work_id: row.work_id,
|
||||
profile_id: row.profile_id,
|
||||
owner_user_id: row.owner_user_id,
|
||||
source_session_id: None,
|
||||
work_title: row.work_title,
|
||||
work_description: row.work_description,
|
||||
theme_prompt: row.theme_prompt,
|
||||
cover_image_src: row.cover_image_src,
|
||||
publication_status: normalize_publication_status(&row.publication_status).to_string(),
|
||||
play_count: row.play_count,
|
||||
updated_at: format_timestamp_micros(row.updated_at_micros),
|
||||
published_at: row.published_at_micros.map(format_timestamp_micros),
|
||||
publish_ready: true,
|
||||
generation_status: parse_generation_status(&row.generation_status),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_puzzle_clear_session_snapshot(
|
||||
snapshot: PuzzleClearAgentSessionSnapshot,
|
||||
) -> PuzzleClearSessionSnapshotResponse {
|
||||
PuzzleClearSessionSnapshotResponse {
|
||||
session_id: snapshot.session_id,
|
||||
owner_user_id: snapshot.owner_user_id,
|
||||
status: parse_generation_status(&snapshot.status),
|
||||
draft: snapshot.draft.map(map_puzzle_clear_draft_snapshot),
|
||||
created_at: format_timestamp_micros(snapshot.created_at_micros),
|
||||
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_puzzle_clear_work_snapshot(
|
||||
snapshot: PuzzleClearWorkSnapshot,
|
||||
) -> PuzzleClearWorkProfileResponse {
|
||||
let atlas_asset = map_image_asset(snapshot.atlas_asset.clone());
|
||||
let pattern_groups = snapshot
|
||||
.pattern_groups
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(map_pattern_group)
|
||||
.collect::<Vec<_>>();
|
||||
let card_assets = snapshot
|
||||
.card_assets
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(map_card_asset)
|
||||
.collect::<Vec<_>>();
|
||||
let board_background_asset = snapshot.board_background_asset.clone().map(map_image_asset);
|
||||
let draft = PuzzleClearDraftResponse {
|
||||
template_id: "puzzle-clear".to_string(),
|
||||
template_name: "拼消消".to_string(),
|
||||
profile_id: Some(snapshot.profile_id.clone()),
|
||||
work_title: snapshot.work_title.clone(),
|
||||
work_description: snapshot.work_description.clone(),
|
||||
theme_prompt: snapshot.theme_prompt.clone(),
|
||||
board_background_prompt: snapshot.board_background_prompt.clone(),
|
||||
generate_board_background: snapshot.generate_board_background,
|
||||
board_background_asset: board_background_asset.clone(),
|
||||
card_back_image_src: snapshot.card_back_image_src.clone(),
|
||||
atlas_asset: Some(atlas_asset.clone()),
|
||||
pattern_groups: pattern_groups.clone(),
|
||||
card_assets: card_assets.clone(),
|
||||
generation_status: parse_generation_status(&snapshot.generation_status),
|
||||
};
|
||||
|
||||
PuzzleClearWorkProfileResponse {
|
||||
summary: PuzzleClearWorkSummaryResponse {
|
||||
runtime_kind: "puzzle-clear".to_string(),
|
||||
work_id: snapshot.work_id,
|
||||
profile_id: snapshot.profile_id,
|
||||
owner_user_id: snapshot.owner_user_id,
|
||||
source_session_id: empty_string_to_none(snapshot.source_session_id),
|
||||
work_title: snapshot.work_title,
|
||||
work_description: snapshot.work_description,
|
||||
theme_prompt: snapshot.theme_prompt,
|
||||
cover_image_src: snapshot.cover_image_src,
|
||||
publication_status: normalize_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,
|
||||
generation_status: parse_generation_status(&snapshot.generation_status),
|
||||
},
|
||||
draft,
|
||||
board_background_asset,
|
||||
atlas_asset,
|
||||
pattern_groups,
|
||||
card_assets,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_puzzle_clear_draft_snapshot(snapshot: PuzzleClearDraftSnapshot) -> PuzzleClearDraftResponse {
|
||||
PuzzleClearDraftResponse {
|
||||
template_id: snapshot.template_id,
|
||||
template_name: snapshot.template_name,
|
||||
profile_id: snapshot.profile_id,
|
||||
work_title: snapshot.work_title,
|
||||
work_description: snapshot.work_description,
|
||||
theme_prompt: snapshot.theme_prompt,
|
||||
board_background_prompt: snapshot.board_background_prompt,
|
||||
generate_board_background: snapshot.generate_board_background,
|
||||
board_background_asset: snapshot.board_background_asset.map(map_image_asset),
|
||||
card_back_image_src: snapshot.card_back_image_src,
|
||||
atlas_asset: snapshot.atlas_asset.map(map_image_asset),
|
||||
pattern_groups: snapshot
|
||||
.pattern_groups
|
||||
.into_iter()
|
||||
.map(map_pattern_group)
|
||||
.collect(),
|
||||
card_assets: snapshot
|
||||
.card_assets
|
||||
.into_iter()
|
||||
.map(map_card_asset)
|
||||
.collect(),
|
||||
generation_status: parse_generation_status(&snapshot.generation_status),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_image_asset(snapshot: PuzzleClearImageAssetSnapshot) -> PuzzleClearImageAsset {
|
||||
PuzzleClearImageAsset {
|
||||
asset_id: snapshot.asset_id,
|
||||
image_src: snapshot.image_src,
|
||||
image_object_key: snapshot.image_object_key,
|
||||
asset_object_id: snapshot.asset_object_id,
|
||||
generation_provider: snapshot.generation_provider,
|
||||
prompt: snapshot.prompt,
|
||||
width: snapshot.width,
|
||||
height: snapshot.height,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_pattern_group(snapshot: PuzzleClearPatternGroupSnapshot) -> PuzzleClearPatternGroup {
|
||||
PuzzleClearPatternGroup {
|
||||
group_id: snapshot.group_id,
|
||||
shape: snapshot.shape,
|
||||
width: snapshot.width,
|
||||
height: snapshot.height,
|
||||
atlas_x: snapshot.atlas_x,
|
||||
atlas_y: snapshot.atlas_y,
|
||||
atlas_width: snapshot.atlas_width,
|
||||
atlas_height: snapshot.atlas_height,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_card_asset(snapshot: PuzzleClearCardAssetSnapshot) -> PuzzleClearCardAsset {
|
||||
PuzzleClearCardAsset {
|
||||
card_id: snapshot.card_id,
|
||||
group_id: snapshot.group_id,
|
||||
shape: snapshot.shape,
|
||||
orientation: snapshot.orientation,
|
||||
part_x: snapshot.part_x,
|
||||
part_y: snapshot.part_y,
|
||||
image_src: snapshot.image_src,
|
||||
image_object_key: snapshot.image_object_key,
|
||||
asset_object_id: snapshot.asset_object_id,
|
||||
source_atlas_cell: snapshot.source_atlas_cell,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_puzzle_clear_run_snapshot(
|
||||
snapshot: PuzzleClearRuntimeSnapshot,
|
||||
) -> PuzzleClearRuntimeSnapshotResponse {
|
||||
PuzzleClearRuntimeSnapshotResponse {
|
||||
run_id: snapshot.run_id,
|
||||
profile_id: snapshot.profile_id,
|
||||
owner_user_id: snapshot.owner_user_id,
|
||||
runtime_mode: None,
|
||||
status: parse_run_status(&snapshot.status),
|
||||
level_index: snapshot.level_index,
|
||||
clears_done: snapshot.clears_done,
|
||||
target_clears: snapshot.target_clears,
|
||||
level_duration_seconds: snapshot.level_duration_seconds,
|
||||
level_started_at_ms: snapshot.level_started_at_ms,
|
||||
board: PuzzleClearBoardSnapshot {
|
||||
rows: snapshot.board.rows,
|
||||
cols: snapshot.board.cols,
|
||||
cells: snapshot
|
||||
.board
|
||||
.cells
|
||||
.into_iter()
|
||||
.map(|cell| PuzzleClearBoardCell {
|
||||
row: cell.row,
|
||||
col: cell.col,
|
||||
card: cell.card.map(map_card_asset),
|
||||
locked_group_id: cell.locked_group_id,
|
||||
})
|
||||
.collect(),
|
||||
},
|
||||
ready_columns: snapshot
|
||||
.ready_columns
|
||||
.into_iter()
|
||||
.map(|column| column.into_iter().map(map_card_asset).collect())
|
||||
.collect(),
|
||||
started_at_ms: snapshot.started_at_ms,
|
||||
finished_at_ms: snapshot.finished_at_ms,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_generation_status(value: &str) -> PuzzleClearGenerationStatus {
|
||||
match value {
|
||||
"generating" => PuzzleClearGenerationStatus::Generating,
|
||||
"ready" => PuzzleClearGenerationStatus::Ready,
|
||||
"failed" => PuzzleClearGenerationStatus::Failed,
|
||||
_ => PuzzleClearGenerationStatus::Draft,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_run_status(value: &str) -> PuzzleClearRunStatus {
|
||||
match value {
|
||||
"level_failed" => PuzzleClearRunStatus::LevelFailed,
|
||||
"level_cleared" => PuzzleClearRunStatus::LevelCleared,
|
||||
"finished" => PuzzleClearRunStatus::Finished,
|
||||
_ => PuzzleClearRunStatus::Playing,
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_publication_status(value: &str) -> &str {
|
||||
match value {
|
||||
"Published" | "published" => "published",
|
||||
_ => "draft",
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user