1
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"provider": "ark",
|
||||
"protocol": "responses",
|
||||
"model": "deepseek-v3-2-251201",
|
||||
"stream": false,
|
||||
"attempt": 1,
|
||||
"maxTokens": null,
|
||||
"messages": [
|
||||
{
|
||||
"role": "system",
|
||||
"content": "你是严格的世界草稿 JSON 生成器。\n只输出一个 JSON 对象,不要输出 Markdown、代码块、解释或额外文字。"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "请先根据下面的玩家设定创建一份“世界核心骨架”,后续我会分步骤生成角色名单、场景名单和详细档案。\n你必须只输出一个能被 JSON.parse 直接解析的 JSON 对象,不要输出 Markdown、代码块、注释或解释。\n这一步只保留世界顶层信息与一个开局归处占位,不要输出 playableNpcs、storyNpcs、landmarks,也不要展开人物、地图细节或多幕场景内容。\n玩家设定:\n世界承诺:{\"hook\":\"在失真的海图上追查一场被篡改的沉船事故。\"}\n玩家切入口:{\"entryMotivation\":\"查清父亲沉船真相\",\"openingIdentity\":\"被停职返乡的守灯人\",\"openingProblem\":\"灯塔记录被人改写\"}\n\n输出 JSON 模板:\n{\n \"name\": \"世界名称\",\n \"subtitle\": \"世界副标题\",\n \"summary\": \"世界概述\",\n \"tone\": \"世界基调\",\n \"playerGoal\": \"玩家核心目标\",\n \"templateWorldType\": \"WUXIA|XIANXIA\",\n \"majorFactions\": [\"势力甲\", \"势力乙\"],\n \"coreConflicts\": [\"冲突甲\", \"冲突乙\"],\n \"attributeSchema\": {\n \"slots\": [\n { \"name\": \"维度名\" },\n { \"name\": \"维度名\" },\n { \"name\": \"维度名\" },\n { \"name\": \"维度名\" },\n { \"name\": \"维度名\" },\n { \"name\": \"维度名\" }\n ]\n },\n \"camp\": {\n \"name\": \"开局归处名称\",\n \"description\": \"这是玩家进入世界后的第一处落脚点描述\"\n }\n}\n\n要求:\n- 所有生成文本都必须使用中文。\n- 这一步只输出顶层 10 个字段:name、subtitle、summary、tone、playerGoal、templateWorldType、majorFactions、coreConflicts、attributeSchema、camp。\n- 这是一个完全独立的自定义世界;不要在任何正文里直接写出“武侠世界”“仙侠世界”等现成世界名。\n- templateWorldType 只是系统兼容字段,不代表正文应当引用的世界名称。\n- camp 只表示玩家开局时的落脚处占位,更接近归舍、住处、栖居、前哨居所这类“家/归处”的概念;不要在这一步生成开局场景任务、三幕事件或三幕背景。\n- 不要输出 playableNpcs、storyNpcs、landmarks、items,也不要输出任何角色和地图细节。\n- majorFactions 保持 2 到 3 个,coreConflicts 保持 2 到 3 个。\n- attributeSchema 必须是本世界专属的角色六维名称体系,slots 必须恰好 6 个,每个 slot 只输出 name,维度名必须是 2 到 4 个汉字且互不重复。\n- attributeSchema.slots 的 name 禁止使用:生命、法力、护甲、攻击、防御、力量、敏捷、智力、精神;不要写通用 DND 或传统四维属性。\n- 不要在 attributeSchema.slots 内输出 definition、positiveSignals、negativeSignals、combatUseText、socialUseText、explorationUseText 或其他说明字段。\n- 世界设定必须直接源自玩家输入,不要脱离主题乱扩写。\n- 每个字符串尽量简洁:subtitle 控制在 8 到 18 个汉字内,summary 控制在 16 到 32 个汉字内,tone 控制在 6 到 16 个汉字内,playerGoal 控制在 16 到 32 个汉字内,camp.description 控制在 18 到 40 个汉字内。\n- 返回前自检:必须是一个能被 JSON.parse 直接解析的单个 JSON 对象。"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"choices":[{"message":{"content":"{\"name\":\"雾港归航\",\"subtitle\":\"失灯旧案\",\"summary\":\"守灯人与群岛议会围绕沉船旧案对峙。\",\"tone\":\"海雾悬疑\",\"playerGoal\":\"查清父亲沉船真相\",\"templateWorldType\":\"WUXIA\",\"majorFactions\":[\"群岛议会\",\"灯塔署\"],\"coreConflicts\":[\"守灯塔的旧档案被人改写。\"],\"attributeSchema\":{\"slots\":[{\"name\":\"灯骨\"},{\"name\":\"潮步\"},{\"name\":\"灯识\"},{\"name\":\"雾魄\"},{\"name\":\"旧约\"},{\"name\":\"回澜\"}]},\"camp\":{\"name\":\"旧灯塔归舍\",\"description\":\"海雾边缘的守灯人旧居。\"}}"}}],"id":"resp_01"}
|
||||
@@ -83,13 +83,13 @@ use crate::{
|
||||
phone_auth::{phone_login, send_phone_code},
|
||||
profile_identity::update_profile_identity,
|
||||
puzzle::{
|
||||
advance_local_puzzle_next_level, advance_puzzle_next_level, create_puzzle_agent_session,
|
||||
delete_puzzle_work, execute_puzzle_agent_action, get_puzzle_agent_session,
|
||||
get_puzzle_gallery_detail, get_puzzle_run, get_puzzle_work_detail, get_puzzle_works,
|
||||
list_puzzle_gallery, put_puzzle_work, record_puzzle_gallery_like,
|
||||
remix_puzzle_gallery_work, start_puzzle_run, stream_puzzle_agent_message,
|
||||
submit_puzzle_agent_message, submit_puzzle_leaderboard, swap_puzzle_pieces,
|
||||
update_puzzle_run_pause, use_puzzle_runtime_prop,
|
||||
advance_local_puzzle_next_level, advance_puzzle_next_level,
|
||||
claim_puzzle_work_point_incentive, create_puzzle_agent_session, delete_puzzle_work,
|
||||
execute_puzzle_agent_action, get_puzzle_agent_session, get_puzzle_gallery_detail,
|
||||
get_puzzle_run, get_puzzle_work_detail, get_puzzle_works, list_puzzle_gallery,
|
||||
put_puzzle_work, record_puzzle_gallery_like, remix_puzzle_gallery_work, start_puzzle_run,
|
||||
stream_puzzle_agent_message, submit_puzzle_agent_message, submit_puzzle_leaderboard,
|
||||
swap_puzzle_pieces, update_puzzle_run_pause, use_puzzle_runtime_prop,
|
||||
},
|
||||
refresh_session::refresh_session,
|
||||
request_context::{attach_request_context, resolve_request_id},
|
||||
@@ -764,6 +764,13 @@ pub fn build_router(state: AppState) -> Router {
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/puzzle/works/{profile_id}/point-incentive/claim",
|
||||
post(claim_puzzle_work_point_incentive).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route("/api/runtime/puzzle/gallery", get(list_puzzle_gallery))
|
||||
.route(
|
||||
"/api/runtime/puzzle/gallery/{profile_id}",
|
||||
|
||||
@@ -17,7 +17,10 @@ use module_assets::{
|
||||
AssetObjectAccessPolicy, AssetObjectFieldError, build_asset_entity_binding_input,
|
||||
build_asset_object_upsert_input, generate_asset_binding_id, generate_asset_object_id,
|
||||
};
|
||||
use module_puzzle::{PuzzleBoardSnapshot, PuzzleGeneratedImageCandidate, PuzzleRuntimeLevelStatus};
|
||||
use module_puzzle::{
|
||||
PuzzleBoardSnapshot, PuzzleGeneratedImageCandidate, PuzzleRuntimeLevelStatus,
|
||||
PuzzleWorkProfile, resolve_puzzle_level_config,
|
||||
};
|
||||
use platform_oss::{
|
||||
LegacyAssetPrefix, OssHeadObjectRequest, OssObjectAccess, OssPutObjectRequest,
|
||||
OssSignedGetObjectUrlRequest,
|
||||
@@ -61,8 +64,9 @@ use spacetime_client::{
|
||||
PuzzleResultPreviewBlockerRecord, PuzzleResultPreviewFindingRecord, PuzzleResultPreviewRecord,
|
||||
PuzzleRunPauseRecordInput, PuzzleRunPropRecordInput, PuzzleRunRecord,
|
||||
PuzzleRunStartRecordInput, PuzzleRunSwapRecordInput, PuzzleRuntimeLevelRecord,
|
||||
PuzzleSelectCoverImageRecordInput, PuzzleWorkLikeReportRecordInput, PuzzleWorkProfileRecord,
|
||||
PuzzleWorkRemixRecordInput, PuzzleWorkUpsertRecordInput, SpacetimeClientError,
|
||||
PuzzleSelectCoverImageRecordInput, PuzzleWorkLikeReportRecordInput,
|
||||
PuzzleWorkPointIncentiveClaimRecordInput, PuzzleWorkProfileRecord, PuzzleWorkRemixRecordInput,
|
||||
PuzzleWorkUpsertRecordInput, SpacetimeClientError,
|
||||
};
|
||||
use std::convert::Infallible;
|
||||
use tokio::time::sleep;
|
||||
@@ -966,6 +970,43 @@ pub async fn delete_puzzle_work(
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn claim_puzzle_work_point_incentive(
|
||||
State(state): State<AppState>,
|
||||
AxumPath(profile_id): AxumPath<String>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
Extension(authenticated): Extension<AuthenticatedAccessToken>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
ensure_non_empty(
|
||||
&request_context,
|
||||
PUZZLE_WORKS_PROVIDER,
|
||||
&profile_id,
|
||||
"profileId",
|
||||
)?;
|
||||
|
||||
let item = state
|
||||
.spacetime_client()
|
||||
.claim_puzzle_work_point_incentive(PuzzleWorkPointIncentiveClaimRecordInput {
|
||||
profile_id,
|
||||
owner_user_id: authenticated.claims().user_id().to_string(),
|
||||
claimed_at_micros: current_utc_micros(),
|
||||
})
|
||||
.await
|
||||
.map_err(|error| {
|
||||
puzzle_error_response(
|
||||
&request_context,
|
||||
PUZZLE_WORKS_PROVIDER,
|
||||
map_puzzle_client_error(error),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(json_success_body(
|
||||
Some(&request_context),
|
||||
PuzzleWorkMutationResponse {
|
||||
item: map_puzzle_work_profile_response(&state, item),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn list_puzzle_gallery(
|
||||
State(state): State<AppState>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
@@ -1370,6 +1411,7 @@ pub async fn use_puzzle_runtime_prop(
|
||||
owner_user_id: reducer_owner_user_id,
|
||||
prop_kind,
|
||||
used_at_micros: current_utc_micros(),
|
||||
spent_points: crate::asset_billing::ASSET_OPERATION_POINTS_COST,
|
||||
})
|
||||
.await
|
||||
.map_err(map_puzzle_client_error)
|
||||
@@ -1689,6 +1731,13 @@ fn map_puzzle_work_summary_response(
|
||||
remix_count: item.remix_count,
|
||||
like_count: item.like_count,
|
||||
recent_play_count_7d: item.recent_play_count_7d,
|
||||
point_incentive_total_half_points: item.point_incentive_total_half_points,
|
||||
point_incentive_claimed_points: item.point_incentive_claimed_points,
|
||||
point_incentive_total_points: item.point_incentive_total_half_points as f64 / 2.0,
|
||||
point_incentive_claimable_points: item
|
||||
.point_incentive_total_half_points
|
||||
.saturating_div(2)
|
||||
.saturating_sub(item.point_incentive_claimed_points),
|
||||
publish_ready: item.publish_ready,
|
||||
levels: Vec::new(),
|
||||
}
|
||||
@@ -1898,7 +1947,8 @@ fn map_puzzle_board_request_record(board: PuzzleBoardSnapshotResponse) -> Puzzle
|
||||
fn map_puzzle_runtime_level_response(
|
||||
level: spacetime_client::PuzzleRuntimeLevelRecord,
|
||||
) -> PuzzleRuntimeLevelSnapshotResponse {
|
||||
let timer_defaults = build_puzzle_runtime_timer_response_defaults(level.grid_size);
|
||||
let timer_defaults =
|
||||
build_puzzle_runtime_timer_response_defaults(level.level_index, level.grid_size);
|
||||
let time_limit_ms = if level.time_limit_ms == 0 {
|
||||
timer_defaults.time_limit_ms
|
||||
} else {
|
||||
@@ -1945,9 +1995,14 @@ struct PuzzleRuntimeTimerResponseDefaults {
|
||||
}
|
||||
|
||||
fn build_puzzle_runtime_timer_response_defaults(
|
||||
level_index: u32,
|
||||
grid_size: u32,
|
||||
) -> PuzzleRuntimeTimerResponseDefaults {
|
||||
let time_limit_ms = module_puzzle::resolve_puzzle_level_time_limit_ms(grid_size);
|
||||
let time_limit_ms = if level_index > 0 {
|
||||
module_puzzle::resolve_puzzle_level_time_limit_ms_by_index(level_index)
|
||||
} else {
|
||||
module_puzzle::resolve_puzzle_level_time_limit_ms(grid_size)
|
||||
};
|
||||
PuzzleRuntimeTimerResponseDefaults { time_limit_ms }
|
||||
}
|
||||
|
||||
@@ -2697,8 +2752,11 @@ async fn build_local_next_puzzle_run(
|
||||
return Ok(next_run);
|
||||
}
|
||||
|
||||
if let Some(gallery_item) = resolve_gallery_next_puzzle_work(state, &run).await? {
|
||||
return Ok(build_next_run_from_puzzle_work(state, run, gallery_item));
|
||||
let current_work = fetch_local_current_work_detail(state, &run).await?;
|
||||
let similar_works =
|
||||
resolve_gallery_similar_puzzle_works(state, &run, current_work.as_ref()).await?;
|
||||
if !similar_works.is_empty() {
|
||||
return Ok(build_local_similar_works_handoff(run, similar_works));
|
||||
}
|
||||
|
||||
if source_session_id.trim().is_empty() {
|
||||
@@ -2886,23 +2944,187 @@ async fn fetch_local_current_work_detail(
|
||||
}
|
||||
}
|
||||
|
||||
async fn resolve_gallery_next_puzzle_work(
|
||||
async fn resolve_gallery_similar_puzzle_works(
|
||||
state: &AppState,
|
||||
run: &PuzzleRunRecord,
|
||||
) -> Result<Option<PuzzleWorkProfileRecord>, AppError> {
|
||||
current_work: Option<&PuzzleWorkProfileRecord>,
|
||||
) -> Result<Vec<PuzzleRecommendedNextWorkRecord>, AppError> {
|
||||
let Some(current_profile) = build_recommendation_current_profile(run, current_work) else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
let items = state
|
||||
.spacetime_client()
|
||||
.list_puzzle_gallery()
|
||||
.await
|
||||
.map_err(map_puzzle_client_error)?;
|
||||
Ok(items.into_iter().find(|item| {
|
||||
item.publication_status == "published"
|
||||
&& item
|
||||
.cover_image_src
|
||||
.as_ref()
|
||||
.is_some_and(|value| !value.is_empty())
|
||||
&& !run.played_profile_ids.contains(&item.profile_id)
|
||||
}))
|
||||
let candidates = items
|
||||
.iter()
|
||||
.map(map_puzzle_work_profile_domain)
|
||||
.collect::<Vec<_>>();
|
||||
Ok(module_puzzle::select_next_profiles(
|
||||
¤t_profile,
|
||||
&run.played_profile_ids,
|
||||
&candidates,
|
||||
3,
|
||||
)
|
||||
.into_iter()
|
||||
.map(|candidate| build_recommended_next_work_record(¤t_profile, candidate))
|
||||
.collect())
|
||||
}
|
||||
|
||||
fn build_local_similar_works_handoff(
|
||||
mut run: PuzzleRunRecord,
|
||||
recommended_next_works: Vec<PuzzleRecommendedNextWorkRecord>,
|
||||
) -> PuzzleRunRecord {
|
||||
let next_profile_id = recommended_next_works
|
||||
.first()
|
||||
.map(|item| item.profile_id.clone());
|
||||
run.recommended_next_profile_id = next_profile_id.clone();
|
||||
run.next_level_mode = module_puzzle::PUZZLE_NEXT_LEVEL_MODE_SIMILAR_WORKS.to_string();
|
||||
run.next_level_profile_id = next_profile_id;
|
||||
run.next_level_id = None;
|
||||
run.recommended_next_works = recommended_next_works;
|
||||
run
|
||||
}
|
||||
|
||||
fn build_recommendation_current_profile(
|
||||
run: &PuzzleRunRecord,
|
||||
current_work: Option<&PuzzleWorkProfileRecord>,
|
||||
) -> Option<PuzzleWorkProfile> {
|
||||
if let Some(work) = current_work {
|
||||
return Some(map_puzzle_work_profile_domain(work));
|
||||
}
|
||||
|
||||
let level = run.current_level.as_ref()?;
|
||||
Some(PuzzleWorkProfile {
|
||||
work_id: format!("runtime-work-{}", level.profile_id),
|
||||
profile_id: level.profile_id.clone(),
|
||||
owner_user_id: String::new(),
|
||||
source_session_id: None,
|
||||
author_display_name: level.author_display_name.clone(),
|
||||
work_title: level.level_name.clone(),
|
||||
work_description: String::new(),
|
||||
level_name: level.level_name.clone(),
|
||||
summary: String::new(),
|
||||
theme_tags: level.theme_tags.clone(),
|
||||
cover_image_src: level.cover_image_src.clone(),
|
||||
cover_asset_id: None,
|
||||
levels: Vec::new(),
|
||||
publication_status: module_puzzle::PuzzlePublicationStatus::Published,
|
||||
updated_at_micros: 0,
|
||||
published_at_micros: None,
|
||||
play_count: 0,
|
||||
remix_count: 0,
|
||||
like_count: 0,
|
||||
recent_play_count_7d: 0,
|
||||
point_incentive_total_half_points: 0,
|
||||
point_incentive_claimed_points: 0,
|
||||
publish_ready: true,
|
||||
anchor_pack: module_puzzle::empty_anchor_pack(),
|
||||
})
|
||||
}
|
||||
|
||||
fn map_puzzle_work_profile_domain(item: &PuzzleWorkProfileRecord) -> PuzzleWorkProfile {
|
||||
PuzzleWorkProfile {
|
||||
work_id: item.work_id.clone(),
|
||||
profile_id: item.profile_id.clone(),
|
||||
owner_user_id: item.owner_user_id.clone(),
|
||||
source_session_id: item.source_session_id.clone(),
|
||||
author_display_name: item.author_display_name.clone(),
|
||||
work_title: item.work_title.clone(),
|
||||
work_description: item.work_description.clone(),
|
||||
level_name: item.level_name.clone(),
|
||||
summary: item.summary.clone(),
|
||||
theme_tags: item.theme_tags.clone(),
|
||||
cover_image_src: item.cover_image_src.clone(),
|
||||
cover_asset_id: item.cover_asset_id.clone(),
|
||||
levels: item
|
||||
.levels
|
||||
.iter()
|
||||
.map(map_puzzle_draft_level_domain)
|
||||
.collect(),
|
||||
publication_status: match item.publication_status.as_str() {
|
||||
"published" => module_puzzle::PuzzlePublicationStatus::Published,
|
||||
_ => module_puzzle::PuzzlePublicationStatus::Draft,
|
||||
},
|
||||
updated_at_micros: parse_puzzle_record_timestamp_micros(&item.updated_at),
|
||||
published_at_micros: item
|
||||
.published_at
|
||||
.as_deref()
|
||||
.map(parse_puzzle_record_timestamp_micros),
|
||||
play_count: item.play_count,
|
||||
remix_count: item.remix_count,
|
||||
like_count: item.like_count,
|
||||
recent_play_count_7d: item.recent_play_count_7d,
|
||||
point_incentive_total_half_points: item.point_incentive_total_half_points,
|
||||
point_incentive_claimed_points: item.point_incentive_claimed_points,
|
||||
publish_ready: item.publish_ready,
|
||||
anchor_pack: module_puzzle::empty_anchor_pack(),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_puzzle_draft_level_domain(
|
||||
level: &PuzzleDraftLevelRecord,
|
||||
) -> module_puzzle::PuzzleDraftLevel {
|
||||
module_puzzle::PuzzleDraftLevel {
|
||||
level_id: level.level_id.clone(),
|
||||
level_name: level.level_name.clone(),
|
||||
picture_description: level.picture_description.clone(),
|
||||
candidates: level
|
||||
.candidates
|
||||
.iter()
|
||||
.map(map_puzzle_generated_image_candidate_domain)
|
||||
.collect(),
|
||||
selected_candidate_id: level.selected_candidate_id.clone(),
|
||||
cover_image_src: level.cover_image_src.clone(),
|
||||
cover_asset_id: level.cover_asset_id.clone(),
|
||||
generation_status: level.generation_status.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_puzzle_generated_image_candidate_domain(
|
||||
candidate: &PuzzleGeneratedImageCandidateRecord,
|
||||
) -> PuzzleGeneratedImageCandidate {
|
||||
PuzzleGeneratedImageCandidate {
|
||||
candidate_id: candidate.candidate_id.clone(),
|
||||
image_src: candidate.image_src.clone(),
|
||||
asset_id: candidate.asset_id.clone(),
|
||||
prompt: candidate.prompt.clone(),
|
||||
actual_prompt: candidate.actual_prompt.clone(),
|
||||
source_type: candidate.source_type.clone(),
|
||||
selected: candidate.selected,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_recommended_next_work_record(
|
||||
current_profile: &PuzzleWorkProfile,
|
||||
candidate: &PuzzleWorkProfile,
|
||||
) -> PuzzleRecommendedNextWorkRecord {
|
||||
PuzzleRecommendedNextWorkRecord {
|
||||
profile_id: candidate.profile_id.clone(),
|
||||
level_name: candidate.level_name.clone(),
|
||||
author_display_name: candidate.author_display_name.clone(),
|
||||
theme_tags: candidate.theme_tags.clone(),
|
||||
cover_image_src: candidate.cover_image_src.clone(),
|
||||
similarity_score: module_puzzle::tag_similarity_score(
|
||||
¤t_profile.theme_tags,
|
||||
&candidate.theme_tags,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_puzzle_record_timestamp_micros(value: &str) -> i64 {
|
||||
let Some((seconds, rest)) = value.split_once('.') else {
|
||||
return 0;
|
||||
};
|
||||
let micros = rest.strip_suffix('Z').unwrap_or(rest);
|
||||
let Ok(seconds) = seconds.parse::<i64>() else {
|
||||
return 0;
|
||||
};
|
||||
let Ok(micros) = micros.parse::<i64>() else {
|
||||
return 0;
|
||||
};
|
||||
seconds.saturating_mul(1_000_000).saturating_add(micros)
|
||||
}
|
||||
|
||||
fn pick_unused_puzzle_candidate<'a>(
|
||||
@@ -2987,27 +3209,6 @@ fn resolve_level_cover_image_src(level: &PuzzleDraftLevelRecord) -> Option<Strin
|
||||
})
|
||||
}
|
||||
|
||||
fn build_next_run_from_puzzle_work(
|
||||
state: &AppState,
|
||||
run: PuzzleRunRecord,
|
||||
item: PuzzleWorkProfileRecord,
|
||||
) -> PuzzleRunRecord {
|
||||
let author = resolve_work_author_by_user_id(
|
||||
state,
|
||||
&item.owner_user_id,
|
||||
Some(&item.author_display_name),
|
||||
None,
|
||||
);
|
||||
build_next_run_from_parts(
|
||||
run,
|
||||
item.profile_id,
|
||||
item.level_name,
|
||||
author.display_name,
|
||||
item.theme_tags,
|
||||
item.cover_image_src,
|
||||
)
|
||||
}
|
||||
|
||||
fn build_next_run_from_candidate(
|
||||
run: PuzzleRunRecord,
|
||||
session: &PuzzleAgentSessionRecord,
|
||||
@@ -3089,8 +3290,9 @@ fn build_next_run_from_parts_with_handoff(
|
||||
next_after_level_id: Option<String>,
|
||||
) -> PuzzleRunRecord {
|
||||
let next_level_index = run.current_level_index + 1;
|
||||
let grid_size = if run.cleared_level_count >= 3 { 4 } else { 3 };
|
||||
let time_limit_ms = module_puzzle::resolve_puzzle_level_time_limit_ms(grid_size);
|
||||
let level_config = resolve_puzzle_level_config(next_level_index);
|
||||
let grid_size = level_config.grid_size;
|
||||
let time_limit_ms = level_config.time_limit_ms;
|
||||
let mut played_profile_ids = run.played_profile_ids.clone();
|
||||
let current_level_id = run.next_level_id.clone();
|
||||
if !played_profile_ids.contains(&profile_id) {
|
||||
@@ -3250,6 +3452,98 @@ mod tests {
|
||||
assert!(!has_original_neighbor_pair(&third));
|
||||
}
|
||||
|
||||
fn test_recommended_work(profile_id: &str, score: f32) -> PuzzleRecommendedNextWorkRecord {
|
||||
PuzzleRecommendedNextWorkRecord {
|
||||
profile_id: profile_id.to_string(),
|
||||
level_name: format!("{profile_id} 关"),
|
||||
author_display_name: "作者".to_string(),
|
||||
theme_tags: vec!["奇幻".to_string()],
|
||||
cover_image_src: Some(format!("/{profile_id}.png")),
|
||||
similarity_score: score,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_similar_works_handoff_keeps_cleared_run_for_user_choice() {
|
||||
let run = PuzzleRunRecord {
|
||||
run_id: "local-puzzle-run-a".to_string(),
|
||||
entry_profile_id: "profile-current".to_string(),
|
||||
cleared_level_count: 1,
|
||||
current_level_index: 1,
|
||||
current_grid_size: 3,
|
||||
played_profile_ids: vec!["profile-current".to_string()],
|
||||
previous_level_tags: vec!["奇幻".to_string()],
|
||||
current_level: Some(PuzzleRuntimeLevelRecord {
|
||||
run_id: "local-puzzle-run-a".to_string(),
|
||||
level_index: 1,
|
||||
level_id: Some("puzzle-level-1".to_string()),
|
||||
grid_size: 3,
|
||||
profile_id: "profile-current".to_string(),
|
||||
level_name: "当前拼图".to_string(),
|
||||
author_display_name: "当前作者".to_string(),
|
||||
theme_tags: vec!["奇幻".to_string()],
|
||||
cover_image_src: Some("/current.png".to_string()),
|
||||
board: build_local_puzzle_board(3, "local-puzzle-run-a", "profile-current", 1),
|
||||
status: "cleared".to_string(),
|
||||
started_at_ms: 1_000,
|
||||
cleared_at_ms: Some(2_000),
|
||||
elapsed_ms: Some(1_000),
|
||||
time_limit_ms: 300_000,
|
||||
remaining_ms: 0,
|
||||
paused_accumulated_ms: 0,
|
||||
pause_started_at_ms: None,
|
||||
freeze_accumulated_ms: 0,
|
||||
freeze_started_at_ms: None,
|
||||
freeze_until_ms: None,
|
||||
leaderboard_entries: Vec::new(),
|
||||
}),
|
||||
recommended_next_profile_id: None,
|
||||
next_level_mode: module_puzzle::PUZZLE_NEXT_LEVEL_MODE_NONE.to_string(),
|
||||
next_level_profile_id: None,
|
||||
next_level_id: None,
|
||||
recommended_next_works: Vec::new(),
|
||||
leaderboard_entries: Vec::new(),
|
||||
};
|
||||
|
||||
let next_run = build_local_similar_works_handoff(
|
||||
run,
|
||||
vec![
|
||||
test_recommended_work("profile-a", 0.9),
|
||||
test_recommended_work("profile-b", 0.8),
|
||||
test_recommended_work("profile-c", 0.7),
|
||||
],
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
next_run.next_level_mode,
|
||||
module_puzzle::PUZZLE_NEXT_LEVEL_MODE_SIMILAR_WORKS
|
||||
);
|
||||
assert_eq!(
|
||||
next_run.recommended_next_profile_id.as_deref(),
|
||||
Some("profile-a")
|
||||
);
|
||||
assert_eq!(next_run.next_level_profile_id.as_deref(), Some("profile-a"));
|
||||
assert_eq!(next_run.next_level_id, None);
|
||||
assert_eq!(next_run.recommended_next_works.len(), 3);
|
||||
assert_eq!(next_run.current_level_index, 1);
|
||||
assert_eq!(
|
||||
next_run
|
||||
.current_level
|
||||
.as_ref()
|
||||
.map(|level| level.status.as_str()),
|
||||
Some("cleared")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn puzzle_record_timestamp_parser_matches_shared_format() {
|
||||
assert_eq!(
|
||||
parse_puzzle_record_timestamp_micros("1713686401.234567Z"),
|
||||
1_713_686_401_234_567
|
||||
);
|
||||
assert_eq!(parse_puzzle_record_timestamp_micros("bad-value"), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn puzzle_generated_image_size_is_square_1_1() {
|
||||
assert_eq!(PUZZLE_GENERATED_IMAGE_SIZE, "1024*1024");
|
||||
|
||||
@@ -21,6 +21,7 @@ use shared_contracts::runtime::{
|
||||
PROFILE_WALLET_LEDGER_SOURCE_TYPE_INVITE_INVITEE_REWARD,
|
||||
PROFILE_WALLET_LEDGER_SOURCE_TYPE_INVITE_INVITER_REWARD,
|
||||
PROFILE_WALLET_LEDGER_SOURCE_TYPE_POINTS_RECHARGE,
|
||||
PROFILE_WALLET_LEDGER_SOURCE_TYPE_PUZZLE_AUTHOR_INCENTIVE_CLAIM,
|
||||
PROFILE_WALLET_LEDGER_SOURCE_TYPE_REDEEM_CODE_REWARD,
|
||||
PROFILE_WALLET_LEDGER_SOURCE_TYPE_SNAPSHOT_SYNC, ProfileDashboardSummaryResponse,
|
||||
ProfileMembershipBenefitResponse, ProfileMembershipResponse, ProfilePlayStatsResponse,
|
||||
@@ -127,6 +128,9 @@ fn format_profile_wallet_ledger_source_type(
|
||||
RuntimeProfileWalletLedgerSourceType::RedeemCodeReward => {
|
||||
PROFILE_WALLET_LEDGER_SOURCE_TYPE_REDEEM_CODE_REWARD
|
||||
}
|
||||
RuntimeProfileWalletLedgerSourceType::PuzzleAuthorIncentiveClaim => {
|
||||
PROFILE_WALLET_LEDGER_SOURCE_TYPE_PUZZLE_AUTHOR_INCENTIVE_CLAIM
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,7 +566,7 @@ mod tests {
|
||||
use crate::{app::build_router, config::AppConfig, state::AppState};
|
||||
|
||||
#[test]
|
||||
fn profile_wallet_ledger_source_type_formats_asset_operation_values() {
|
||||
fn profile_wallet_ledger_source_type_formats_backend_values() {
|
||||
assert_eq!(
|
||||
format_profile_wallet_ledger_source_type(
|
||||
RuntimeProfileWalletLedgerSourceType::AssetOperationConsume
|
||||
@@ -575,6 +579,12 @@ mod tests {
|
||||
),
|
||||
shared_contracts::runtime::PROFILE_WALLET_LEDGER_SOURCE_TYPE_ASSET_OPERATION_REFUND
|
||||
);
|
||||
assert_eq!(
|
||||
format_profile_wallet_ledger_source_type(
|
||||
RuntimeProfileWalletLedgerSourceType::PuzzleAuthorIncentiveClaim
|
||||
),
|
||||
shared_contracts::runtime::PROFILE_WALLET_LEDGER_SOURCE_TYPE_PUZZLE_AUTHOR_INCENTIVE_CLAIM
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@@ -20,8 +20,16 @@ pub const PUZZLE_EXTEND_TIME_DURATION_MS: u64 = 60_000;
|
||||
pub const PUZZLE_NEXT_LEVEL_MODE_SAME_WORK: &str = "sameWork";
|
||||
pub const PUZZLE_NEXT_LEVEL_MODE_SIMILAR_WORKS: &str = "similarWorks";
|
||||
pub const PUZZLE_NEXT_LEVEL_MODE_NONE: &str = "none";
|
||||
pub const PUZZLE_SUPPORTED_GRID_SIZES: [u32; 5] = [3, 4, 5, 6, 7];
|
||||
const PUZZLE_INITIAL_SHUFFLE_ATTEMPTS: u64 = 64;
|
||||
|
||||
// 中文注释:拼图难度只从关卡序号解析,避免切割规格和倒计时在不同入口各写一套。
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct PuzzleLevelConfig {
|
||||
pub grid_size: u32,
|
||||
pub time_limit_ms: u64,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum PuzzleAgentStage {
|
||||
@@ -257,6 +265,10 @@ pub struct PuzzleWorkProfile {
|
||||
pub like_count: u32,
|
||||
#[serde(default)]
|
||||
pub recent_play_count_7d: u32,
|
||||
#[serde(default)]
|
||||
pub point_incentive_total_half_points: u64,
|
||||
#[serde(default)]
|
||||
pub point_incentive_claimed_points: u64,
|
||||
pub publish_ready: bool,
|
||||
pub anchor_pack: PuzzleAnchorPack,
|
||||
}
|
||||
@@ -540,6 +552,14 @@ pub struct PuzzleWorkLikeRecordInput {
|
||||
pub liked_at_micros: i64,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct PuzzleWorkPointIncentiveClaimInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub claimed_at_micros: i64,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct PuzzleRunStartInput {
|
||||
@@ -602,6 +622,8 @@ pub struct PuzzleRunPropInput {
|
||||
pub owner_user_id: String,
|
||||
pub prop_kind: String,
|
||||
pub used_at_micros: i64,
|
||||
#[serde(default)]
|
||||
pub spent_points: u64,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
@@ -1298,6 +1320,8 @@ pub fn create_work_profile(
|
||||
remix_count: 0,
|
||||
like_count: 0,
|
||||
recent_play_count_7d: 0,
|
||||
point_incentive_total_half_points: 0,
|
||||
point_incentive_claimed_points: 0,
|
||||
publish_ready: preview.publish_ready,
|
||||
anchor_pack: draft.anchor_pack.clone(),
|
||||
})
|
||||
@@ -1411,20 +1435,81 @@ pub fn normalize_puzzle_levels(
|
||||
Ok(normalized_levels)
|
||||
}
|
||||
|
||||
pub fn is_supported_puzzle_grid_size(grid_size: u32) -> bool {
|
||||
PUZZLE_SUPPORTED_GRID_SIZES.contains(&grid_size)
|
||||
}
|
||||
|
||||
pub fn resolve_puzzle_level_config(level_index: u32) -> PuzzleLevelConfig {
|
||||
let level_index = level_index.max(1);
|
||||
match level_index {
|
||||
1 => PuzzleLevelConfig {
|
||||
grid_size: 3,
|
||||
time_limit_ms: 300_000,
|
||||
},
|
||||
2 => PuzzleLevelConfig {
|
||||
grid_size: 4,
|
||||
time_limit_ms: 300_000,
|
||||
},
|
||||
3 => PuzzleLevelConfig {
|
||||
grid_size: 5,
|
||||
time_limit_ms: 300_000,
|
||||
},
|
||||
4 => PuzzleLevelConfig {
|
||||
grid_size: 5,
|
||||
time_limit_ms: 210_000,
|
||||
},
|
||||
_ => {
|
||||
let loop_index = (level_index.saturating_sub(5) % 6) + 5;
|
||||
match loop_index {
|
||||
5 => PuzzleLevelConfig {
|
||||
grid_size: 5,
|
||||
time_limit_ms: 210_000,
|
||||
},
|
||||
6 => PuzzleLevelConfig {
|
||||
grid_size: 6,
|
||||
time_limit_ms: 240_000,
|
||||
},
|
||||
7 => PuzzleLevelConfig {
|
||||
grid_size: 5,
|
||||
time_limit_ms: 210_000,
|
||||
},
|
||||
8 => PuzzleLevelConfig {
|
||||
grid_size: 7,
|
||||
time_limit_ms: 270_000,
|
||||
},
|
||||
9 => PuzzleLevelConfig {
|
||||
grid_size: 5,
|
||||
time_limit_ms: 240_000,
|
||||
},
|
||||
_ => PuzzleLevelConfig {
|
||||
grid_size: 7,
|
||||
time_limit_ms: 270_000,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_puzzle_grid_size(cleared_level_count: u32) -> u32 {
|
||||
if cleared_level_count >= 3 { 4 } else { 3 }
|
||||
resolve_puzzle_level_config(cleared_level_count + 1).grid_size
|
||||
}
|
||||
|
||||
pub fn resolve_puzzle_level_time_limit_ms_by_index(level_index: u32) -> u64 {
|
||||
resolve_puzzle_level_config(level_index.max(1)).time_limit_ms
|
||||
}
|
||||
|
||||
pub fn resolve_puzzle_level_time_limit_ms(grid_size: u32) -> u64 {
|
||||
match grid_size {
|
||||
4 => 300_000,
|
||||
_ => 180_000,
|
||||
3 | 4 | 5 => 300_000,
|
||||
6 => 240_000,
|
||||
7 => 270_000,
|
||||
_ => 300_000,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_puzzle_runtime_remaining_ms(level: &PuzzleRuntimeLevelSnapshot, now_ms: u64) -> u64 {
|
||||
let time_limit_ms = if level.time_limit_ms == 0 {
|
||||
resolve_puzzle_level_time_limit_ms(level.grid_size)
|
||||
resolve_puzzle_level_time_limit_ms_by_index(level.level_index)
|
||||
} else {
|
||||
level.time_limit_ms
|
||||
};
|
||||
@@ -1436,7 +1521,7 @@ fn normalize_timer_fields(level: &mut PuzzleRuntimeLevelSnapshot, now_ms: u64) {
|
||||
level.started_at_ms = now_ms;
|
||||
}
|
||||
if level.time_limit_ms == 0 {
|
||||
level.time_limit_ms = resolve_puzzle_level_time_limit_ms(level.grid_size);
|
||||
level.time_limit_ms = resolve_puzzle_level_time_limit_ms_by_index(level.level_index);
|
||||
}
|
||||
if level.remaining_ms == 0 && level.status == PuzzleRuntimeLevelStatus::Playing {
|
||||
level.remaining_ms = level.time_limit_ms;
|
||||
@@ -1612,7 +1697,7 @@ pub fn build_initial_board_with_seed(
|
||||
grid_size: u32,
|
||||
shuffle_seed: u64,
|
||||
) -> Result<PuzzleBoardSnapshot, PuzzleFieldError> {
|
||||
if !matches!(grid_size, 3 | 4) {
|
||||
if !is_supported_puzzle_grid_size(grid_size) {
|
||||
return Err(PuzzleFieldError::InvalidGridSize);
|
||||
}
|
||||
|
||||
@@ -1678,19 +1763,21 @@ pub fn start_run_with_shuffle_seed_at(
|
||||
shuffle_seed: u64,
|
||||
started_at_ms: u64,
|
||||
) -> Result<PuzzleRunSnapshot, PuzzleFieldError> {
|
||||
let grid_size = resolve_puzzle_grid_size(cleared_level_count);
|
||||
let level_index = cleared_level_count + 1;
|
||||
let level_config = resolve_puzzle_level_config(level_index);
|
||||
let grid_size = level_config.grid_size;
|
||||
let board = build_initial_board_with_seed(grid_size, shuffle_seed)?;
|
||||
Ok(PuzzleRunSnapshot {
|
||||
run_id: run_id.clone(),
|
||||
entry_profile_id: entry_profile.profile_id.clone(),
|
||||
cleared_level_count,
|
||||
current_level_index: cleared_level_count + 1,
|
||||
current_level_index: level_index,
|
||||
current_grid_size: grid_size,
|
||||
played_profile_ids: vec![entry_profile.profile_id.clone()],
|
||||
previous_level_tags: entry_profile.theme_tags.clone(),
|
||||
current_level: Some(PuzzleRuntimeLevelSnapshot {
|
||||
run_id,
|
||||
level_index: cleared_level_count + 1,
|
||||
level_index,
|
||||
level_id: entry_profile
|
||||
.levels
|
||||
.first()
|
||||
@@ -1706,8 +1793,8 @@ pub fn start_run_with_shuffle_seed_at(
|
||||
started_at_ms,
|
||||
cleared_at_ms: None,
|
||||
elapsed_ms: None,
|
||||
time_limit_ms: resolve_puzzle_level_time_limit_ms(grid_size),
|
||||
remaining_ms: resolve_puzzle_level_time_limit_ms(grid_size),
|
||||
time_limit_ms: level_config.time_limit_ms,
|
||||
remaining_ms: level_config.time_limit_ms,
|
||||
paused_accumulated_ms: 0,
|
||||
pause_started_at_ms: None,
|
||||
freeze_accumulated_ms: 0,
|
||||
@@ -1938,11 +2025,13 @@ pub fn advance_next_level_at(
|
||||
}
|
||||
|
||||
let next_cleared_count = run.cleared_level_count;
|
||||
let next_grid_size = resolve_puzzle_grid_size(next_cleared_count);
|
||||
let next_level_index = run.current_level_index + 1;
|
||||
let next_level_config = resolve_puzzle_level_config(next_level_index);
|
||||
let next_grid_size = next_level_config.grid_size;
|
||||
let shuffle_seed = puzzle_shuffle_seed(
|
||||
&run.run_id,
|
||||
&next_profile.profile_id,
|
||||
run.current_level_index + 1,
|
||||
next_level_index,
|
||||
next_grid_size,
|
||||
);
|
||||
let next_board = build_initial_board_with_seed(next_grid_size, shuffle_seed)?;
|
||||
@@ -1953,13 +2042,13 @@ pub fn advance_next_level_at(
|
||||
run_id: run.run_id.clone(),
|
||||
entry_profile_id: run.entry_profile_id.clone(),
|
||||
cleared_level_count: next_cleared_count,
|
||||
current_level_index: run.current_level_index + 1,
|
||||
current_level_index: next_level_index,
|
||||
current_grid_size: next_grid_size,
|
||||
played_profile_ids,
|
||||
previous_level_tags: next_profile.theme_tags.clone(),
|
||||
current_level: Some(PuzzleRuntimeLevelSnapshot {
|
||||
run_id: run.run_id.clone(),
|
||||
level_index: run.current_level_index + 1,
|
||||
level_index: next_level_index,
|
||||
level_id: next_profile
|
||||
.levels
|
||||
.first()
|
||||
@@ -1975,8 +2064,81 @@ pub fn advance_next_level_at(
|
||||
started_at_ms,
|
||||
cleared_at_ms: None,
|
||||
elapsed_ms: None,
|
||||
time_limit_ms: resolve_puzzle_level_time_limit_ms(next_grid_size),
|
||||
remaining_ms: resolve_puzzle_level_time_limit_ms(next_grid_size),
|
||||
time_limit_ms: next_level_config.time_limit_ms,
|
||||
remaining_ms: next_level_config.time_limit_ms,
|
||||
paused_accumulated_ms: 0,
|
||||
pause_started_at_ms: None,
|
||||
freeze_accumulated_ms: 0,
|
||||
freeze_started_at_ms: None,
|
||||
freeze_until_ms: None,
|
||||
leaderboard_entries: Vec::new(),
|
||||
}),
|
||||
recommended_next_profile_id: None,
|
||||
next_level_mode: default_puzzle_next_level_mode(),
|
||||
next_level_profile_id: None,
|
||||
next_level_id: None,
|
||||
recommended_next_works: Vec::new(),
|
||||
leaderboard_entries: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn advance_to_new_work_first_level_at(
|
||||
run: &PuzzleRunSnapshot,
|
||||
next_profile: &PuzzleWorkProfile,
|
||||
started_at_ms: u64,
|
||||
) -> Result<PuzzleRunSnapshot, PuzzleFieldError> {
|
||||
let current_level = run
|
||||
.current_level
|
||||
.clone()
|
||||
.ok_or(PuzzleFieldError::InvalidOperation)?;
|
||||
if current_level.status != PuzzleRuntimeLevelStatus::Cleared {
|
||||
return Err(PuzzleFieldError::InvalidOperation);
|
||||
}
|
||||
|
||||
// 中文注释:跨作品代表进入一个新作品,关卡序号、切割规格和倒计时都从第 1 关重新开始。
|
||||
let next_level_index = 1;
|
||||
let level_config = resolve_puzzle_level_config(next_level_index);
|
||||
let grid_size = level_config.grid_size;
|
||||
let shuffle_seed = puzzle_shuffle_seed(
|
||||
&run.run_id,
|
||||
&next_profile.profile_id,
|
||||
next_level_index,
|
||||
grid_size,
|
||||
);
|
||||
let next_board = build_initial_board_with_seed(grid_size, shuffle_seed)?;
|
||||
let mut played_profile_ids = run.played_profile_ids.clone();
|
||||
if !played_profile_ids.contains(&next_profile.profile_id) {
|
||||
played_profile_ids.push(next_profile.profile_id.clone());
|
||||
}
|
||||
|
||||
Ok(PuzzleRunSnapshot {
|
||||
run_id: run.run_id.clone(),
|
||||
entry_profile_id: next_profile.profile_id.clone(),
|
||||
cleared_level_count: 0,
|
||||
current_level_index: next_level_index,
|
||||
current_grid_size: grid_size,
|
||||
played_profile_ids,
|
||||
previous_level_tags: next_profile.theme_tags.clone(),
|
||||
current_level: Some(PuzzleRuntimeLevelSnapshot {
|
||||
run_id: run.run_id.clone(),
|
||||
level_index: next_level_index,
|
||||
level_id: next_profile
|
||||
.levels
|
||||
.first()
|
||||
.map(|level| level.level_id.clone()),
|
||||
grid_size,
|
||||
profile_id: next_profile.profile_id.clone(),
|
||||
level_name: next_profile.level_name.clone(),
|
||||
author_display_name: next_profile.author_display_name.clone(),
|
||||
theme_tags: next_profile.theme_tags.clone(),
|
||||
cover_image_src: next_profile.cover_image_src.clone(),
|
||||
board: next_board,
|
||||
status: PuzzleRuntimeLevelStatus::Playing,
|
||||
started_at_ms,
|
||||
cleared_at_ms: None,
|
||||
elapsed_ms: None,
|
||||
time_limit_ms: level_config.time_limit_ms,
|
||||
remaining_ms: level_config.time_limit_ms,
|
||||
paused_accumulated_ms: 0,
|
||||
pause_started_at_ms: None,
|
||||
freeze_accumulated_ms: 0,
|
||||
@@ -2058,6 +2220,11 @@ pub fn selected_profile_level_index(profile: &PuzzleWorkProfile, level_id: &str)
|
||||
.position(|level| level.level_id == target_level_id)
|
||||
}
|
||||
|
||||
pub fn resolve_restart_cleared_level_count(profile: &PuzzleWorkProfile, level_id: &str) -> u32 {
|
||||
// 中文注释:失败重开指定的是当前关 levelId;start_run_at 用“已通关数 + 1”计算当前关,所以这里返回关卡下标。
|
||||
selected_profile_level_index(profile, level_id).unwrap_or(0) as u32
|
||||
}
|
||||
|
||||
pub fn select_next_profile<'a>(
|
||||
current_profile: &PuzzleWorkProfile,
|
||||
played_profile_ids: &[String],
|
||||
@@ -2618,7 +2785,8 @@ fn build_initial_pieces_without_correct_neighbors(
|
||||
}
|
||||
|
||||
// 随机尝试耗尽后使用确定性约束搜索兜底,保证开局没有任意一对原图相邻块互相贴边。
|
||||
let fallback_pieces = build_original_neighbor_free_pieces(grid_size, shuffle_seed)
|
||||
let fallback_pieces = build_deterministic_neighbor_free_pieces(grid_size, shuffle_seed)
|
||||
.or_else(|| build_original_neighbor_free_pieces(grid_size, shuffle_seed))
|
||||
.unwrap_or_else(|| build_pieces_from_positions(grid_size, &base_positions));
|
||||
debug_assert!(!has_any_original_neighbor_pair(&fallback_pieces));
|
||||
fallback_pieces
|
||||
@@ -2686,6 +2854,124 @@ fn are_original_neighbors(left: &PuzzlePieceState, right: &PuzzlePieceState) ->
|
||||
left.correct_row.abs_diff(right.correct_row) + left.correct_col.abs_diff(right.correct_col) == 1
|
||||
}
|
||||
|
||||
fn build_deterministic_neighbor_free_pieces(
|
||||
grid_size: u32,
|
||||
shuffle_seed: u64,
|
||||
) -> Option<Vec<PuzzlePieceState>> {
|
||||
// 中文注释:大棋盘随机命中“无原图相邻贴边”的概率较低,失败后用确定性排列兜底保证稳定开局。
|
||||
let positions = match grid_size {
|
||||
3 => build_seeded_3x3_neighbor_free_positions(shuffle_seed),
|
||||
4 | 6 => build_affine_neighbor_free_positions(grid_size, 1, 1, 2, 1, shuffle_seed),
|
||||
5 | 7 => {
|
||||
build_affine_neighbor_free_positions(grid_size, 0, 1, 2, grid_size - 1, shuffle_seed)
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
let pieces = build_pieces_from_positions(grid_size, &positions);
|
||||
(!has_any_original_neighbor_pair(&pieces)).then_some(pieces)
|
||||
}
|
||||
|
||||
fn build_seeded_3x3_neighbor_free_positions(shuffle_seed: u64) -> Vec<PuzzleCellPosition> {
|
||||
const LAYOUTS: [[(u32, u32); 9]; 6] = [
|
||||
[
|
||||
(0, 1),
|
||||
(1, 0),
|
||||
(1, 2),
|
||||
(2, 0),
|
||||
(0, 2),
|
||||
(2, 1),
|
||||
(1, 1),
|
||||
(2, 2),
|
||||
(0, 0),
|
||||
],
|
||||
[
|
||||
(0, 1),
|
||||
(1, 0),
|
||||
(1, 2),
|
||||
(2, 0),
|
||||
(0, 2),
|
||||
(2, 1),
|
||||
(2, 2),
|
||||
(1, 1),
|
||||
(0, 0),
|
||||
],
|
||||
[
|
||||
(0, 1),
|
||||
(1, 0),
|
||||
(1, 2),
|
||||
(2, 0),
|
||||
(2, 2),
|
||||
(0, 0),
|
||||
(1, 1),
|
||||
(0, 2),
|
||||
(2, 1),
|
||||
],
|
||||
[
|
||||
(0, 1),
|
||||
(1, 0),
|
||||
(1, 2),
|
||||
(2, 1),
|
||||
(0, 2),
|
||||
(2, 0),
|
||||
(0, 0),
|
||||
(2, 2),
|
||||
(1, 1),
|
||||
],
|
||||
[
|
||||
(0, 1),
|
||||
(1, 0),
|
||||
(1, 2),
|
||||
(2, 2),
|
||||
(0, 2),
|
||||
(2, 1),
|
||||
(1, 1),
|
||||
(2, 0),
|
||||
(0, 0),
|
||||
],
|
||||
[
|
||||
(0, 1),
|
||||
(1, 0),
|
||||
(2, 1),
|
||||
(2, 0),
|
||||
(2, 2),
|
||||
(0, 2),
|
||||
(1, 2),
|
||||
(0, 0),
|
||||
(1, 1),
|
||||
],
|
||||
];
|
||||
let layout = &LAYOUTS[(shuffle_seed as usize) % LAYOUTS.len()];
|
||||
layout
|
||||
.into_iter()
|
||||
.map(|(row, col)| PuzzleCellPosition {
|
||||
row: *row,
|
||||
col: *col,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn build_affine_neighbor_free_positions(
|
||||
grid_size: u32,
|
||||
row_from_row: u32,
|
||||
row_from_col: u32,
|
||||
col_from_row: u32,
|
||||
col_from_col: u32,
|
||||
shuffle_seed: u64,
|
||||
) -> Vec<PuzzleCellPosition> {
|
||||
let row_offset = (shuffle_seed % u64::from(grid_size)) as u32;
|
||||
let col_offset = ((shuffle_seed / u64::from(grid_size)) % u64::from(grid_size)) as u32;
|
||||
(0..(grid_size * grid_size))
|
||||
.map(|index| {
|
||||
let row = index / grid_size;
|
||||
let col = index % grid_size;
|
||||
PuzzleCellPosition {
|
||||
row: (row_from_row * row + row_from_col * col + row_offset) % grid_size,
|
||||
col: (col_from_row * row + col_from_col * col + col_offset) % grid_size,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn build_original_neighbor_free_pieces(
|
||||
grid_size: u32,
|
||||
shuffle_seed: u64,
|
||||
@@ -3212,6 +3498,8 @@ mod tests {
|
||||
recent_play_count_7d: 0,
|
||||
remix_count: 0,
|
||||
like_count: 0,
|
||||
point_incentive_total_half_points: 0,
|
||||
point_incentive_claimed_points: 0,
|
||||
publish_ready: true,
|
||||
anchor_pack: empty_anchor_pack(),
|
||||
}
|
||||
@@ -3220,8 +3508,33 @@ mod tests {
|
||||
#[test]
|
||||
fn resolve_grid_size_matches_prd() {
|
||||
assert_eq!(resolve_puzzle_grid_size(0), 3);
|
||||
assert_eq!(resolve_puzzle_grid_size(2), 3);
|
||||
assert_eq!(resolve_puzzle_grid_size(3), 4);
|
||||
assert_eq!(resolve_puzzle_grid_size(1), 4);
|
||||
assert_eq!(resolve_puzzle_grid_size(2), 5);
|
||||
assert_eq!(resolve_puzzle_grid_size(3), 5);
|
||||
assert_eq!(resolve_puzzle_grid_size(4), 5);
|
||||
assert_eq!(resolve_puzzle_grid_size(5), 6);
|
||||
assert_eq!(resolve_puzzle_grid_size(6), 5);
|
||||
assert_eq!(resolve_puzzle_grid_size(7), 7);
|
||||
assert_eq!(resolve_puzzle_grid_size(8), 5);
|
||||
assert_eq!(resolve_puzzle_grid_size(9), 7);
|
||||
assert_eq!(resolve_puzzle_grid_size(10), 5);
|
||||
assert_eq!(resolve_puzzle_grid_size(15), 7);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_level_time_limit_matches_prd() {
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(1), 300_000);
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(2), 300_000);
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(3), 300_000);
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(4), 210_000);
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(5), 210_000);
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(6), 240_000);
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(7), 210_000);
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(8), 270_000);
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(9), 240_000);
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(10), 270_000);
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(11), 210_000);
|
||||
assert_eq!(resolve_puzzle_level_time_limit_ms_by_index(16), 270_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -3360,6 +3673,66 @@ mod tests {
|
||||
assert_eq!(selected.profile_id, "b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn restart_cleared_count_uses_selected_level_index() {
|
||||
let mut profile = build_published_profile("entry", "owner-a", vec!["机关"]);
|
||||
profile.levels = vec![
|
||||
PuzzleDraftLevel {
|
||||
level_id: "puzzle-level-1".to_string(),
|
||||
level_name: "第一关".to_string(),
|
||||
picture_description: "第一关画面".to_string(),
|
||||
candidates: Vec::new(),
|
||||
selected_candidate_id: None,
|
||||
cover_image_src: Some("/level-1.png".to_string()),
|
||||
cover_asset_id: None,
|
||||
generation_status: "ready".to_string(),
|
||||
},
|
||||
PuzzleDraftLevel {
|
||||
level_id: "puzzle-level-2".to_string(),
|
||||
level_name: "第二关".to_string(),
|
||||
picture_description: "第二关画面".to_string(),
|
||||
candidates: Vec::new(),
|
||||
selected_candidate_id: None,
|
||||
cover_image_src: Some("/level-2.png".to_string()),
|
||||
cover_asset_id: None,
|
||||
generation_status: "ready".to_string(),
|
||||
},
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
resolve_restart_cleared_level_count(&profile, "puzzle-level-2"),
|
||||
1
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_restart_cleared_level_count(&profile, "missing-level"),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advance_to_new_work_first_level_restarts_level_progress() {
|
||||
let first_profile = build_published_profile("entry", "owner-a", vec!["奇幻", "遗迹"]);
|
||||
let next_profile = build_published_profile("next", "owner-b", vec!["奇幻", "魔法"]);
|
||||
let mut run = start_run("run-cross-work".to_string(), &first_profile, 2).expect("run");
|
||||
run.cleared_level_count = run.current_level_index;
|
||||
let current_level = run.current_level.as_mut().expect("level");
|
||||
current_level.status = PuzzleRuntimeLevelStatus::Cleared;
|
||||
current_level.cleared_at_ms = Some(2_000);
|
||||
current_level.elapsed_ms = Some(1_000);
|
||||
|
||||
let next_run =
|
||||
advance_to_new_work_first_level_at(&run, &next_profile, 3_000).expect("next run");
|
||||
|
||||
assert_eq!(next_run.entry_profile_id, "next");
|
||||
assert_eq!(next_run.cleared_level_count, 0);
|
||||
assert_eq!(next_run.current_level_index, 1);
|
||||
let next_level = next_run.current_level.expect("next level");
|
||||
assert_eq!(next_level.profile_id, "next");
|
||||
assert_eq!(next_level.level_index, 1);
|
||||
assert_eq!(next_level.grid_size, 3);
|
||||
assert_eq!(next_level.time_limit_ms, 300_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn swap_pieces_marks_cleared_when_back_to_origin() {
|
||||
let profile = build_published_profile("entry", "owner-a", vec!["蒸汽城市", "雨夜", "猫咪"]);
|
||||
@@ -3408,7 +3781,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn initial_board_has_no_original_neighbor_pairs() {
|
||||
for grid_size in [3, 4] {
|
||||
for grid_size in PUZZLE_SUPPORTED_GRID_SIZES {
|
||||
for shuffle_seed in 0..128 {
|
||||
let board = build_initial_board_with_seed(grid_size, shuffle_seed).expect("board");
|
||||
|
||||
@@ -3672,6 +4045,28 @@ mod tests {
|
||||
assert_eq!(timed_level.elapsed_ms, Some(timed_level.time_limit_ms));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_level_can_extend_one_minute() {
|
||||
let profile = build_published_profile("entry", "owner-a", vec!["蒸汽城市", "雨夜", "猫咪"]);
|
||||
let now_ms = current_unix_ms();
|
||||
let mut run =
|
||||
start_run_with_shuffle_seed("run-extend".to_string(), &profile, 0, 14).expect("run");
|
||||
let level = run.current_level.as_mut().expect("level");
|
||||
level.started_at_ms = now_ms.saturating_sub(level.time_limit_ms + 1_000);
|
||||
|
||||
let failed_run = resolve_puzzle_run_timer_at(run, now_ms);
|
||||
let extended_run = extend_failed_puzzle_time_at(&failed_run, now_ms + 5_000)
|
||||
.expect("extend should succeed");
|
||||
let extended_level = extended_run.current_level.as_ref().expect("level");
|
||||
|
||||
assert_eq!(extended_level.status, PuzzleRuntimeLevelStatus::Playing);
|
||||
assert_eq!(extended_level.remaining_ms, PUZZLE_EXTEND_TIME_DURATION_MS);
|
||||
assert_eq!(extended_level.elapsed_ms, None);
|
||||
assert_eq!(extended_level.cleared_at_ms, None);
|
||||
assert_eq!(extended_level.pause_started_at_ms, None);
|
||||
assert_eq!(extended_level.freeze_until_ms, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pause_and_freeze_are_excluded_from_effective_timer() {
|
||||
let profile = build_published_profile("entry", "owner-a", vec!["蒸汽城市", "雨夜", "猫咪"]);
|
||||
|
||||
@@ -262,6 +262,7 @@ pub enum RuntimeProfileWalletLedgerSourceType {
|
||||
AssetOperationConsume,
|
||||
AssetOperationRefund,
|
||||
RedeemCodeReward,
|
||||
PuzzleAuthorIncentiveClaim,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
@@ -1709,6 +1710,7 @@ impl RuntimeProfileWalletLedgerSourceType {
|
||||
Self::AssetOperationConsume => "asset_operation_consume",
|
||||
Self::AssetOperationRefund => "asset_operation_refund",
|
||||
Self::RedeemCodeReward => "redeem_code_reward",
|
||||
Self::PuzzleAuthorIncentiveClaim => "puzzle_author_incentive_claim",
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2233,6 +2235,10 @@ mod tests {
|
||||
RuntimeProfileWalletLedgerSourceType::AssetOperationRefund.as_str(),
|
||||
"asset_operation_refund"
|
||||
);
|
||||
assert_eq!(
|
||||
RuntimeProfileWalletLedgerSourceType::PuzzleAuthorIncentiveClaim.as_str(),
|
||||
"puzzle_author_incentive_claim"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -47,11 +47,61 @@ pub struct PuzzleWorkSummaryResponse {
|
||||
pub like_count: u32,
|
||||
#[serde(default)]
|
||||
pub recent_play_count_7d: u32,
|
||||
#[serde(default)]
|
||||
pub point_incentive_total_half_points: u64,
|
||||
#[serde(default)]
|
||||
pub point_incentive_claimed_points: u64,
|
||||
#[serde(default)]
|
||||
pub point_incentive_total_points: f64,
|
||||
#[serde(default)]
|
||||
pub point_incentive_claimable_points: u64,
|
||||
pub publish_ready: bool,
|
||||
#[serde(default)]
|
||||
pub levels: Vec<PuzzleDraftLevelResponse>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn puzzle_work_summary_response_uses_point_incentive_fields() {
|
||||
let payload = serde_json::to_value(PuzzleWorkSummaryResponse {
|
||||
work_id: "work-1".to_string(),
|
||||
profile_id: "profile-1".to_string(),
|
||||
owner_user_id: "user-1".to_string(),
|
||||
source_session_id: None,
|
||||
author_display_name: "作者".to_string(),
|
||||
work_title: "作品".to_string(),
|
||||
work_description: "描述".to_string(),
|
||||
level_name: "第一关".to_string(),
|
||||
summary: "画面".to_string(),
|
||||
theme_tags: vec!["拼图".to_string(), "夜色".to_string(), "灯光".to_string()],
|
||||
cover_image_src: None,
|
||||
cover_asset_id: None,
|
||||
publication_status: "published".to_string(),
|
||||
updated_at: "2026-05-01T00:00:00Z".to_string(),
|
||||
published_at: Some("2026-05-01T00:00:00Z".to_string()),
|
||||
play_count: 1,
|
||||
remix_count: 0,
|
||||
like_count: 0,
|
||||
recent_play_count_7d: 1,
|
||||
point_incentive_total_half_points: 3,
|
||||
point_incentive_claimed_points: 1,
|
||||
point_incentive_total_points: 1.5,
|
||||
point_incentive_claimable_points: 0,
|
||||
publish_ready: true,
|
||||
levels: Vec::new(),
|
||||
})
|
||||
.expect("payload should serialize");
|
||||
|
||||
assert_eq!(payload["pointIncentiveTotalHalfPoints"], 3);
|
||||
assert_eq!(payload["pointIncentiveClaimedPoints"], 1);
|
||||
assert_eq!(payload["pointIncentiveTotalPoints"], 1.5);
|
||||
assert_eq!(payload["pointIncentiveClaimablePoints"], 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PuzzleWorkProfileResponse {
|
||||
|
||||
@@ -11,6 +11,8 @@ pub const PROFILE_WALLET_LEDGER_SOURCE_TYPE_ASSET_OPERATION_CONSUME: &str =
|
||||
"asset_operation_consume";
|
||||
pub const PROFILE_WALLET_LEDGER_SOURCE_TYPE_ASSET_OPERATION_REFUND: &str = "asset_operation_refund";
|
||||
pub const PROFILE_WALLET_LEDGER_SOURCE_TYPE_REDEEM_CODE_REWARD: &str = "redeem_code_reward";
|
||||
pub const PROFILE_WALLET_LEDGER_SOURCE_TYPE_PUZZLE_AUTHOR_INCENTIVE_CLAIM: &str =
|
||||
"puzzle_author_incentive_claim";
|
||||
pub const BROWSE_HISTORY_THEME_MODE_MARTIAL: &str = "martial";
|
||||
pub const BROWSE_HISTORY_THEME_MODE_ARCANE: &str = "arcane";
|
||||
pub const BROWSE_HISTORY_THEME_MODE_MACHINA: &str = "machina";
|
||||
@@ -910,6 +912,14 @@ mod tests {
|
||||
.to_string(),
|
||||
created_at: "2026-04-22T10:05:00Z".to_string(),
|
||||
},
|
||||
ProfileWalletLedgerEntryResponse {
|
||||
id: "ledger-7".to_string(),
|
||||
amount_delta: 2,
|
||||
balance_after: 202,
|
||||
source_type: PROFILE_WALLET_LEDGER_SOURCE_TYPE_PUZZLE_AUTHOR_INCENTIVE_CLAIM
|
||||
.to_string(),
|
||||
created_at: "2026-04-22T10:06:00Z".to_string(),
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect("payload should serialize");
|
||||
@@ -940,6 +950,10 @@ mod tests {
|
||||
payload["entries"][5]["sourceType"],
|
||||
json!(PROFILE_WALLET_LEDGER_SOURCE_TYPE_ASSET_OPERATION_REFUND)
|
||||
);
|
||||
assert_eq!(
|
||||
payload["entries"][6]["sourceType"],
|
||||
json!(PROFILE_WALLET_LEDGER_SOURCE_TYPE_PUZZLE_AUTHOR_INCENTIVE_CLAIM)
|
||||
);
|
||||
assert_eq!(
|
||||
payload["entries"][0]["createdAt"],
|
||||
json!("2026-04-22T10:00:00Z")
|
||||
|
||||
@@ -39,9 +39,9 @@ pub use mapper::{
|
||||
PuzzleResultPreviewRecord, PuzzleRunDragRecordInput, PuzzleRunNextLevelRecordInput,
|
||||
PuzzleRunPauseRecordInput, PuzzleRunPropRecordInput, PuzzleRunRecord,
|
||||
PuzzleRunStartRecordInput, PuzzleRunSwapRecordInput, PuzzleRuntimeLevelRecord,
|
||||
PuzzleSelectCoverImageRecordInput, PuzzleWorkLikeReportRecordInput, PuzzleWorkProfileRecord,
|
||||
PuzzleWorkRemixRecordInput, PuzzleWorkUpsertRecordInput, ResolveCombatActionRecord,
|
||||
ResolveNpcBattleInteractionInput,
|
||||
PuzzleSelectCoverImageRecordInput, PuzzleWorkLikeReportRecordInput,
|
||||
PuzzleWorkPointIncentiveClaimRecordInput, PuzzleWorkProfileRecord, PuzzleWorkRemixRecordInput,
|
||||
PuzzleWorkUpsertRecordInput, ResolveCombatActionRecord, ResolveNpcBattleInteractionInput,
|
||||
};
|
||||
|
||||
pub mod ai;
|
||||
|
||||
@@ -2436,6 +2436,8 @@ pub(crate) fn map_puzzle_work_profile(
|
||||
remix_count: snapshot.remix_count,
|
||||
like_count: snapshot.like_count,
|
||||
recent_play_count_7d: snapshot.recent_play_count_7d,
|
||||
point_incentive_total_half_points: snapshot.point_incentive_total_half_points,
|
||||
point_incentive_claimed_points: snapshot.point_incentive_claimed_points,
|
||||
publish_ready: snapshot.publish_ready,
|
||||
anchor_pack: map_puzzle_anchor_pack(snapshot.anchor_pack),
|
||||
levels: snapshot
|
||||
@@ -2491,6 +2493,13 @@ 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
|
||||
} else {
|
||||
snapshot.started_at_ms
|
||||
};
|
||||
|
||||
PuzzleRuntimeLevelRecord {
|
||||
run_id: snapshot.run_id,
|
||||
level_index: snapshot.level_index,
|
||||
@@ -2503,7 +2512,7 @@ pub(crate) fn map_puzzle_runtime_level_snapshot(
|
||||
cover_image_src: snapshot.cover_image_src,
|
||||
board: map_puzzle_board_snapshot(snapshot.board),
|
||||
status: snapshot.status.as_str().to_string(),
|
||||
started_at_ms: snapshot.started_at_ms,
|
||||
started_at_ms,
|
||||
cleared_at_ms: snapshot.cleared_at_ms,
|
||||
elapsed_ms: snapshot.elapsed_ms,
|
||||
time_limit_ms: snapshot.time_limit_ms,
|
||||
@@ -3485,6 +3494,9 @@ pub(crate) fn map_runtime_profile_wallet_ledger_source_type_back(
|
||||
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::RedeemCodeReward => {
|
||||
module_runtime::RuntimeProfileWalletLedgerSourceType::RedeemCodeReward
|
||||
}
|
||||
crate::module_bindings::RuntimeProfileWalletLedgerSourceType::PuzzleAuthorIncentiveClaim => {
|
||||
module_runtime::RuntimeProfileWalletLedgerSourceType::PuzzleAuthorIncentiveClaim
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4535,6 +4547,7 @@ pub struct PuzzleRunPropRecordInput {
|
||||
pub owner_user_id: String,
|
||||
pub prop_kind: String,
|
||||
pub used_at_micros: i64,
|
||||
pub spent_points: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@@ -4716,11 +4729,20 @@ pub struct PuzzleWorkProfileRecord {
|
||||
pub remix_count: u32,
|
||||
pub like_count: u32,
|
||||
pub recent_play_count_7d: u32,
|
||||
pub point_incentive_total_half_points: u64,
|
||||
pub point_incentive_claimed_points: u64,
|
||||
pub publish_ready: bool,
|
||||
pub anchor_pack: PuzzleAnchorPackRecord,
|
||||
pub levels: Vec<PuzzleDraftLevelRecord>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct PuzzleWorkPointIncentiveClaimRecordInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub claimed_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct PuzzleCellPositionRecord {
|
||||
pub row: u32,
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::puzzle_work_point_incentive_claim_input_type::PuzzleWorkPointIncentiveClaimInput;
|
||||
use super::puzzle_work_procedure_result_type::PuzzleWorkProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct ClaimPuzzleWorkPointIncentiveArgs {
|
||||
pub input: PuzzleWorkPointIncentiveClaimInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for ClaimPuzzleWorkPointIncentiveArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `claim_puzzle_work_point_incentive`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait claim_puzzle_work_point_incentive {
|
||||
fn claim_puzzle_work_point_incentive(&self, input: PuzzleWorkPointIncentiveClaimInput,
|
||||
) {
|
||||
self.claim_puzzle_work_point_incentive_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn claim_puzzle_work_point_incentive_then(
|
||||
&self,
|
||||
input: PuzzleWorkPointIncentiveClaimInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<PuzzleWorkProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl claim_puzzle_work_point_incentive for super::RemoteProcedures {
|
||||
fn claim_puzzle_work_point_incentive_then(
|
||||
&self,
|
||||
input: PuzzleWorkPointIncentiveClaimInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<PuzzleWorkProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, PuzzleWorkProcedureResult>(
|
||||
"claim_puzzle_work_point_incentive",
|
||||
ClaimPuzzleWorkPointIncentiveArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_run_click_input_type::Match3DRunClickInput;
|
||||
use super::match_3_d_click_item_procedure_result_type::Match3DClickItemProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct ClickMatch3DItemArgs {
|
||||
pub input: Match3DRunClickInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for ClickMatch3DItemArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `click_match_3_d_item`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait click_match_3_d_item {
|
||||
fn click_match_3_d_item(&self, input: Match3DRunClickInput,
|
||||
) {
|
||||
self.click_match_3_d_item_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn click_match_3_d_item_then(
|
||||
&self,
|
||||
input: Match3DRunClickInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DClickItemProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl click_match_3_d_item for super::RemoteProcedures {
|
||||
fn click_match_3_d_item_then(
|
||||
&self,
|
||||
input: Match3DRunClickInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DClickItemProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DClickItemProcedureResult>(
|
||||
"click_match_3_d_item",
|
||||
ClickMatch3DItemArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_draft_compile_input_type::Match3DDraftCompileInput;
|
||||
use super::match_3_d_agent_session_procedure_result_type::Match3DAgentSessionProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct CompileMatch3DDraftArgs {
|
||||
pub input: Match3DDraftCompileInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for CompileMatch3DDraftArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `compile_match_3_d_draft`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait compile_match_3_d_draft {
|
||||
fn compile_match_3_d_draft(&self, input: Match3DDraftCompileInput,
|
||||
) {
|
||||
self.compile_match_3_d_draft_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn compile_match_3_d_draft_then(
|
||||
&self,
|
||||
input: Match3DDraftCompileInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl compile_match_3_d_draft for super::RemoteProcedures {
|
||||
fn compile_match_3_d_draft_then(
|
||||
&self,
|
||||
input: Match3DDraftCompileInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DAgentSessionProcedureResult>(
|
||||
"compile_match_3_d_draft",
|
||||
CompileMatch3DDraftArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_agent_session_procedure_result_type::Match3DAgentSessionProcedureResult;
|
||||
use super::match_3_d_agent_session_create_input_type::Match3DAgentSessionCreateInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct CreateMatch3DAgentSessionArgs {
|
||||
pub input: Match3DAgentSessionCreateInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for CreateMatch3DAgentSessionArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `create_match_3_d_agent_session`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait create_match_3_d_agent_session {
|
||||
fn create_match_3_d_agent_session(&self, input: Match3DAgentSessionCreateInput,
|
||||
) {
|
||||
self.create_match_3_d_agent_session_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn create_match_3_d_agent_session_then(
|
||||
&self,
|
||||
input: Match3DAgentSessionCreateInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl create_match_3_d_agent_session for super::RemoteProcedures {
|
||||
fn create_match_3_d_agent_session_then(
|
||||
&self,
|
||||
input: Match3DAgentSessionCreateInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DAgentSessionProcedureResult>(
|
||||
"create_match_3_d_agent_session",
|
||||
CreateMatch3DAgentSessionArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_work_delete_input_type::Match3DWorkDeleteInput;
|
||||
use super::match_3_d_works_procedure_result_type::Match3DWorksProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct DeleteMatch3DWorkArgs {
|
||||
pub input: Match3DWorkDeleteInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for DeleteMatch3DWorkArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `delete_match_3_d_work`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait delete_match_3_d_work {
|
||||
fn delete_match_3_d_work(&self, input: Match3DWorkDeleteInput,
|
||||
) {
|
||||
self.delete_match_3_d_work_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn delete_match_3_d_work_then(
|
||||
&self,
|
||||
input: Match3DWorkDeleteInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DWorksProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl delete_match_3_d_work for super::RemoteProcedures {
|
||||
fn delete_match_3_d_work_then(
|
||||
&self,
|
||||
input: Match3DWorkDeleteInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DWorksProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DWorksProcedureResult>(
|
||||
"delete_match_3_d_work",
|
||||
DeleteMatch3DWorkArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_agent_session_procedure_result_type::Match3DAgentSessionProcedureResult;
|
||||
use super::match_3_d_agent_message_finalize_input_type::Match3DAgentMessageFinalizeInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct FinalizeMatch3DAgentMessageTurnArgs {
|
||||
pub input: Match3DAgentMessageFinalizeInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for FinalizeMatch3DAgentMessageTurnArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `finalize_match_3_d_agent_message_turn`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait finalize_match_3_d_agent_message_turn {
|
||||
fn finalize_match_3_d_agent_message_turn(&self, input: Match3DAgentMessageFinalizeInput,
|
||||
) {
|
||||
self.finalize_match_3_d_agent_message_turn_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn finalize_match_3_d_agent_message_turn_then(
|
||||
&self,
|
||||
input: Match3DAgentMessageFinalizeInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl finalize_match_3_d_agent_message_turn for super::RemoteProcedures {
|
||||
fn finalize_match_3_d_agent_message_turn_then(
|
||||
&self,
|
||||
input: Match3DAgentMessageFinalizeInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DAgentSessionProcedureResult>(
|
||||
"finalize_match_3_d_agent_message_turn",
|
||||
FinalizeMatch3DAgentMessageTurnArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_run_time_up_input_type::Match3DRunTimeUpInput;
|
||||
use super::match_3_d_run_procedure_result_type::Match3DRunProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct FinishMatch3DTimeUpArgs {
|
||||
pub input: Match3DRunTimeUpInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for FinishMatch3DTimeUpArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `finish_match_3_d_time_up`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait finish_match_3_d_time_up {
|
||||
fn finish_match_3_d_time_up(&self, input: Match3DRunTimeUpInput,
|
||||
) {
|
||||
self.finish_match_3_d_time_up_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn finish_match_3_d_time_up_then(
|
||||
&self,
|
||||
input: Match3DRunTimeUpInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DRunProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl finish_match_3_d_time_up for super::RemoteProcedures {
|
||||
fn finish_match_3_d_time_up_then(
|
||||
&self,
|
||||
input: Match3DRunTimeUpInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DRunProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DRunProcedureResult>(
|
||||
"finish_match_3_d_time_up",
|
||||
FinishMatch3DTimeUpArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_agent_session_procedure_result_type::Match3DAgentSessionProcedureResult;
|
||||
use super::match_3_d_agent_session_get_input_type::Match3DAgentSessionGetInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct GetMatch3DAgentSessionArgs {
|
||||
pub input: Match3DAgentSessionGetInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for GetMatch3DAgentSessionArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `get_match_3_d_agent_session`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait get_match_3_d_agent_session {
|
||||
fn get_match_3_d_agent_session(&self, input: Match3DAgentSessionGetInput,
|
||||
) {
|
||||
self.get_match_3_d_agent_session_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn get_match_3_d_agent_session_then(
|
||||
&self,
|
||||
input: Match3DAgentSessionGetInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl get_match_3_d_agent_session for super::RemoteProcedures {
|
||||
fn get_match_3_d_agent_session_then(
|
||||
&self,
|
||||
input: Match3DAgentSessionGetInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DAgentSessionProcedureResult>(
|
||||
"get_match_3_d_agent_session",
|
||||
GetMatch3DAgentSessionArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_run_procedure_result_type::Match3DRunProcedureResult;
|
||||
use super::match_3_d_run_get_input_type::Match3DRunGetInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct GetMatch3DRunArgs {
|
||||
pub input: Match3DRunGetInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for GetMatch3DRunArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `get_match_3_d_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait get_match_3_d_run {
|
||||
fn get_match_3_d_run(&self, input: Match3DRunGetInput,
|
||||
) {
|
||||
self.get_match_3_d_run_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn get_match_3_d_run_then(
|
||||
&self,
|
||||
input: Match3DRunGetInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DRunProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl get_match_3_d_run for super::RemoteProcedures {
|
||||
fn get_match_3_d_run_then(
|
||||
&self,
|
||||
input: Match3DRunGetInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DRunProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DRunProcedureResult>(
|
||||
"get_match_3_d_run",
|
||||
GetMatch3DRunArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_work_get_input_type::Match3DWorkGetInput;
|
||||
use super::match_3_d_work_procedure_result_type::Match3DWorkProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct GetMatch3DWorkDetailArgs {
|
||||
pub input: Match3DWorkGetInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for GetMatch3DWorkDetailArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `get_match_3_d_work_detail`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait get_match_3_d_work_detail {
|
||||
fn get_match_3_d_work_detail(&self, input: Match3DWorkGetInput,
|
||||
) {
|
||||
self.get_match_3_d_work_detail_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn get_match_3_d_work_detail_then(
|
||||
&self,
|
||||
input: Match3DWorkGetInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DWorkProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl get_match_3_d_work_detail for super::RemoteProcedures {
|
||||
fn get_match_3_d_work_detail_then(
|
||||
&self,
|
||||
input: Match3DWorkGetInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DWorkProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DWorkProcedureResult>(
|
||||
"get_match_3_d_work_detail",
|
||||
GetMatch3DWorkDetailArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ use spacetimedb_sdk::__codegen::{
|
||||
__ws,
|
||||
};
|
||||
|
||||
use super::puzzle_work_get_input_type::PuzzleWorkGetInput;
|
||||
use super::puzzle_work_procedure_result_type::PuzzleWorkProcedureResult;
|
||||
use super::puzzle_work_get_input_type::PuzzleWorkGetInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
|
||||
@@ -9,8 +9,8 @@ use spacetimedb_sdk::__codegen::{
|
||||
__ws,
|
||||
};
|
||||
|
||||
use super::puzzle_work_get_input_type::PuzzleWorkGetInput;
|
||||
use super::puzzle_work_procedure_result_type::PuzzleWorkProcedureResult;
|
||||
use super::puzzle_work_get_input_type::PuzzleWorkGetInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_works_procedure_result_type::Match3DWorksProcedureResult;
|
||||
use super::match_3_d_works_list_input_type::Match3DWorksListInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct ListMatch3DWorksArgs {
|
||||
pub input: Match3DWorksListInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for ListMatch3DWorksArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `list_match_3_d_works`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait list_match_3_d_works {
|
||||
fn list_match_3_d_works(&self, input: Match3DWorksListInput,
|
||||
) {
|
||||
self.list_match_3_d_works_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn list_match_3_d_works_then(
|
||||
&self,
|
||||
input: Match3DWorksListInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DWorksProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl list_match_3_d_works for super::RemoteProcedures {
|
||||
fn list_match_3_d_works_then(
|
||||
&self,
|
||||
input: Match3DWorksListInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DWorksProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DWorksProcedureResult>(
|
||||
"list_match_3_d_works",
|
||||
ListMatch3DWorksArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// 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 Match3DAgentMessageFinalizeInput {
|
||||
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>,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DAgentMessageFinalizeInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
// 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 Match3DAgentMessageRow {
|
||||
pub message_id: String,
|
||||
pub session_id: String,
|
||||
pub role: String,
|
||||
pub kind: String,
|
||||
pub text: String,
|
||||
pub created_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DAgentMessageRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
|
||||
/// Column accessor struct for the table `Match3DAgentMessageRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct Match3DAgentMessageRowCols {
|
||||
pub message_id: __sdk::__query_builder::Col<Match3DAgentMessageRow, String>,
|
||||
pub session_id: __sdk::__query_builder::Col<Match3DAgentMessageRow, String>,
|
||||
pub role: __sdk::__query_builder::Col<Match3DAgentMessageRow, String>,
|
||||
pub kind: __sdk::__query_builder::Col<Match3DAgentMessageRow, String>,
|
||||
pub text: __sdk::__query_builder::Col<Match3DAgentMessageRow, String>,
|
||||
pub created_at: __sdk::__query_builder::Col<Match3DAgentMessageRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for Match3DAgentMessageRow {
|
||||
type Cols = Match3DAgentMessageRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
Match3DAgentMessageRowCols {
|
||||
message_id: __sdk::__query_builder::Col::new(table_name, "message_id"),
|
||||
session_id: __sdk::__query_builder::Col::new(table_name, "session_id"),
|
||||
role: __sdk::__query_builder::Col::new(table_name, "role"),
|
||||
kind: __sdk::__query_builder::Col::new(table_name, "kind"),
|
||||
text: __sdk::__query_builder::Col::new(table_name, "text"),
|
||||
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indexed column accessor struct for the table `Match3DAgentMessageRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct Match3DAgentMessageRowIxCols {
|
||||
pub message_id: __sdk::__query_builder::IxCol<Match3DAgentMessageRow, String>,
|
||||
pub session_id: __sdk::__query_builder::IxCol<Match3DAgentMessageRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for Match3DAgentMessageRow {
|
||||
type IxCols = Match3DAgentMessageRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
Match3DAgentMessageRowIxCols {
|
||||
message_id: __sdk::__query_builder::IxCol::new(table_name, "message_id"),
|
||||
session_id: __sdk::__query_builder::IxCol::new(table_name, "session_id"),
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for Match3DAgentMessageRow {}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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 Match3DAgentMessageSubmitInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub user_message_id: String,
|
||||
pub user_message_text: String,
|
||||
pub submitted_at_micros: i64,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DAgentMessageSubmitInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// 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 Match3DAgentSessionCreateInput {
|
||||
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,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DAgentSessionCreateInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// 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 Match3DAgentSessionGetInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DAgentSessionGetInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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 Match3DAgentSessionProcedureResult {
|
||||
pub ok: bool,
|
||||
pub session_json: Option::<String>,
|
||||
pub error_message: Option::<String>,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DAgentSessionProcedureResult {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
// 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 Match3DAgentSessionRow {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub seed_text: String,
|
||||
pub current_turn: u32,
|
||||
pub progress_percent: u32,
|
||||
pub stage: String,
|
||||
pub config_json: String,
|
||||
pub draft_json: String,
|
||||
pub last_assistant_reply: String,
|
||||
pub published_profile_id: String,
|
||||
pub created_at: __sdk::Timestamp,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DAgentSessionRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
|
||||
/// Column accessor struct for the table `Match3DAgentSessionRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct Match3DAgentSessionRowCols {
|
||||
pub session_id: __sdk::__query_builder::Col<Match3DAgentSessionRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<Match3DAgentSessionRow, String>,
|
||||
pub seed_text: __sdk::__query_builder::Col<Match3DAgentSessionRow, String>,
|
||||
pub current_turn: __sdk::__query_builder::Col<Match3DAgentSessionRow, u32>,
|
||||
pub progress_percent: __sdk::__query_builder::Col<Match3DAgentSessionRow, u32>,
|
||||
pub stage: __sdk::__query_builder::Col<Match3DAgentSessionRow, String>,
|
||||
pub config_json: __sdk::__query_builder::Col<Match3DAgentSessionRow, String>,
|
||||
pub draft_json: __sdk::__query_builder::Col<Match3DAgentSessionRow, String>,
|
||||
pub last_assistant_reply: __sdk::__query_builder::Col<Match3DAgentSessionRow, String>,
|
||||
pub published_profile_id: __sdk::__query_builder::Col<Match3DAgentSessionRow, String>,
|
||||
pub created_at: __sdk::__query_builder::Col<Match3DAgentSessionRow, __sdk::Timestamp>,
|
||||
pub updated_at: __sdk::__query_builder::Col<Match3DAgentSessionRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for Match3DAgentSessionRow {
|
||||
type Cols = Match3DAgentSessionRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
Match3DAgentSessionRowCols {
|
||||
session_id: __sdk::__query_builder::Col::new(table_name, "session_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
seed_text: __sdk::__query_builder::Col::new(table_name, "seed_text"),
|
||||
current_turn: __sdk::__query_builder::Col::new(table_name, "current_turn"),
|
||||
progress_percent: __sdk::__query_builder::Col::new(table_name, "progress_percent"),
|
||||
stage: __sdk::__query_builder::Col::new(table_name, "stage"),
|
||||
config_json: __sdk::__query_builder::Col::new(table_name, "config_json"),
|
||||
draft_json: __sdk::__query_builder::Col::new(table_name, "draft_json"),
|
||||
last_assistant_reply: __sdk::__query_builder::Col::new(table_name, "last_assistant_reply"),
|
||||
published_profile_id: __sdk::__query_builder::Col::new(table_name, "published_profile_id"),
|
||||
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
|
||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indexed column accessor struct for the table `Match3DAgentSessionRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct Match3DAgentSessionRowIxCols {
|
||||
pub owner_user_id: __sdk::__query_builder::IxCol<Match3DAgentSessionRow, String>,
|
||||
pub session_id: __sdk::__query_builder::IxCol<Match3DAgentSessionRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for Match3DAgentSessionRow {
|
||||
type IxCols = Match3DAgentSessionRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
Match3DAgentSessionRowIxCols {
|
||||
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
|
||||
session_id: __sdk::__query_builder::IxCol::new(table_name, "session_id"),
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for Match3DAgentSessionRow {}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// 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 Match3DClickItemProcedureResult {
|
||||
pub ok: bool,
|
||||
pub status: String,
|
||||
pub run_json: Option::<String>,
|
||||
pub accepted_item_instance_id: Option::<String>,
|
||||
pub cleared_item_instance_ids: Vec::<String>,
|
||||
pub failure_reason: Option::<String>,
|
||||
pub error_message: Option::<String>,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DClickItemProcedureResult {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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 Match3DDraftCompileInput {
|
||||
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,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DDraftCompileInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// 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 Match3DRunClickInput {
|
||||
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,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DRunClickInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// 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 Match3DRunGetInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DRunGetInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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 Match3DRunProcedureResult {
|
||||
pub ok: bool,
|
||||
pub run_json: Option::<String>,
|
||||
pub error_message: Option::<String>,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DRunProcedureResult {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// 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 Match3DRunRestartInput {
|
||||
pub source_run_id: String,
|
||||
pub next_run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub restarted_at_ms: i64,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DRunRestartInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// 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 Match3DRunStartInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub started_at_ms: i64,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DRunStartInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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 Match3DRunStopInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub stopped_at_ms: i64,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DRunStopInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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 Match3DRunTimeUpInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub finished_at_ms: i64,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DRunTimeUpInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
// 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 Match3DRuntimeRunRow {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub status: String,
|
||||
pub snapshot_version: u32,
|
||||
pub started_at_ms: i64,
|
||||
pub duration_limit_ms: i64,
|
||||
pub finished_at_ms: i64,
|
||||
pub elapsed_ms: i64,
|
||||
pub clear_count: u32,
|
||||
pub total_item_count: u32,
|
||||
pub cleared_item_count: u32,
|
||||
pub failure_reason: String,
|
||||
pub snapshot_json: String,
|
||||
pub created_at: __sdk::Timestamp,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DRuntimeRunRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
|
||||
/// Column accessor struct for the table `Match3DRuntimeRunRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct Match3DRuntimeRunRowCols {
|
||||
pub run_id: __sdk::__query_builder::Col<Match3DRuntimeRunRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<Match3DRuntimeRunRow, String>,
|
||||
pub profile_id: __sdk::__query_builder::Col<Match3DRuntimeRunRow, String>,
|
||||
pub status: __sdk::__query_builder::Col<Match3DRuntimeRunRow, String>,
|
||||
pub snapshot_version: __sdk::__query_builder::Col<Match3DRuntimeRunRow, u32>,
|
||||
pub started_at_ms: __sdk::__query_builder::Col<Match3DRuntimeRunRow, i64>,
|
||||
pub duration_limit_ms: __sdk::__query_builder::Col<Match3DRuntimeRunRow, i64>,
|
||||
pub finished_at_ms: __sdk::__query_builder::Col<Match3DRuntimeRunRow, i64>,
|
||||
pub elapsed_ms: __sdk::__query_builder::Col<Match3DRuntimeRunRow, i64>,
|
||||
pub clear_count: __sdk::__query_builder::Col<Match3DRuntimeRunRow, u32>,
|
||||
pub total_item_count: __sdk::__query_builder::Col<Match3DRuntimeRunRow, u32>,
|
||||
pub cleared_item_count: __sdk::__query_builder::Col<Match3DRuntimeRunRow, u32>,
|
||||
pub failure_reason: __sdk::__query_builder::Col<Match3DRuntimeRunRow, String>,
|
||||
pub snapshot_json: __sdk::__query_builder::Col<Match3DRuntimeRunRow, String>,
|
||||
pub created_at: __sdk::__query_builder::Col<Match3DRuntimeRunRow, __sdk::Timestamp>,
|
||||
pub updated_at: __sdk::__query_builder::Col<Match3DRuntimeRunRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for Match3DRuntimeRunRow {
|
||||
type Cols = Match3DRuntimeRunRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
Match3DRuntimeRunRowCols {
|
||||
run_id: __sdk::__query_builder::Col::new(table_name, "run_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
profile_id: __sdk::__query_builder::Col::new(table_name, "profile_id"),
|
||||
status: __sdk::__query_builder::Col::new(table_name, "status"),
|
||||
snapshot_version: __sdk::__query_builder::Col::new(table_name, "snapshot_version"),
|
||||
started_at_ms: __sdk::__query_builder::Col::new(table_name, "started_at_ms"),
|
||||
duration_limit_ms: __sdk::__query_builder::Col::new(table_name, "duration_limit_ms"),
|
||||
finished_at_ms: __sdk::__query_builder::Col::new(table_name, "finished_at_ms"),
|
||||
elapsed_ms: __sdk::__query_builder::Col::new(table_name, "elapsed_ms"),
|
||||
clear_count: __sdk::__query_builder::Col::new(table_name, "clear_count"),
|
||||
total_item_count: __sdk::__query_builder::Col::new(table_name, "total_item_count"),
|
||||
cleared_item_count: __sdk::__query_builder::Col::new(table_name, "cleared_item_count"),
|
||||
failure_reason: __sdk::__query_builder::Col::new(table_name, "failure_reason"),
|
||||
snapshot_json: __sdk::__query_builder::Col::new(table_name, "snapshot_json"),
|
||||
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
|
||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indexed column accessor struct for the table `Match3DRuntimeRunRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct Match3DRuntimeRunRowIxCols {
|
||||
pub owner_user_id: __sdk::__query_builder::IxCol<Match3DRuntimeRunRow, String>,
|
||||
pub profile_id: __sdk::__query_builder::IxCol<Match3DRuntimeRunRow, String>,
|
||||
pub run_id: __sdk::__query_builder::IxCol<Match3DRuntimeRunRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for Match3DRuntimeRunRow {
|
||||
type IxCols = Match3DRuntimeRunRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
Match3DRuntimeRunRowIxCols {
|
||||
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
|
||||
profile_id: __sdk::__query_builder::IxCol::new(table_name, "profile_id"),
|
||||
run_id: __sdk::__query_builder::IxCol::new(table_name, "run_id"),
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for Match3DRuntimeRunRow {}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// 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 Match3DWorkDeleteInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DWorkDeleteInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// 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 Match3DWorkGetInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DWorkGetInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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 Match3DWorkProcedureResult {
|
||||
pub ok: bool,
|
||||
pub work_json: Option::<String>,
|
||||
pub error_message: Option::<String>,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DWorkProcedureResult {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
// 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 Match3DWorkProfileRow {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub source_session_id: String,
|
||||
pub author_display_name: 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 config_json: String,
|
||||
pub publication_status: String,
|
||||
pub play_count: u32,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
pub published_at: Option::<__sdk::Timestamp>,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DWorkProfileRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
|
||||
/// Column accessor struct for the table `Match3DWorkProfileRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct Match3DWorkProfileRowCols {
|
||||
pub profile_id: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub source_session_id: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub author_display_name: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub game_name: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub theme_text: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub summary_text: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub tags_json: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub cover_image_src: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub cover_asset_id: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub clear_count: __sdk::__query_builder::Col<Match3DWorkProfileRow, u32>,
|
||||
pub difficulty: __sdk::__query_builder::Col<Match3DWorkProfileRow, u32>,
|
||||
pub config_json: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub publication_status: __sdk::__query_builder::Col<Match3DWorkProfileRow, String>,
|
||||
pub play_count: __sdk::__query_builder::Col<Match3DWorkProfileRow, u32>,
|
||||
pub updated_at: __sdk::__query_builder::Col<Match3DWorkProfileRow, __sdk::Timestamp>,
|
||||
pub published_at: __sdk::__query_builder::Col<Match3DWorkProfileRow, Option::<__sdk::Timestamp>>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for Match3DWorkProfileRow {
|
||||
type Cols = Match3DWorkProfileRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
Match3DWorkProfileRowCols {
|
||||
profile_id: __sdk::__query_builder::Col::new(table_name, "profile_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
source_session_id: __sdk::__query_builder::Col::new(table_name, "source_session_id"),
|
||||
author_display_name: __sdk::__query_builder::Col::new(table_name, "author_display_name"),
|
||||
game_name: __sdk::__query_builder::Col::new(table_name, "game_name"),
|
||||
theme_text: __sdk::__query_builder::Col::new(table_name, "theme_text"),
|
||||
summary_text: __sdk::__query_builder::Col::new(table_name, "summary_text"),
|
||||
tags_json: __sdk::__query_builder::Col::new(table_name, "tags_json"),
|
||||
cover_image_src: __sdk::__query_builder::Col::new(table_name, "cover_image_src"),
|
||||
cover_asset_id: __sdk::__query_builder::Col::new(table_name, "cover_asset_id"),
|
||||
clear_count: __sdk::__query_builder::Col::new(table_name, "clear_count"),
|
||||
difficulty: __sdk::__query_builder::Col::new(table_name, "difficulty"),
|
||||
config_json: __sdk::__query_builder::Col::new(table_name, "config_json"),
|
||||
publication_status: __sdk::__query_builder::Col::new(table_name, "publication_status"),
|
||||
play_count: __sdk::__query_builder::Col::new(table_name, "play_count"),
|
||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indexed column accessor struct for the table `Match3DWorkProfileRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct Match3DWorkProfileRowIxCols {
|
||||
pub owner_user_id: __sdk::__query_builder::IxCol<Match3DWorkProfileRow, String>,
|
||||
pub profile_id: __sdk::__query_builder::IxCol<Match3DWorkProfileRow, String>,
|
||||
pub publication_status: __sdk::__query_builder::IxCol<Match3DWorkProfileRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for Match3DWorkProfileRow {
|
||||
type IxCols = Match3DWorkProfileRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
Match3DWorkProfileRowIxCols {
|
||||
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
|
||||
profile_id: __sdk::__query_builder::IxCol::new(table_name, "profile_id"),
|
||||
publication_status: __sdk::__query_builder::IxCol::new(table_name, "publication_status"),
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for Match3DWorkProfileRow {}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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 Match3DWorkPublishInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub published_at_micros: i64,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DWorkPublishInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// 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 Match3DWorkUpdateInput {
|
||||
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,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DWorkUpdateInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// 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 Match3DWorksListInput {
|
||||
pub owner_user_id: String,
|
||||
pub published_only: bool,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DWorksListInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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 Match3DWorksProcedureResult {
|
||||
pub ok: bool,
|
||||
pub items_json: Option::<String>,
|
||||
pub error_message: Option::<String>,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for Match3DWorksProcedureResult {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -183,6 +183,31 @@ pub mod inventory_mutation_type;
|
||||
pub mod inventory_mutation_input_type;
|
||||
pub mod inventory_slot_type;
|
||||
pub mod inventory_slot_snapshot_type;
|
||||
pub mod match_3_d_agent_message_finalize_input_type;
|
||||
pub mod match_3_d_agent_message_row_type;
|
||||
pub mod match_3_d_agent_message_submit_input_type;
|
||||
pub mod match_3_d_agent_session_create_input_type;
|
||||
pub mod match_3_d_agent_session_get_input_type;
|
||||
pub mod match_3_d_agent_session_procedure_result_type;
|
||||
pub mod match_3_d_agent_session_row_type;
|
||||
pub mod match_3_d_click_item_procedure_result_type;
|
||||
pub mod match_3_d_draft_compile_input_type;
|
||||
pub mod match_3_d_run_click_input_type;
|
||||
pub mod match_3_d_run_get_input_type;
|
||||
pub mod match_3_d_run_procedure_result_type;
|
||||
pub mod match_3_d_run_restart_input_type;
|
||||
pub mod match_3_d_run_start_input_type;
|
||||
pub mod match_3_d_run_stop_input_type;
|
||||
pub mod match_3_d_run_time_up_input_type;
|
||||
pub mod match_3_d_runtime_run_row_type;
|
||||
pub mod match_3_d_work_delete_input_type;
|
||||
pub mod match_3_d_work_get_input_type;
|
||||
pub mod match_3_d_work_procedure_result_type;
|
||||
pub mod match_3_d_work_profile_row_type;
|
||||
pub mod match_3_d_work_publish_input_type;
|
||||
pub mod match_3_d_work_update_input_type;
|
||||
pub mod match_3_d_works_list_input_type;
|
||||
pub mod match_3_d_works_procedure_result_type;
|
||||
pub mod npc_battle_interaction_procedure_result_type;
|
||||
pub mod npc_battle_interaction_result_type;
|
||||
pub mod npc_interaction_battle_mode_type;
|
||||
@@ -245,6 +270,7 @@ pub mod puzzle_select_cover_image_input_type;
|
||||
pub mod puzzle_work_delete_input_type;
|
||||
pub mod puzzle_work_get_input_type;
|
||||
pub mod puzzle_work_like_record_input_type;
|
||||
pub mod puzzle_work_point_incentive_claim_input_type;
|
||||
pub mod puzzle_work_procedure_result_type;
|
||||
pub mod puzzle_work_profile_row_type;
|
||||
pub mod puzzle_work_remix_input_type;
|
||||
@@ -414,10 +440,13 @@ pub mod authorize_database_migration_operator_procedure;
|
||||
pub mod begin_story_session_and_return_procedure;
|
||||
pub mod bind_asset_object_to_entity_and_return_procedure;
|
||||
pub mod cancel_ai_task_and_return_procedure;
|
||||
pub mod claim_puzzle_work_point_incentive_procedure;
|
||||
pub mod clear_database_migration_import_chunks_procedure;
|
||||
pub mod clear_platform_browse_history_and_return_procedure;
|
||||
pub mod click_match_3_d_item_procedure;
|
||||
pub mod compile_big_fish_draft_procedure;
|
||||
pub mod compile_custom_world_published_profile_procedure;
|
||||
pub mod compile_match_3_d_draft_procedure;
|
||||
pub mod compile_puzzle_agent_draft_procedure;
|
||||
pub mod complete_ai_stage_and_return_procedure;
|
||||
pub mod complete_ai_task_and_return_procedure;
|
||||
@@ -428,11 +457,13 @@ pub mod create_ai_task_and_return_procedure;
|
||||
pub mod create_battle_state_and_return_procedure;
|
||||
pub mod create_big_fish_session_procedure;
|
||||
pub mod create_custom_world_agent_session_procedure;
|
||||
pub mod create_match_3_d_agent_session_procedure;
|
||||
pub mod create_profile_recharge_order_and_return_procedure;
|
||||
pub mod create_puzzle_agent_session_procedure;
|
||||
pub mod delete_big_fish_work_procedure;
|
||||
pub mod delete_custom_world_agent_session_procedure;
|
||||
pub mod delete_custom_world_profile_and_return_procedure;
|
||||
pub mod delete_match_3_d_work_procedure;
|
||||
pub mod delete_puzzle_work_procedure;
|
||||
pub mod delete_runtime_snapshot_and_return_procedure;
|
||||
pub mod drag_puzzle_piece_or_group_procedure;
|
||||
@@ -442,7 +473,9 @@ pub mod export_database_migration_to_file_procedure;
|
||||
pub mod fail_ai_task_and_return_procedure;
|
||||
pub mod finalize_big_fish_agent_message_turn_procedure;
|
||||
pub mod finalize_custom_world_agent_message_turn_procedure;
|
||||
pub mod finalize_match_3_d_agent_message_turn_procedure;
|
||||
pub mod finalize_puzzle_agent_message_turn_procedure;
|
||||
pub mod finish_match_3_d_time_up_procedure;
|
||||
pub mod generate_big_fish_asset_procedure;
|
||||
pub mod get_auth_store_snapshot_procedure;
|
||||
pub mod get_battle_state_procedure;
|
||||
@@ -454,6 +487,9 @@ pub mod get_custom_world_agent_session_procedure;
|
||||
pub mod get_custom_world_gallery_detail_procedure;
|
||||
pub mod get_custom_world_gallery_detail_by_code_procedure;
|
||||
pub mod get_custom_world_library_detail_procedure;
|
||||
pub mod get_match_3_d_agent_session_procedure;
|
||||
pub mod get_match_3_d_run_procedure;
|
||||
pub mod get_match_3_d_work_detail_procedure;
|
||||
pub mod get_player_progression_or_default_procedure;
|
||||
pub mod get_profile_dashboard_procedure;
|
||||
pub mod get_profile_play_stats_procedure;
|
||||
@@ -478,6 +514,7 @@ pub mod list_big_fish_works_procedure;
|
||||
pub mod list_custom_world_gallery_entries_procedure;
|
||||
pub mod list_custom_world_profiles_procedure;
|
||||
pub mod list_custom_world_works_procedure;
|
||||
pub mod list_match_3_d_works_procedure;
|
||||
pub mod list_platform_browse_history_procedure;
|
||||
pub mod list_profile_save_archives_procedure;
|
||||
pub mod list_profile_wallet_ledger_procedure;
|
||||
@@ -486,6 +523,7 @@ pub mod list_puzzle_works_procedure;
|
||||
pub mod publish_big_fish_game_procedure;
|
||||
pub mod publish_custom_world_profile_and_return_procedure;
|
||||
pub mod publish_custom_world_world_procedure;
|
||||
pub mod publish_match_3_d_work_procedure;
|
||||
pub mod publish_puzzle_work_procedure;
|
||||
pub mod put_database_migration_import_chunk_procedure;
|
||||
pub mod record_big_fish_like_procedure;
|
||||
@@ -504,18 +542,23 @@ pub mod resolve_npc_battle_interaction_and_return_procedure;
|
||||
pub mod resolve_npc_interaction_and_return_procedure;
|
||||
pub mod resolve_npc_social_action_and_return_procedure;
|
||||
pub mod resolve_treasure_interaction_and_return_procedure;
|
||||
pub mod restart_match_3_d_run_procedure;
|
||||
pub mod resume_profile_save_archive_and_return_procedure;
|
||||
pub mod revoke_database_migration_operator_procedure;
|
||||
pub mod save_puzzle_form_draft_procedure;
|
||||
pub mod save_puzzle_generated_images_procedure;
|
||||
pub mod select_puzzle_cover_image_procedure;
|
||||
pub mod start_match_3_d_run_procedure;
|
||||
pub mod start_puzzle_run_procedure;
|
||||
pub mod stop_match_3_d_run_procedure;
|
||||
pub mod submit_big_fish_message_procedure;
|
||||
pub mod submit_custom_world_agent_message_procedure;
|
||||
pub mod submit_match_3_d_agent_message_procedure;
|
||||
pub mod submit_puzzle_agent_message_procedure;
|
||||
pub mod submit_puzzle_leaderboard_entry_procedure;
|
||||
pub mod swap_puzzle_pieces_procedure;
|
||||
pub mod unpublish_custom_world_profile_and_return_procedure;
|
||||
pub mod update_match_3_d_work_procedure;
|
||||
pub mod update_puzzle_run_pause_procedure;
|
||||
pub mod update_puzzle_work_procedure;
|
||||
pub mod upsert_auth_store_snapshot_procedure;
|
||||
@@ -700,6 +743,31 @@ pub use inventory_mutation_type::InventoryMutation;
|
||||
pub use inventory_mutation_input_type::InventoryMutationInput;
|
||||
pub use inventory_slot_type::InventorySlot;
|
||||
pub use inventory_slot_snapshot_type::InventorySlotSnapshot;
|
||||
pub use match_3_d_agent_message_finalize_input_type::Match3DAgentMessageFinalizeInput;
|
||||
pub use match_3_d_agent_message_row_type::Match3DAgentMessageRow;
|
||||
pub use match_3_d_agent_message_submit_input_type::Match3DAgentMessageSubmitInput;
|
||||
pub use match_3_d_agent_session_create_input_type::Match3DAgentSessionCreateInput;
|
||||
pub use match_3_d_agent_session_get_input_type::Match3DAgentSessionGetInput;
|
||||
pub use match_3_d_agent_session_procedure_result_type::Match3DAgentSessionProcedureResult;
|
||||
pub use match_3_d_agent_session_row_type::Match3DAgentSessionRow;
|
||||
pub use match_3_d_click_item_procedure_result_type::Match3DClickItemProcedureResult;
|
||||
pub use match_3_d_draft_compile_input_type::Match3DDraftCompileInput;
|
||||
pub use match_3_d_run_click_input_type::Match3DRunClickInput;
|
||||
pub use match_3_d_run_get_input_type::Match3DRunGetInput;
|
||||
pub use match_3_d_run_procedure_result_type::Match3DRunProcedureResult;
|
||||
pub use match_3_d_run_restart_input_type::Match3DRunRestartInput;
|
||||
pub use match_3_d_run_start_input_type::Match3DRunStartInput;
|
||||
pub use match_3_d_run_stop_input_type::Match3DRunStopInput;
|
||||
pub use match_3_d_run_time_up_input_type::Match3DRunTimeUpInput;
|
||||
pub use match_3_d_runtime_run_row_type::Match3DRuntimeRunRow;
|
||||
pub use match_3_d_work_delete_input_type::Match3DWorkDeleteInput;
|
||||
pub use match_3_d_work_get_input_type::Match3DWorkGetInput;
|
||||
pub use match_3_d_work_procedure_result_type::Match3DWorkProcedureResult;
|
||||
pub use match_3_d_work_profile_row_type::Match3DWorkProfileRow;
|
||||
pub use match_3_d_work_publish_input_type::Match3DWorkPublishInput;
|
||||
pub use match_3_d_work_update_input_type::Match3DWorkUpdateInput;
|
||||
pub use match_3_d_works_list_input_type::Match3DWorksListInput;
|
||||
pub use match_3_d_works_procedure_result_type::Match3DWorksProcedureResult;
|
||||
pub use npc_battle_interaction_procedure_result_type::NpcBattleInteractionProcedureResult;
|
||||
pub use npc_battle_interaction_result_type::NpcBattleInteractionResult;
|
||||
pub use npc_interaction_battle_mode_type::NpcInteractionBattleMode;
|
||||
@@ -762,6 +830,7 @@ pub use puzzle_select_cover_image_input_type::PuzzleSelectCoverImageInput;
|
||||
pub use puzzle_work_delete_input_type::PuzzleWorkDeleteInput;
|
||||
pub use puzzle_work_get_input_type::PuzzleWorkGetInput;
|
||||
pub use puzzle_work_like_record_input_type::PuzzleWorkLikeRecordInput;
|
||||
pub use puzzle_work_point_incentive_claim_input_type::PuzzleWorkPointIncentiveClaimInput;
|
||||
pub use puzzle_work_procedure_result_type::PuzzleWorkProcedureResult;
|
||||
pub use puzzle_work_profile_row_type::PuzzleWorkProfileRow;
|
||||
pub use puzzle_work_remix_input_type::PuzzleWorkRemixInput;
|
||||
@@ -931,10 +1000,13 @@ pub use authorize_database_migration_operator_procedure::authorize_database_migr
|
||||
pub use begin_story_session_and_return_procedure::begin_story_session_and_return;
|
||||
pub use bind_asset_object_to_entity_and_return_procedure::bind_asset_object_to_entity_and_return;
|
||||
pub use cancel_ai_task_and_return_procedure::cancel_ai_task_and_return;
|
||||
pub use claim_puzzle_work_point_incentive_procedure::claim_puzzle_work_point_incentive;
|
||||
pub use clear_database_migration_import_chunks_procedure::clear_database_migration_import_chunks;
|
||||
pub use clear_platform_browse_history_and_return_procedure::clear_platform_browse_history_and_return;
|
||||
pub use click_match_3_d_item_procedure::click_match_3_d_item;
|
||||
pub use compile_big_fish_draft_procedure::compile_big_fish_draft;
|
||||
pub use compile_custom_world_published_profile_procedure::compile_custom_world_published_profile;
|
||||
pub use compile_match_3_d_draft_procedure::compile_match_3_d_draft;
|
||||
pub use compile_puzzle_agent_draft_procedure::compile_puzzle_agent_draft;
|
||||
pub use complete_ai_stage_and_return_procedure::complete_ai_stage_and_return;
|
||||
pub use complete_ai_task_and_return_procedure::complete_ai_task_and_return;
|
||||
@@ -945,11 +1017,13 @@ pub use create_ai_task_and_return_procedure::create_ai_task_and_return;
|
||||
pub use create_battle_state_and_return_procedure::create_battle_state_and_return;
|
||||
pub use create_big_fish_session_procedure::create_big_fish_session;
|
||||
pub use create_custom_world_agent_session_procedure::create_custom_world_agent_session;
|
||||
pub use create_match_3_d_agent_session_procedure::create_match_3_d_agent_session;
|
||||
pub use create_profile_recharge_order_and_return_procedure::create_profile_recharge_order_and_return;
|
||||
pub use create_puzzle_agent_session_procedure::create_puzzle_agent_session;
|
||||
pub use delete_big_fish_work_procedure::delete_big_fish_work;
|
||||
pub use delete_custom_world_agent_session_procedure::delete_custom_world_agent_session;
|
||||
pub use delete_custom_world_profile_and_return_procedure::delete_custom_world_profile_and_return;
|
||||
pub use delete_match_3_d_work_procedure::delete_match_3_d_work;
|
||||
pub use delete_puzzle_work_procedure::delete_puzzle_work;
|
||||
pub use delete_runtime_snapshot_and_return_procedure::delete_runtime_snapshot_and_return;
|
||||
pub use drag_puzzle_piece_or_group_procedure::drag_puzzle_piece_or_group;
|
||||
@@ -959,7 +1033,9 @@ pub use export_database_migration_to_file_procedure::export_database_migration_t
|
||||
pub use fail_ai_task_and_return_procedure::fail_ai_task_and_return;
|
||||
pub use finalize_big_fish_agent_message_turn_procedure::finalize_big_fish_agent_message_turn;
|
||||
pub use finalize_custom_world_agent_message_turn_procedure::finalize_custom_world_agent_message_turn;
|
||||
pub use finalize_match_3_d_agent_message_turn_procedure::finalize_match_3_d_agent_message_turn;
|
||||
pub use finalize_puzzle_agent_message_turn_procedure::finalize_puzzle_agent_message_turn;
|
||||
pub use finish_match_3_d_time_up_procedure::finish_match_3_d_time_up;
|
||||
pub use generate_big_fish_asset_procedure::generate_big_fish_asset;
|
||||
pub use get_auth_store_snapshot_procedure::get_auth_store_snapshot;
|
||||
pub use get_battle_state_procedure::get_battle_state;
|
||||
@@ -971,6 +1047,9 @@ pub use get_custom_world_agent_session_procedure::get_custom_world_agent_session
|
||||
pub use get_custom_world_gallery_detail_procedure::get_custom_world_gallery_detail;
|
||||
pub use get_custom_world_gallery_detail_by_code_procedure::get_custom_world_gallery_detail_by_code;
|
||||
pub use get_custom_world_library_detail_procedure::get_custom_world_library_detail;
|
||||
pub use get_match_3_d_agent_session_procedure::get_match_3_d_agent_session;
|
||||
pub use get_match_3_d_run_procedure::get_match_3_d_run;
|
||||
pub use get_match_3_d_work_detail_procedure::get_match_3_d_work_detail;
|
||||
pub use get_player_progression_or_default_procedure::get_player_progression_or_default;
|
||||
pub use get_profile_dashboard_procedure::get_profile_dashboard;
|
||||
pub use get_profile_play_stats_procedure::get_profile_play_stats;
|
||||
@@ -995,6 +1074,7 @@ pub use list_big_fish_works_procedure::list_big_fish_works;
|
||||
pub use list_custom_world_gallery_entries_procedure::list_custom_world_gallery_entries;
|
||||
pub use list_custom_world_profiles_procedure::list_custom_world_profiles;
|
||||
pub use list_custom_world_works_procedure::list_custom_world_works;
|
||||
pub use list_match_3_d_works_procedure::list_match_3_d_works;
|
||||
pub use list_platform_browse_history_procedure::list_platform_browse_history;
|
||||
pub use list_profile_save_archives_procedure::list_profile_save_archives;
|
||||
pub use list_profile_wallet_ledger_procedure::list_profile_wallet_ledger;
|
||||
@@ -1003,6 +1083,7 @@ pub use list_puzzle_works_procedure::list_puzzle_works;
|
||||
pub use publish_big_fish_game_procedure::publish_big_fish_game;
|
||||
pub use publish_custom_world_profile_and_return_procedure::publish_custom_world_profile_and_return;
|
||||
pub use publish_custom_world_world_procedure::publish_custom_world_world;
|
||||
pub use publish_match_3_d_work_procedure::publish_match_3_d_work;
|
||||
pub use publish_puzzle_work_procedure::publish_puzzle_work;
|
||||
pub use put_database_migration_import_chunk_procedure::put_database_migration_import_chunk;
|
||||
pub use record_big_fish_like_procedure::record_big_fish_like;
|
||||
@@ -1021,18 +1102,23 @@ pub use resolve_npc_battle_interaction_and_return_procedure::resolve_npc_battle_
|
||||
pub use resolve_npc_interaction_and_return_procedure::resolve_npc_interaction_and_return;
|
||||
pub use resolve_npc_social_action_and_return_procedure::resolve_npc_social_action_and_return;
|
||||
pub use resolve_treasure_interaction_and_return_procedure::resolve_treasure_interaction_and_return;
|
||||
pub use restart_match_3_d_run_procedure::restart_match_3_d_run;
|
||||
pub use resume_profile_save_archive_and_return_procedure::resume_profile_save_archive_and_return;
|
||||
pub use revoke_database_migration_operator_procedure::revoke_database_migration_operator;
|
||||
pub use save_puzzle_form_draft_procedure::save_puzzle_form_draft;
|
||||
pub use save_puzzle_generated_images_procedure::save_puzzle_generated_images;
|
||||
pub use select_puzzle_cover_image_procedure::select_puzzle_cover_image;
|
||||
pub use start_match_3_d_run_procedure::start_match_3_d_run;
|
||||
pub use start_puzzle_run_procedure::start_puzzle_run;
|
||||
pub use stop_match_3_d_run_procedure::stop_match_3_d_run;
|
||||
pub use submit_big_fish_message_procedure::submit_big_fish_message;
|
||||
pub use submit_custom_world_agent_message_procedure::submit_custom_world_agent_message;
|
||||
pub use submit_match_3_d_agent_message_procedure::submit_match_3_d_agent_message;
|
||||
pub use submit_puzzle_agent_message_procedure::submit_puzzle_agent_message;
|
||||
pub use submit_puzzle_leaderboard_entry_procedure::submit_puzzle_leaderboard_entry;
|
||||
pub use swap_puzzle_pieces_procedure::swap_puzzle_pieces;
|
||||
pub use unpublish_custom_world_profile_and_return_procedure::unpublish_custom_world_profile_and_return;
|
||||
pub use update_match_3_d_work_procedure::update_match_3_d_work;
|
||||
pub use update_puzzle_run_pause_procedure::update_puzzle_run_pause;
|
||||
pub use update_puzzle_work_procedure::update_puzzle_work;
|
||||
pub use upsert_auth_store_snapshot_procedure::upsert_auth_store_snapshot;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_work_procedure_result_type::Match3DWorkProcedureResult;
|
||||
use super::match_3_d_work_publish_input_type::Match3DWorkPublishInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct PublishMatch3DWorkArgs {
|
||||
pub input: Match3DWorkPublishInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for PublishMatch3DWorkArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `publish_match_3_d_work`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait publish_match_3_d_work {
|
||||
fn publish_match_3_d_work(&self, input: Match3DWorkPublishInput,
|
||||
) {
|
||||
self.publish_match_3_d_work_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn publish_match_3_d_work_then(
|
||||
&self,
|
||||
input: Match3DWorkPublishInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DWorkProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl publish_match_3_d_work for super::RemoteProcedures {
|
||||
fn publish_match_3_d_work_then(
|
||||
&self,
|
||||
input: Match3DWorkPublishInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DWorkProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DWorkProcedureResult>(
|
||||
"publish_match_3_d_work",
|
||||
PublishMatch3DWorkArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ pub struct PuzzleRunPropInput {
|
||||
pub owner_user_id: String,
|
||||
pub prop_kind: String,
|
||||
pub used_at_micros: i64,
|
||||
pub spent_points: u64,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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 PuzzleWorkPointIncentiveClaimInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub claimed_at_micros: i64,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for PuzzleWorkPointIncentiveClaimInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ pub struct PuzzleWorkProfileRow {
|
||||
pub published_at: Option::<__sdk::Timestamp>,
|
||||
pub remix_count: u32,
|
||||
pub like_count: u32,
|
||||
pub point_incentive_total_half_points: u64,
|
||||
pub point_incentive_claimed_points: u64,
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +72,8 @@ pub struct PuzzleWorkProfileRowCols {
|
||||
pub published_at: __sdk::__query_builder::Col<PuzzleWorkProfileRow, Option::<__sdk::Timestamp>>,
|
||||
pub remix_count: __sdk::__query_builder::Col<PuzzleWorkProfileRow, u32>,
|
||||
pub like_count: __sdk::__query_builder::Col<PuzzleWorkProfileRow, u32>,
|
||||
pub point_incentive_total_half_points: __sdk::__query_builder::Col<PuzzleWorkProfileRow, u64>,
|
||||
pub point_incentive_claimed_points: __sdk::__query_builder::Col<PuzzleWorkProfileRow, u64>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for PuzzleWorkProfileRow {
|
||||
@@ -98,6 +102,8 @@ impl __sdk::__query_builder::HasCols for PuzzleWorkProfileRow {
|
||||
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
||||
remix_count: __sdk::__query_builder::Col::new(table_name, "remix_count"),
|
||||
like_count: __sdk::__query_builder::Col::new(table_name, "like_count"),
|
||||
point_incentive_total_half_points: __sdk::__query_builder::Col::new(table_name, "point_incentive_total_half_points"),
|
||||
point_incentive_claimed_points: __sdk::__query_builder::Col::new(table_name, "point_incentive_claimed_points"),
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_run_procedure_result_type::Match3DRunProcedureResult;
|
||||
use super::match_3_d_run_restart_input_type::Match3DRunRestartInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct RestartMatch3DRunArgs {
|
||||
pub input: Match3DRunRestartInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for RestartMatch3DRunArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `restart_match_3_d_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait restart_match_3_d_run {
|
||||
fn restart_match_3_d_run(&self, input: Match3DRunRestartInput,
|
||||
) {
|
||||
self.restart_match_3_d_run_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn restart_match_3_d_run_then(
|
||||
&self,
|
||||
input: Match3DRunRestartInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DRunProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl restart_match_3_d_run for super::RemoteProcedures {
|
||||
fn restart_match_3_d_run_then(
|
||||
&self,
|
||||
input: Match3DRunRestartInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DRunProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DRunProcedureResult>(
|
||||
"restart_match_3_d_run",
|
||||
RestartMatch3DRunArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ pub enum RuntimeProfileWalletLedgerSourceType {
|
||||
|
||||
RedeemCodeReward,
|
||||
|
||||
PuzzleAuthorIncentiveClaim,
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_run_procedure_result_type::Match3DRunProcedureResult;
|
||||
use super::match_3_d_run_start_input_type::Match3DRunStartInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct StartMatch3DRunArgs {
|
||||
pub input: Match3DRunStartInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for StartMatch3DRunArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `start_match_3_d_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait start_match_3_d_run {
|
||||
fn start_match_3_d_run(&self, input: Match3DRunStartInput,
|
||||
) {
|
||||
self.start_match_3_d_run_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn start_match_3_d_run_then(
|
||||
&self,
|
||||
input: Match3DRunStartInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DRunProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl start_match_3_d_run for super::RemoteProcedures {
|
||||
fn start_match_3_d_run_then(
|
||||
&self,
|
||||
input: Match3DRunStartInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DRunProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DRunProcedureResult>(
|
||||
"start_match_3_d_run",
|
||||
StartMatch3DRunArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_run_procedure_result_type::Match3DRunProcedureResult;
|
||||
use super::match_3_d_run_stop_input_type::Match3DRunStopInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct StopMatch3DRunArgs {
|
||||
pub input: Match3DRunStopInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for StopMatch3DRunArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `stop_match_3_d_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait stop_match_3_d_run {
|
||||
fn stop_match_3_d_run(&self, input: Match3DRunStopInput,
|
||||
) {
|
||||
self.stop_match_3_d_run_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn stop_match_3_d_run_then(
|
||||
&self,
|
||||
input: Match3DRunStopInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DRunProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl stop_match_3_d_run for super::RemoteProcedures {
|
||||
fn stop_match_3_d_run_then(
|
||||
&self,
|
||||
input: Match3DRunStopInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DRunProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DRunProcedureResult>(
|
||||
"stop_match_3_d_run",
|
||||
StopMatch3DRunArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_agent_session_procedure_result_type::Match3DAgentSessionProcedureResult;
|
||||
use super::match_3_d_agent_message_submit_input_type::Match3DAgentMessageSubmitInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct SubmitMatch3DAgentMessageArgs {
|
||||
pub input: Match3DAgentMessageSubmitInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for SubmitMatch3DAgentMessageArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `submit_match_3_d_agent_message`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait submit_match_3_d_agent_message {
|
||||
fn submit_match_3_d_agent_message(&self, input: Match3DAgentMessageSubmitInput,
|
||||
) {
|
||||
self.submit_match_3_d_agent_message_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn submit_match_3_d_agent_message_then(
|
||||
&self,
|
||||
input: Match3DAgentMessageSubmitInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl submit_match_3_d_agent_message for super::RemoteProcedures {
|
||||
fn submit_match_3_d_agent_message_then(
|
||||
&self,
|
||||
input: Match3DAgentMessageSubmitInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DAgentSessionProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DAgentSessionProcedureResult>(
|
||||
"submit_match_3_d_agent_message",
|
||||
SubmitMatch3DAgentMessageArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// 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::match_3_d_work_procedure_result_type::Match3DWorkProcedureResult;
|
||||
use super::match_3_d_work_update_input_type::Match3DWorkUpdateInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct UpdateMatch3DWorkArgs {
|
||||
pub input: Match3DWorkUpdateInput,
|
||||
}
|
||||
|
||||
|
||||
impl __sdk::InModule for UpdateMatch3DWorkArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `update_match_3_d_work`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait update_match_3_d_work {
|
||||
fn update_match_3_d_work(&self, input: Match3DWorkUpdateInput,
|
||||
) {
|
||||
self.update_match_3_d_work_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn update_match_3_d_work_then(
|
||||
&self,
|
||||
input: Match3DWorkUpdateInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DWorkProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl update_match_3_d_work for super::RemoteProcedures {
|
||||
fn update_match_3_d_work_then(
|
||||
&self,
|
||||
input: Match3DWorkUpdateInput,
|
||||
|
||||
__callback: impl FnOnce(&super::ProcedureEventContext, Result<Match3DWorkProcedureResult, __sdk::InternalError>) + Send + 'static,
|
||||
) {
|
||||
self.imp.invoke_procedure_with_callback::<_, Match3DWorkProcedureResult>(
|
||||
"update_match_3_d_work",
|
||||
UpdateMatch3DWorkArgs { input, },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use super::*;
|
||||
use crate::mapper::*;
|
||||
use crate::module_bindings::claim_puzzle_work_point_incentive_procedure::claim_puzzle_work_point_incentive;
|
||||
use crate::module_bindings::delete_puzzle_work_procedure::delete_puzzle_work;
|
||||
use crate::module_bindings::record_puzzle_work_like_procedure::record_puzzle_work_like;
|
||||
use crate::module_bindings::remix_puzzle_work_procedure::remix_puzzle_work;
|
||||
@@ -340,6 +341,29 @@ impl SpacetimeClient {
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn claim_puzzle_work_point_incentive(
|
||||
&self,
|
||||
input: PuzzleWorkPointIncentiveClaimRecordInput,
|
||||
) -> Result<PuzzleWorkProfileRecord, SpacetimeClientError> {
|
||||
let procedure_input = PuzzleWorkPointIncentiveClaimInput {
|
||||
profile_id: input.profile_id,
|
||||
owner_user_id: input.owner_user_id,
|
||||
claimed_at_micros: input.claimed_at_micros,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.claim_puzzle_work_point_incentive_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_puzzle_work_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn list_puzzle_gallery(
|
||||
&self,
|
||||
) -> Result<Vec<PuzzleWorkProfileRecord>, SpacetimeClientError> {
|
||||
@@ -586,6 +610,7 @@ impl SpacetimeClient {
|
||||
owner_user_id: input.owner_user_id,
|
||||
prop_kind: input.prop_kind,
|
||||
used_at_micros: input.used_at_micros,
|
||||
spent_points: input.spent_points,
|
||||
};
|
||||
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
|
||||
@@ -1145,6 +1145,12 @@ fn normalize_migration_row(table_name: &str, value: &serde_json::Value) -> serde
|
||||
object
|
||||
.entry("like_count".to_string())
|
||||
.or_insert_with(|| serde_json::Value::from(0));
|
||||
object
|
||||
.entry("point_incentive_total_half_points".to_string())
|
||||
.or_insert_with(|| serde_json::Value::from(0));
|
||||
object
|
||||
.entry("point_incentive_claimed_points".to_string())
|
||||
.or_insert_with(|| serde_json::Value::from(0));
|
||||
// 中文注释:拼图多关卡字段晚于旧作品表加入,旧迁移包留空并由读取层补出首关。
|
||||
object
|
||||
.entry("levels_json".to_string())
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::runtime::{
|
||||
ProfilePlayedWorkUpsertInput, PublicWorkLikeRecordInput, PublicWorkPlayRecordInput,
|
||||
ProfileSaveArchiveUpsertInput,
|
||||
add_profile_observed_play_time, count_recent_public_work_plays, record_public_work_like,
|
||||
record_public_work_play, upsert_profile_played_work, upsert_profile_save_archive,
|
||||
ProfilePlayedWorkUpsertInput, ProfileSaveArchiveUpsertInput, PublicWorkLikeRecordInput,
|
||||
PublicWorkPlayRecordInput, add_profile_observed_play_time, count_recent_public_work_plays,
|
||||
grant_profile_wallet_points, record_public_work_like, record_public_work_play,
|
||||
upsert_profile_played_work, upsert_profile_save_archive,
|
||||
};
|
||||
use module_puzzle::{
|
||||
PUZZLE_MAX_TAG_COUNT, PUZZLE_NEXT_LEVEL_MODE_NONE, PUZZLE_NEXT_LEVEL_MODE_SAME_WORK,
|
||||
@@ -16,19 +16,23 @@ use module_puzzle::{
|
||||
PuzzleRunNextLevelInput, PuzzleRunPauseInput, PuzzleRunProcedureResult, PuzzleRunPropInput,
|
||||
PuzzleRunSnapshot, PuzzleRunStartInput, PuzzleRunSwapInput, PuzzleRuntimeLevelStatus,
|
||||
PuzzleSelectCoverImageInput, PuzzleWorkDeleteInput, PuzzleWorkGetInput,
|
||||
PuzzleWorkLikeRecordInput as PuzzleWorkLikeInput, PuzzleWorkProcedureResult, PuzzleWorkProfile,
|
||||
PuzzleWorkRemixInput, PuzzleWorkUpsertInput, PuzzleWorksListInput, PuzzleWorksProcedureResult,
|
||||
apply_publish_overrides_to_draft, apply_selected_candidate, build_form_draft_from_seed,
|
||||
build_result_preview, compile_result_draft_from_seed, create_work_profile, infer_anchor_pack,
|
||||
normalize_puzzle_draft, normalize_puzzle_levels, normalize_theme_tags, publish_work_profile,
|
||||
replace_puzzle_level, resolve_puzzle_grid_size, select_next_profiles,
|
||||
selected_profile_level_after_runtime_level, selected_puzzle_level, tag_similarity_score,
|
||||
PuzzleWorkLikeRecordInput as PuzzleWorkLikeInput, PuzzleWorkPointIncentiveClaimInput,
|
||||
PuzzleWorkProcedureResult, PuzzleWorkProfile, PuzzleWorkRemixInput, PuzzleWorkUpsertInput,
|
||||
PuzzleWorksListInput, PuzzleWorksProcedureResult, apply_publish_overrides_to_draft,
|
||||
apply_selected_candidate, build_form_draft_from_seed, build_result_preview,
|
||||
compile_result_draft_from_seed, create_work_profile, infer_anchor_pack, normalize_puzzle_draft,
|
||||
normalize_puzzle_levels, normalize_theme_tags, publish_work_profile, replace_puzzle_level,
|
||||
select_next_profiles, selected_profile_level_after_runtime_level, selected_puzzle_level,
|
||||
tag_similarity_score,
|
||||
};
|
||||
use module_runtime::RuntimeProfileWalletLedgerSourceType;
|
||||
use serde_json::from_str as json_from_str;
|
||||
use serde_json::json;
|
||||
use serde_json::to_string as json_to_string;
|
||||
use spacetimedb::{ProcedureContext, Table, Timestamp, TxContext};
|
||||
|
||||
const PUZZLE_POINT_INCENTIVE_DEFAULT_U64: u64 = 0;
|
||||
|
||||
/// 拼图 Agent session 真相表。
|
||||
/// 当前只保存结构化字段与 JSON 草稿,不提前拆出更多编辑态子表。
|
||||
#[spacetimedb::table(
|
||||
@@ -98,6 +102,10 @@ pub struct PuzzleWorkProfileRow {
|
||||
remix_count: u32,
|
||||
#[default(0)]
|
||||
like_count: u32,
|
||||
#[default(PUZZLE_POINT_INCENTIVE_DEFAULT_U64)]
|
||||
point_incentive_total_half_points: u64,
|
||||
#[default(PUZZLE_POINT_INCENTIVE_DEFAULT_U64)]
|
||||
point_incentive_claimed_points: u64,
|
||||
}
|
||||
|
||||
/// 运行态 run 快照表。
|
||||
@@ -595,6 +603,25 @@ pub fn use_puzzle_runtime_prop(
|
||||
}
|
||||
}
|
||||
|
||||
#[spacetimedb::procedure]
|
||||
pub fn claim_puzzle_work_point_incentive(
|
||||
ctx: &mut ProcedureContext,
|
||||
input: PuzzleWorkPointIncentiveClaimInput,
|
||||
) -> PuzzleWorkProcedureResult {
|
||||
match ctx.try_with_tx(|tx| claim_puzzle_work_point_incentive_tx(tx, input.clone())) {
|
||||
Ok(item) => PuzzleWorkProcedureResult {
|
||||
ok: true,
|
||||
item_json: Some(serialize_json(&item)),
|
||||
error_message: None,
|
||||
},
|
||||
Err(message) => PuzzleWorkProcedureResult {
|
||||
ok: false,
|
||||
item_json: None,
|
||||
error_message: Some(message),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[spacetimedb::procedure]
|
||||
pub fn submit_puzzle_leaderboard_entry(
|
||||
ctx: &mut ProcedureContext,
|
||||
@@ -1186,6 +1213,8 @@ fn update_puzzle_work_tx(
|
||||
play_count: row.play_count,
|
||||
remix_count: row.remix_count,
|
||||
like_count: row.like_count,
|
||||
point_incentive_total_half_points: row.point_incentive_total_half_points,
|
||||
point_incentive_claimed_points: row.point_incentive_claimed_points,
|
||||
anchor_pack_json: row.anchor_pack_json.clone(),
|
||||
publish_ready: build_result_preview(&preview_draft, Some(&row.author_display_name))
|
||||
.publish_ready,
|
||||
@@ -1341,6 +1370,8 @@ fn record_puzzle_work_like_tx(
|
||||
play_count: row.play_count,
|
||||
remix_count: row.remix_count,
|
||||
like_count: row.like_count.saturating_add(1),
|
||||
point_incentive_total_half_points: row.point_incentive_total_half_points,
|
||||
point_incentive_claimed_points: row.point_incentive_claimed_points,
|
||||
anchor_pack_json: row.anchor_pack_json.clone(),
|
||||
publish_ready: row.publish_ready,
|
||||
created_at: row.created_at,
|
||||
@@ -1427,6 +1458,8 @@ fn remix_puzzle_work_tx(
|
||||
play_count: source.play_count,
|
||||
remix_count: source.remix_count.saturating_add(1),
|
||||
like_count: source.like_count,
|
||||
point_incentive_total_half_points: source.point_incentive_total_half_points,
|
||||
point_incentive_claimed_points: source.point_incentive_claimed_points,
|
||||
anchor_pack_json: source.anchor_pack_json.clone(),
|
||||
publish_ready: source.publish_ready,
|
||||
created_at: source.created_at,
|
||||
@@ -1492,6 +1525,8 @@ fn remix_puzzle_work_tx(
|
||||
play_count: 0,
|
||||
remix_count: 0,
|
||||
like_count: 0,
|
||||
point_incentive_total_half_points: 0,
|
||||
point_incentive_claimed_points: 0,
|
||||
anchor_pack_json: serialize_json(&source_profile.anchor_pack),
|
||||
publish_ready: true,
|
||||
created_at: remixed_at,
|
||||
@@ -1531,13 +1566,20 @@ fn start_puzzle_run_tx(
|
||||
return Err("入口拼图作品未发布".to_string());
|
||||
}
|
||||
let mut entry_profile = build_puzzle_work_profile_from_row(&entry_profile_row)?;
|
||||
let mut cleared_level_count = 0;
|
||||
if let Some(level) = selected_profile_level(&entry_profile, input.level_id.as_deref())? {
|
||||
cleared_level_count =
|
||||
module_puzzle::resolve_restart_cleared_level_count(&entry_profile, &level.level_id);
|
||||
entry_profile = profile_for_single_level(&entry_profile, &level);
|
||||
}
|
||||
let started_at_ms = micros_to_millis(input.started_at_micros);
|
||||
let mut run =
|
||||
module_puzzle::start_run_at(input.run_id.clone(), &entry_profile, 0, started_at_ms)
|
||||
.map_err(|error| error.to_string())?;
|
||||
let mut run = module_puzzle::start_run_at(
|
||||
input.run_id.clone(),
|
||||
&entry_profile,
|
||||
cleared_level_count,
|
||||
started_at_ms,
|
||||
)
|
||||
.map_err(|error| error.to_string())?;
|
||||
let current_grid_size = run.current_grid_size;
|
||||
let current_profile_id = entry_profile.profile_id.clone();
|
||||
hydrate_puzzle_leaderboard_entries(
|
||||
@@ -1682,26 +1724,40 @@ fn advance_puzzle_next_level_tx(
|
||||
.find(¤t_level.profile_id)
|
||||
.ok_or_else(|| "当前拼图作品不存在".to_string())?;
|
||||
let current_profile = build_puzzle_work_profile_from_row(¤t_profile_row)?;
|
||||
let next_profile = selected_profile_level_after_runtime_level(¤t_profile, current_level)
|
||||
.map(|level| profile_for_single_level(¤t_profile, &level))
|
||||
.or_else(|| {
|
||||
let candidates = list_published_puzzle_profiles(ctx).ok()?;
|
||||
select_next_profiles(
|
||||
¤t_profile,
|
||||
¤t_run.played_profile_ids,
|
||||
&candidates,
|
||||
1,
|
||||
)
|
||||
.into_iter()
|
||||
.next()
|
||||
.cloned()
|
||||
})
|
||||
let same_work_next_profile =
|
||||
selected_profile_level_after_runtime_level(¤t_profile, current_level)
|
||||
.map(|level| profile_for_single_level(¤t_profile, &level));
|
||||
let similar_work_next_profile = if same_work_next_profile.is_none() {
|
||||
let candidates = list_published_puzzle_profiles(ctx)?;
|
||||
select_next_profiles(
|
||||
¤t_profile,
|
||||
¤t_run.played_profile_ids,
|
||||
&candidates,
|
||||
1,
|
||||
)
|
||||
.into_iter()
|
||||
.next()
|
||||
.cloned()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let next_profile = same_work_next_profile
|
||||
.as_ref()
|
||||
.or(similar_work_next_profile.as_ref())
|
||||
.ok_or_else(|| "没有可用的下一关候选".to_string())?;
|
||||
let mut next_run = module_puzzle::advance_next_level_at(
|
||||
¤t_run,
|
||||
&next_profile,
|
||||
micros_to_millis(input.advanced_at_micros),
|
||||
)
|
||||
let mut next_run = if same_work_next_profile.is_some() {
|
||||
module_puzzle::advance_next_level_at(
|
||||
¤t_run,
|
||||
next_profile,
|
||||
micros_to_millis(input.advanced_at_micros),
|
||||
)
|
||||
} else {
|
||||
module_puzzle::advance_to_new_work_first_level_at(
|
||||
¤t_run,
|
||||
next_profile,
|
||||
micros_to_millis(input.advanced_at_micros),
|
||||
)
|
||||
}
|
||||
.map_err(|error| error.to_string())?;
|
||||
let next_grid_size = next_run.current_grid_size;
|
||||
let next_profile_id = next_profile.profile_id.clone();
|
||||
@@ -1805,6 +1861,19 @@ fn use_puzzle_runtime_prop_tx(
|
||||
};
|
||||
let mut hydrated_run = next_run;
|
||||
refresh_next_level_handoff(ctx, &mut hydrated_run)?;
|
||||
if let Some(profile_id) = hydrated_run
|
||||
.current_level
|
||||
.as_ref()
|
||||
.map(|level| level.profile_id.clone())
|
||||
{
|
||||
accrue_puzzle_point_incentive(
|
||||
ctx,
|
||||
&profile_id,
|
||||
&input.owner_user_id,
|
||||
input.spent_points,
|
||||
input.used_at_micros,
|
||||
)?;
|
||||
}
|
||||
replace_puzzle_runtime_run(ctx, &row, &hydrated_run, input.used_at_micros);
|
||||
if let Some((profile_id, grid_size)) = hydrated_run
|
||||
.current_level
|
||||
@@ -1822,6 +1891,86 @@ fn use_puzzle_runtime_prop_tx(
|
||||
Ok(hydrated_run)
|
||||
}
|
||||
|
||||
fn claim_puzzle_work_point_incentive_tx(
|
||||
ctx: &TxContext,
|
||||
input: PuzzleWorkPointIncentiveClaimInput,
|
||||
) -> Result<PuzzleWorkProfile, String> {
|
||||
let profile_id = input.profile_id.trim();
|
||||
let owner_user_id = input.owner_user_id.trim();
|
||||
if profile_id.is_empty() || owner_user_id.is_empty() {
|
||||
return Err("拼图积分激励参数不能为空".to_string());
|
||||
}
|
||||
|
||||
let row = ctx
|
||||
.db
|
||||
.puzzle_work_profile()
|
||||
.profile_id()
|
||||
.find(&profile_id.to_string())
|
||||
.ok_or_else(|| "拼图作品不存在".to_string())?;
|
||||
if row.owner_user_id != owner_user_id {
|
||||
return Err("无权领取该作品的积分激励".to_string());
|
||||
}
|
||||
|
||||
let claimable_points = puzzle_point_incentive_claimable_points(
|
||||
row.point_incentive_total_half_points,
|
||||
row.point_incentive_claimed_points,
|
||||
);
|
||||
if claimable_points == 0 {
|
||||
return Err("暂无可领取积分激励".to_string());
|
||||
}
|
||||
|
||||
let claimed_at = Timestamp::from_micros_since_unix_epoch(input.claimed_at_micros);
|
||||
let next_row = PuzzleWorkProfileRow {
|
||||
profile_id: row.profile_id.clone(),
|
||||
work_id: row.work_id.clone(),
|
||||
owner_user_id: row.owner_user_id.clone(),
|
||||
source_session_id: row.source_session_id.clone(),
|
||||
author_display_name: row.author_display_name.clone(),
|
||||
work_title: row.work_title.clone(),
|
||||
work_description: row.work_description.clone(),
|
||||
level_name: row.level_name.clone(),
|
||||
summary: row.summary.clone(),
|
||||
theme_tags_json: row.theme_tags_json.clone(),
|
||||
cover_image_src: row.cover_image_src.clone(),
|
||||
cover_asset_id: row.cover_asset_id.clone(),
|
||||
levels_json: row.levels_json.clone(),
|
||||
publication_status: row.publication_status,
|
||||
play_count: row.play_count,
|
||||
remix_count: row.remix_count,
|
||||
like_count: row.like_count,
|
||||
point_incentive_total_half_points: row.point_incentive_total_half_points,
|
||||
point_incentive_claimed_points: row
|
||||
.point_incentive_claimed_points
|
||||
.saturating_add(claimable_points),
|
||||
anchor_pack_json: row.anchor_pack_json.clone(),
|
||||
publish_ready: row.publish_ready,
|
||||
created_at: row.created_at,
|
||||
updated_at: claimed_at,
|
||||
published_at: row.published_at,
|
||||
};
|
||||
replace_puzzle_work_profile(ctx, &row, next_row);
|
||||
|
||||
grant_profile_wallet_points(
|
||||
ctx,
|
||||
owner_user_id,
|
||||
claimable_points,
|
||||
RuntimeProfileWalletLedgerSourceType::PuzzleAuthorIncentiveClaim,
|
||||
&format!(
|
||||
"puzzle_author_incentive_claim:{}:{}:{}",
|
||||
profile_id, owner_user_id, input.claimed_at_micros
|
||||
),
|
||||
claimed_at,
|
||||
)?;
|
||||
|
||||
let updated = ctx
|
||||
.db
|
||||
.puzzle_work_profile()
|
||||
.profile_id()
|
||||
.find(&profile_id.to_string())
|
||||
.ok_or_else(|| "拼图积分激励领取更新失败".to_string())?;
|
||||
build_puzzle_work_profile_from_row(&updated)
|
||||
}
|
||||
|
||||
fn submit_puzzle_leaderboard_entry_tx(
|
||||
ctx: &TxContext,
|
||||
input: PuzzleLeaderboardSubmitInput,
|
||||
@@ -1835,7 +1984,7 @@ fn submit_puzzle_leaderboard_entry_tx(
|
||||
if input.profile_id.trim().is_empty() {
|
||||
return Err("提交成绩的拼图作品不能为空".to_string());
|
||||
}
|
||||
if input.grid_size != 3 && input.grid_size != 4 {
|
||||
if !module_puzzle::is_supported_puzzle_grid_size(input.grid_size) {
|
||||
return Err("提交成绩的网格规格无效".to_string());
|
||||
}
|
||||
let matches_service_level =
|
||||
@@ -2002,6 +2151,8 @@ fn build_puzzle_work_profile_from_row_without_recent_count(
|
||||
play_count: row.play_count,
|
||||
remix_count: row.remix_count,
|
||||
like_count: row.like_count,
|
||||
point_incentive_total_half_points: row.point_incentive_total_half_points,
|
||||
point_incentive_claimed_points: row.point_incentive_claimed_points,
|
||||
recent_play_count_7d: 0,
|
||||
publish_ready: row.publish_ready,
|
||||
anchor_pack: deserialize_anchor_pack(&row.anchor_pack_json)?,
|
||||
@@ -2108,6 +2259,8 @@ fn upsert_puzzle_draft_work_profile(
|
||||
profile.play_count = existing.play_count;
|
||||
profile.remix_count = existing.remix_count;
|
||||
profile.like_count = existing.like_count;
|
||||
profile.point_incentive_total_half_points = existing.point_incentive_total_half_points;
|
||||
profile.point_incentive_claimed_points = existing.point_incentive_claimed_points;
|
||||
return upsert_puzzle_work_profile(ctx, profile);
|
||||
}
|
||||
let profile = create_work_profile(
|
||||
@@ -2286,6 +2439,12 @@ fn upsert_puzzle_work_profile(ctx: &TxContext, profile: PuzzleWorkProfile) -> Re
|
||||
play_count: existing.play_count.max(profile.play_count),
|
||||
remix_count: existing.remix_count.max(profile.remix_count),
|
||||
like_count: existing.like_count.max(profile.like_count),
|
||||
point_incentive_total_half_points: existing
|
||||
.point_incentive_total_half_points
|
||||
.max(profile.point_incentive_total_half_points),
|
||||
point_incentive_claimed_points: existing
|
||||
.point_incentive_claimed_points
|
||||
.max(profile.point_incentive_claimed_points),
|
||||
anchor_pack_json: serialize_json(&profile.anchor_pack),
|
||||
publish_ready: profile.publish_ready,
|
||||
created_at: existing.created_at,
|
||||
@@ -2316,6 +2475,8 @@ fn upsert_puzzle_work_profile(ctx: &TxContext, profile: PuzzleWorkProfile) -> Re
|
||||
play_count: profile.play_count,
|
||||
remix_count: profile.remix_count,
|
||||
like_count: profile.like_count,
|
||||
point_incentive_total_half_points: profile.point_incentive_total_half_points,
|
||||
point_incentive_claimed_points: profile.point_incentive_claimed_points,
|
||||
anchor_pack_json: serialize_json(&profile.anchor_pack),
|
||||
publish_ready: profile.publish_ready,
|
||||
created_at: Timestamp::from_micros_since_unix_epoch(profile.updated_at_micros),
|
||||
@@ -2375,7 +2536,7 @@ fn replace_puzzle_runtime_run(
|
||||
.unwrap_or_else(|| current.current_profile_id.clone()),
|
||||
cleared_level_count: run.cleared_level_count,
|
||||
current_level_index: run.current_level_index,
|
||||
current_grid_size: resolve_puzzle_grid_size(run.cleared_level_count),
|
||||
current_grid_size: run.current_grid_size,
|
||||
played_profile_ids_json: serialize_json(&run.played_profile_ids),
|
||||
previous_level_tags_json: serialize_json(&run.previous_level_tags),
|
||||
snapshot_json: serialize_json(run),
|
||||
@@ -2403,16 +2564,17 @@ fn upsert_puzzle_profile_save_archive(
|
||||
return Ok(());
|
||||
};
|
||||
let world_key = format!("puzzle:{}", run.entry_profile_id);
|
||||
let target = resolve_puzzle_archive_target(ctx, run, current_level)?;
|
||||
|
||||
// 中文注释:拼图存档只保存恢复入口所需的最小运行态索引,棋盘真相继续放在 puzzle_runtime_run。
|
||||
let game_state_json = json_to_string(&json!({
|
||||
"runtimeKind": "puzzle",
|
||||
"runId": run.run_id,
|
||||
"entryProfileId": run.entry_profile_id,
|
||||
"currentProfileId": current_level.profile_id,
|
||||
"currentLevelIndex": current_level.level_index,
|
||||
"currentLevelId": current_level.level_id,
|
||||
"status": current_level.status.as_str(),
|
||||
"currentProfileId": target.profile_id,
|
||||
"currentLevelIndex": target.level_index,
|
||||
"currentLevelId": target.level_id,
|
||||
"status": target.status.as_str(),
|
||||
}))
|
||||
.unwrap_or_else(|_| "{}".to_string());
|
||||
|
||||
@@ -2421,13 +2583,13 @@ fn upsert_puzzle_profile_save_archive(
|
||||
ProfileSaveArchiveUpsertInput {
|
||||
user_id: user_id.to_string(),
|
||||
world_key,
|
||||
owner_user_id: resolve_puzzle_current_owner_user_id(ctx, ¤t_level.profile_id),
|
||||
owner_user_id: target.owner_user_id,
|
||||
profile_id: Some(run.entry_profile_id.clone()),
|
||||
world_type: Some("PUZZLE".to_string()),
|
||||
world_name: current_level.level_name.clone(),
|
||||
subtitle: format!("第 {} 关", current_level.level_index),
|
||||
summary_text: puzzle_archive_summary_text(current_level.status),
|
||||
cover_image_src: current_level.cover_image_src.clone(),
|
||||
world_name: target.level_name,
|
||||
subtitle: format!("第 {} 关", target.level_index),
|
||||
summary_text: puzzle_archive_summary_text(target.status),
|
||||
cover_image_src: target.cover_image_src,
|
||||
bottom_tab: "puzzle".to_string(),
|
||||
game_state_json,
|
||||
current_story_json: None,
|
||||
@@ -2436,6 +2598,88 @@ fn upsert_puzzle_profile_save_archive(
|
||||
)
|
||||
}
|
||||
|
||||
struct PuzzleArchiveTarget {
|
||||
profile_id: String,
|
||||
level_index: u32,
|
||||
level_id: Option<String>,
|
||||
level_name: String,
|
||||
status: PuzzleRuntimeLevelStatus,
|
||||
cover_image_src: Option<String>,
|
||||
owner_user_id: Option<String>,
|
||||
}
|
||||
|
||||
fn resolve_puzzle_archive_target(
|
||||
ctx: &TxContext,
|
||||
run: &PuzzleRunSnapshot,
|
||||
current_level: &module_puzzle::PuzzleRuntimeLevelSnapshot,
|
||||
) -> Result<PuzzleArchiveTarget, String> {
|
||||
let owner_user_id = resolve_puzzle_current_owner_user_id(ctx, ¤t_level.profile_id);
|
||||
if current_level.status != PuzzleRuntimeLevelStatus::Cleared {
|
||||
return Ok(PuzzleArchiveTarget {
|
||||
profile_id: current_level.profile_id.clone(),
|
||||
level_index: current_level.level_index,
|
||||
level_id: current_level.level_id.clone(),
|
||||
level_name: current_level.level_name.clone(),
|
||||
status: current_level.status,
|
||||
cover_image_src: current_level.cover_image_src.clone(),
|
||||
owner_user_id,
|
||||
});
|
||||
}
|
||||
|
||||
let Some(next_level_id) = run
|
||||
.next_level_id
|
||||
.as_deref()
|
||||
.filter(|value| !value.trim().is_empty())
|
||||
else {
|
||||
return Ok(PuzzleArchiveTarget {
|
||||
profile_id: current_level.profile_id.clone(),
|
||||
level_index: current_level.level_index,
|
||||
level_id: current_level.level_id.clone(),
|
||||
level_name: current_level.level_name.clone(),
|
||||
status: current_level.status,
|
||||
cover_image_src: current_level.cover_image_src.clone(),
|
||||
owner_user_id,
|
||||
});
|
||||
};
|
||||
if run.next_level_profile_id.as_deref() != Some(current_level.profile_id.as_str())
|
||||
|| run.next_level_mode != PUZZLE_NEXT_LEVEL_MODE_SAME_WORK
|
||||
{
|
||||
return Ok(PuzzleArchiveTarget {
|
||||
profile_id: current_level.profile_id.clone(),
|
||||
level_index: current_level.level_index,
|
||||
level_id: current_level.level_id.clone(),
|
||||
level_name: current_level.level_name.clone(),
|
||||
status: current_level.status,
|
||||
cover_image_src: current_level.cover_image_src.clone(),
|
||||
owner_user_id,
|
||||
});
|
||||
}
|
||||
|
||||
let current_profile = build_puzzle_work_profile_from_row(
|
||||
&ctx.db
|
||||
.puzzle_work_profile()
|
||||
.profile_id()
|
||||
.find(¤t_level.profile_id)
|
||||
.ok_or_else(|| "当前拼图作品不存在".to_string())?,
|
||||
)?;
|
||||
let next_level = current_profile
|
||||
.levels
|
||||
.iter()
|
||||
.find(|level| level.level_id == next_level_id)
|
||||
.cloned()
|
||||
.ok_or_else(|| "下一关拼图关卡不存在".to_string())?;
|
||||
|
||||
Ok(PuzzleArchiveTarget {
|
||||
profile_id: current_profile.profile_id,
|
||||
level_index: current_level.level_index.saturating_add(1),
|
||||
level_id: Some(next_level.level_id),
|
||||
level_name: next_level.level_name,
|
||||
status: PuzzleRuntimeLevelStatus::Playing,
|
||||
cover_image_src: next_level.cover_image_src,
|
||||
owner_user_id,
|
||||
})
|
||||
}
|
||||
|
||||
fn resolve_puzzle_current_owner_user_id(ctx: &TxContext, profile_id: &str) -> Option<String> {
|
||||
ctx.db
|
||||
.puzzle_work_profile()
|
||||
@@ -2453,6 +2697,72 @@ fn puzzle_archive_summary_text(status: PuzzleRuntimeLevelStatus) -> String {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn puzzle_point_incentive_claimable_points(total_half_points: u64, claimed_points: u64) -> u64 {
|
||||
total_half_points
|
||||
.saturating_div(2)
|
||||
.saturating_sub(claimed_points)
|
||||
}
|
||||
|
||||
fn accrue_puzzle_point_incentive(
|
||||
ctx: &TxContext,
|
||||
profile_id: &str,
|
||||
player_user_id: &str,
|
||||
spent_points: u64,
|
||||
updated_at_micros: i64,
|
||||
) -> Result<(), String> {
|
||||
if spent_points == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let Some(row) = ctx
|
||||
.db
|
||||
.puzzle_work_profile()
|
||||
.profile_id()
|
||||
.find(&profile_id.to_string())
|
||||
else {
|
||||
return Ok(());
|
||||
};
|
||||
if row.publication_status != PuzzlePublicationStatus::Published
|
||||
|| row.owner_user_id == player_user_id
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
replace_puzzle_work_profile(
|
||||
ctx,
|
||||
&row,
|
||||
PuzzleWorkProfileRow {
|
||||
profile_id: row.profile_id.clone(),
|
||||
work_id: row.work_id.clone(),
|
||||
owner_user_id: row.owner_user_id.clone(),
|
||||
source_session_id: row.source_session_id.clone(),
|
||||
author_display_name: row.author_display_name.clone(),
|
||||
work_title: row.work_title.clone(),
|
||||
work_description: row.work_description.clone(),
|
||||
level_name: row.level_name.clone(),
|
||||
summary: row.summary.clone(),
|
||||
theme_tags_json: row.theme_tags_json.clone(),
|
||||
cover_image_src: row.cover_image_src.clone(),
|
||||
cover_asset_id: row.cover_asset_id.clone(),
|
||||
levels_json: row.levels_json.clone(),
|
||||
publication_status: row.publication_status,
|
||||
play_count: row.play_count,
|
||||
remix_count: row.remix_count,
|
||||
like_count: row.like_count,
|
||||
point_incentive_total_half_points: row
|
||||
.point_incentive_total_half_points
|
||||
.saturating_add(spent_points),
|
||||
point_incentive_claimed_points: row.point_incentive_claimed_points,
|
||||
anchor_pack_json: row.anchor_pack_json.clone(),
|
||||
publish_ready: row.publish_ready,
|
||||
created_at: row.created_at,
|
||||
updated_at: Timestamp::from_micros_since_unix_epoch(updated_at_micros),
|
||||
published_at: row.published_at,
|
||||
},
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn increment_puzzle_profile_play_count(
|
||||
ctx: &TxContext,
|
||||
row: &PuzzleWorkProfileRow,
|
||||
@@ -2479,6 +2789,8 @@ fn increment_puzzle_profile_play_count(
|
||||
play_count: row.play_count.saturating_add(1),
|
||||
remix_count: row.remix_count,
|
||||
like_count: row.like_count,
|
||||
point_incentive_total_half_points: row.point_incentive_total_half_points,
|
||||
point_incentive_claimed_points: row.point_incentive_claimed_points,
|
||||
anchor_pack_json: row.anchor_pack_json.clone(),
|
||||
publish_ready: row.publish_ready,
|
||||
created_at: row.created_at,
|
||||
@@ -2841,7 +3153,7 @@ mod tests {
|
||||
}];
|
||||
|
||||
replace_generated_candidate(
|
||||
&mut draft,
|
||||
&mut draft.candidates,
|
||||
vec![PuzzleGeneratedImageCandidate {
|
||||
candidate_id: "session-1-candidate-2".to_string(),
|
||||
image_src: "/generated-puzzle-assets/session-1/new/cover.png".to_string(),
|
||||
@@ -2866,11 +3178,14 @@ mod tests {
|
||||
owner_user_id: "owner-a".to_string(),
|
||||
source_session_id: None,
|
||||
author_display_name: "作者".to_string(),
|
||||
work_title: "A".to_string(),
|
||||
work_description: String::new(),
|
||||
level_name: "A".to_string(),
|
||||
summary: String::new(),
|
||||
theme_tags: vec!["雨夜".to_string(), "猫咪".to_string()],
|
||||
cover_image_src: Some("/a.png".to_string()),
|
||||
cover_asset_id: Some("asset-a".to_string()),
|
||||
levels: Vec::new(),
|
||||
publication_status: PuzzlePublicationStatus::Published,
|
||||
updated_at_micros: 1,
|
||||
published_at_micros: Some(1),
|
||||
@@ -2878,6 +3193,8 @@ mod tests {
|
||||
recent_play_count_7d: 0,
|
||||
remix_count: 0,
|
||||
like_count: 0,
|
||||
point_incentive_total_half_points: 0,
|
||||
point_incentive_claimed_points: 0,
|
||||
publish_ready: true,
|
||||
anchor_pack: empty_anchor_pack(),
|
||||
};
|
||||
@@ -2885,10 +3202,13 @@ mod tests {
|
||||
owner_user_id: "owner-a".to_string(),
|
||||
profile_id: "profile-b".to_string(),
|
||||
work_id: "work-b".to_string(),
|
||||
work_title: "B".to_string(),
|
||||
work_description: String::new(),
|
||||
level_name: "B".to_string(),
|
||||
theme_tags: vec!["雨夜".to_string(), "蒸汽城市".to_string()],
|
||||
cover_image_src: Some("/b.png".to_string()),
|
||||
cover_asset_id: Some("asset-b".to_string()),
|
||||
levels: Vec::new(),
|
||||
publication_status: PuzzlePublicationStatus::Published,
|
||||
updated_at_micros: 2,
|
||||
published_at_micros: Some(2),
|
||||
@@ -2896,6 +3216,8 @@ mod tests {
|
||||
recent_play_count_7d: 0,
|
||||
remix_count: 0,
|
||||
like_count: 0,
|
||||
point_incentive_total_half_points: 0,
|
||||
point_incentive_claimed_points: 0,
|
||||
publish_ready: true,
|
||||
anchor_pack: empty_anchor_pack(),
|
||||
source_session_id: None,
|
||||
|
||||
@@ -2120,6 +2120,24 @@ fn apply_profile_wallet_delta(
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn grant_profile_wallet_points(
|
||||
ctx: &ReducerContext,
|
||||
user_id: &str,
|
||||
amount_delta: u64,
|
||||
source_type: RuntimeProfileWalletLedgerSourceType,
|
||||
ledger_id: &str,
|
||||
created_at: Timestamp,
|
||||
) -> Result<u64, String> {
|
||||
apply_profile_wallet_delta(
|
||||
ctx,
|
||||
user_id,
|
||||
amount_delta,
|
||||
source_type,
|
||||
ledger_id,
|
||||
created_at,
|
||||
)
|
||||
}
|
||||
|
||||
fn apply_profile_wallet_adjustment(
|
||||
ctx: &ReducerContext,
|
||||
input: RuntimeProfileWalletAdjustmentInput,
|
||||
|
||||
Reference in New Issue
Block a user