1
This commit is contained in:
@@ -1396,9 +1396,13 @@ pub async fn use_puzzle_runtime_prop(
|
||||
));
|
||||
}
|
||||
};
|
||||
let should_sync_freeze_boundary = matches!(prop_kind.as_str(), "freezeTime" | "freeze_time");
|
||||
let billing_asset_id = format!("{}:{}:{}", run_id, prop_kind, current_utc_micros());
|
||||
let reducer_owner_user_id = owner_user_id.clone();
|
||||
let run = execute_billable_asset_operation(
|
||||
let reducer_run_id = run_id.clone();
|
||||
let fallback_run_id = run_id.clone();
|
||||
let fallback_owner_user_id = owner_user_id.clone();
|
||||
let run_result = execute_billable_asset_operation(
|
||||
&state,
|
||||
&owner_user_id,
|
||||
billing_asset_kind,
|
||||
@@ -1407,7 +1411,7 @@ pub async fn use_puzzle_runtime_prop(
|
||||
state
|
||||
.spacetime_client()
|
||||
.use_puzzle_runtime_prop(PuzzleRunPropRecordInput {
|
||||
run_id,
|
||||
run_id: reducer_run_id,
|
||||
owner_user_id: reducer_owner_user_id,
|
||||
prop_kind,
|
||||
used_at_micros: current_utc_micros(),
|
||||
@@ -1417,8 +1421,30 @@ pub async fn use_puzzle_runtime_prop(
|
||||
.map_err(map_puzzle_client_error)
|
||||
},
|
||||
)
|
||||
.await
|
||||
.map_err(|error| puzzle_error_response(&request_context, PUZZLE_RUNTIME_PROVIDER, error))?;
|
||||
.await;
|
||||
|
||||
let run = match run_result {
|
||||
Ok(run) => run,
|
||||
Err(error) if should_sync_puzzle_freeze_boundary(&error, should_sync_freeze_boundary) => {
|
||||
// 中文注释:冻结确认窗打开时前端会暂停视觉计时,但正式 run 仍可能在服务端边界帧先结算失败。
|
||||
// 这类情况已由扣费包装器退款,此处只同步失败态快照,避免玩家看到“操作不合法”。
|
||||
state
|
||||
.spacetime_client()
|
||||
.get_puzzle_run(fallback_run_id, fallback_owner_user_id)
|
||||
.await
|
||||
.map_err(map_puzzle_client_error)
|
||||
.map_err(|error| {
|
||||
puzzle_error_response(&request_context, PUZZLE_RUNTIME_PROVIDER, error)
|
||||
})?
|
||||
}
|
||||
Err(error) => {
|
||||
return Err(puzzle_error_response(
|
||||
&request_context,
|
||||
PUZZLE_RUNTIME_PROVIDER,
|
||||
error,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(json_success_body(
|
||||
Some(&request_context),
|
||||
@@ -2503,6 +2529,10 @@ fn map_puzzle_client_error(error: SpacetimeClientError) -> AppError {
|
||||
}))
|
||||
}
|
||||
|
||||
fn should_sync_puzzle_freeze_boundary(error: &AppError, is_freeze_time: bool) -> bool {
|
||||
is_freeze_time && error.body_text().contains("操作不合法")
|
||||
}
|
||||
|
||||
fn is_missing_puzzle_form_draft_procedure_error(error: &SpacetimeClientError) -> bool {
|
||||
matches!(error, SpacetimeClientError::Procedure(message) if
|
||||
message.contains("save_puzzle_form_draft")
|
||||
@@ -3580,6 +3610,26 @@ mod tests {
|
||||
let response = error.into_response();
|
||||
assert_eq!(response.status(), StatusCode::BAD_GATEWAY);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn freeze_boundary_sync_only_matches_freeze_invalid_operation() {
|
||||
let invalid_operation =
|
||||
AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
|
||||
"provider": "spacetimedb",
|
||||
"message": "操作不合法",
|
||||
}));
|
||||
let other_error = AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
|
||||
"provider": "spacetimedb",
|
||||
"message": "陶泥币余额不足",
|
||||
}));
|
||||
|
||||
assert!(should_sync_puzzle_freeze_boundary(&invalid_operation, true));
|
||||
assert!(!should_sync_puzzle_freeze_boundary(
|
||||
&invalid_operation,
|
||||
false
|
||||
));
|
||||
assert!(!should_sync_puzzle_freeze_boundary(&other_error, true));
|
||||
}
|
||||
}
|
||||
|
||||
struct PuzzleDashScopeSettings {
|
||||
|
||||
Reference in New Issue
Block a user