feat: wire bark battle platform loop
Some checks are pending
CI / verify (pull_request) Waiting to run
Some checks are pending
CI / verify (pull_request) Waiting to run
This commit is contained in:
@@ -16,6 +16,7 @@ module-ai = { workspace = true }
|
||||
module-assets = { workspace = true, features = ["server-service"] }
|
||||
module-auth = { workspace = true }
|
||||
module-big-fish = { workspace = true }
|
||||
module-bark-battle = { workspace = true }
|
||||
module-combat = { workspace = true }
|
||||
module-creative-agent = { workspace = true }
|
||||
module-custom-world = { workspace = true }
|
||||
|
||||
@@ -34,6 +34,10 @@ use crate::{
|
||||
auth_me::auth_me,
|
||||
auth_public_user::{get_public_user_by_code, get_public_user_by_id},
|
||||
auth_sessions::auth_sessions,
|
||||
bark_battle::{
|
||||
create_bark_battle_draft, finish_bark_battle_run, get_bark_battle_run,
|
||||
get_bark_battle_runtime_config, publish_bark_battle_work, start_bark_battle_run,
|
||||
},
|
||||
big_fish::{
|
||||
create_big_fish_session, delete_big_fish_work, execute_big_fish_action, get_big_fish_run,
|
||||
get_big_fish_session, get_big_fish_works, list_big_fish_gallery,
|
||||
@@ -1001,6 +1005,48 @@ pub fn build_router(state: AppState) -> Router {
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/bark-battle/drafts",
|
||||
post(create_bark_battle_draft).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/bark-battle/works/publish",
|
||||
post(publish_bark_battle_work).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/bark-battle/works/{work_id}/config",
|
||||
get(get_bark_battle_runtime_config).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/bark-battle/works/{work_id}/runs",
|
||||
post(start_bark_battle_run).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/bark-battle/runs/{run_id}",
|
||||
get(get_bark_battle_run).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/bark-battle/runs/{run_id}/finish",
|
||||
post(finish_bark_battle_run).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/square-hole/sessions",
|
||||
post(create_square_hole_agent_session).route_layer(middleware::from_fn_with_state(
|
||||
|
||||
776
server-rs/crates/api-server/src/bark_battle.rs
Normal file
776
server-rs/crates/api-server/src/bark_battle.rs
Normal file
@@ -0,0 +1,776 @@
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Extension, Path, State, rejection::JsonRejection},
|
||||
http::{HeaderName, StatusCode, header},
|
||||
response::Response,
|
||||
};
|
||||
use module_bark_battle::{BARK_BATTLE_RULESET_VERSION_V1, BarkBattleRuleset};
|
||||
use serde::Deserialize;
|
||||
use serde_json::{Value, json};
|
||||
use shared_contracts::bark_battle::{
|
||||
BarkBattleConfigEditorPayload, BarkBattleDerivedMetrics, BarkBattleDifficultyPreset,
|
||||
BarkBattleDraftConfig, BarkBattleDraftCreateRequest, BarkBattleFinishStatus,
|
||||
BarkBattlePublishedConfig, BarkBattleRunFinishRequest, BarkBattleRunFinishResponse,
|
||||
BarkBattleRunStartRequest, BarkBattleRunStartResponse, BarkBattleScoreSummary,
|
||||
BarkBattleServerResult, BarkBattleWorkPublishRequest,
|
||||
};
|
||||
use shared_kernel::{
|
||||
build_prefixed_uuid_id, format_rfc3339, format_timestamp_micros,
|
||||
offset_datetime_to_unix_micros, parse_rfc3339,
|
||||
};
|
||||
use spacetime_client::{
|
||||
BarkBattleDraftCreateRecordInput, BarkBattleRunFinishRecordInput, BarkBattleRunRecord,
|
||||
BarkBattleRunStartRecordInput, BarkBattleWorkPublishRecordInput, SpacetimeClientError,
|
||||
};
|
||||
use time::{Duration as TimeDuration, OffsetDateTime};
|
||||
|
||||
use crate::{
|
||||
api_response::json_success_body,
|
||||
auth::AuthenticatedAccessToken,
|
||||
http_error::AppError,
|
||||
request_context::RequestContext,
|
||||
state::AppState,
|
||||
work_play_tracking::{WorkPlayTrackingDraft, record_work_play_start_after_success},
|
||||
};
|
||||
|
||||
const BARK_BATTLE_RUNTIME_PROVIDER: &str = "bark-battle-runtime";
|
||||
const BARK_BATTLE_DRAFT_ID_PREFIX: &str = "bark-battle-draft-";
|
||||
const BARK_BATTLE_WORK_ID_PREFIX: &str = "bark-battle-work-";
|
||||
const BARK_BATTLE_RUN_ID_PREFIX: &str = "bark-battle-run-";
|
||||
const BARK_BATTLE_RUN_TOKEN_PREFIX: &str = "bark-battle-token-";
|
||||
const BARK_BATTLE_PLAY_TYPE_ID: &str = "bark-battle";
|
||||
const BARK_BATTLE_RUN_TTL_SECONDS: i64 = 10 * 60;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct BarkBattleRunSnapshotRecord {
|
||||
run_id: String,
|
||||
work_id: String,
|
||||
config_version: u64,
|
||||
ruleset_version: String,
|
||||
difficulty_preset: String,
|
||||
#[serde(default)]
|
||||
client_started_at_micros: i64,
|
||||
#[serde(default)]
|
||||
server_started_at_micros: i64,
|
||||
#[serde(default)]
|
||||
server_finished_at_micros: Option<i64>,
|
||||
#[serde(default)]
|
||||
metrics_json: String,
|
||||
#[serde(default)]
|
||||
server_result: Option<String>,
|
||||
#[serde(default)]
|
||||
validation_status: String,
|
||||
#[serde(default)]
|
||||
anti_cheat_flags_json: String,
|
||||
#[serde(default)]
|
||||
leaderboard_score: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct BarkBattleDraftConfigSnapshotRecord {
|
||||
draft_id: String,
|
||||
#[allow(dead_code)]
|
||||
work_id: String,
|
||||
#[allow(dead_code)]
|
||||
config_version: u64,
|
||||
#[allow(dead_code)]
|
||||
ruleset_version: String,
|
||||
#[serde(default)]
|
||||
config_json: String,
|
||||
updated_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct BarkBattleRuntimeConfigSnapshotRecord {
|
||||
work_id: String,
|
||||
source_draft_id: Option<String>,
|
||||
config_version: u64,
|
||||
ruleset_version: String,
|
||||
#[serde(default)]
|
||||
config_json: String,
|
||||
published_at_micros: i64,
|
||||
updated_at_micros: i64,
|
||||
}
|
||||
|
||||
pub async fn create_bark_battle_draft(
|
||||
State(state): State<AppState>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
Extension(authenticated): Extension<AuthenticatedAccessToken>,
|
||||
payload: Result<Json<BarkBattleDraftCreateRequest>, JsonRejection>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
let Json(payload) = bark_battle_json(payload, &request_context)?;
|
||||
let now = current_utc_micros();
|
||||
let draft = state
|
||||
.spacetime_client()
|
||||
.create_bark_battle_draft(BarkBattleDraftCreateRecordInput {
|
||||
draft_id: build_prefixed_uuid_id(BARK_BATTLE_DRAFT_ID_PREFIX),
|
||||
owner_user_id: authenticated.claims().user_id().to_string(),
|
||||
work_id: build_prefixed_uuid_id(BARK_BATTLE_WORK_ID_PREFIX),
|
||||
title: Some(payload.title),
|
||||
description: payload.description,
|
||||
theme_preset: payload.theme_preset,
|
||||
player_dog_skin_preset: payload.player_dog_skin_preset,
|
||||
opponent_dog_skin_preset: payload.opponent_dog_skin_preset,
|
||||
difficulty_preset: Some(
|
||||
difficulty_to_spacetime_string(&payload.difficulty_preset).to_string(),
|
||||
),
|
||||
leaderboard_enabled: Some(payload.leaderboard_enabled),
|
||||
editor_state_json: Some("{}".to_string()),
|
||||
created_at_micros: now,
|
||||
})
|
||||
.await
|
||||
.map_err(|error| {
|
||||
bark_battle_error_response(&request_context, map_bark_battle_client_error(error))
|
||||
})?;
|
||||
let draft = map_draft_config_record(draft, &request_context)?;
|
||||
Ok(json_success_body(Some(&request_context), draft))
|
||||
}
|
||||
|
||||
pub async fn publish_bark_battle_work(
|
||||
State(state): State<AppState>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
Extension(authenticated): Extension<AuthenticatedAccessToken>,
|
||||
payload: Result<Json<BarkBattleWorkPublishRequest>, JsonRejection>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
let Json(payload) = bark_battle_json(payload, &request_context)?;
|
||||
ensure_non_empty(&request_context, &payload.draft_id, "draftId")?;
|
||||
let work_id = payload
|
||||
.work_id
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(ToString::to_string)
|
||||
.unwrap_or_else(|| build_prefixed_uuid_id(BARK_BATTLE_WORK_ID_PREFIX));
|
||||
let published_snapshot_json = payload
|
||||
.published_snapshot
|
||||
.as_ref()
|
||||
.map(serde_json::to_string)
|
||||
.transpose()
|
||||
.map_err(|error| {
|
||||
bark_battle_error_response(
|
||||
&request_context,
|
||||
AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
|
||||
"provider": BARK_BATTLE_RUNTIME_PROVIDER,
|
||||
"message": format!("publishedSnapshot JSON 序列化失败: {error}"),
|
||||
})),
|
||||
)
|
||||
})?;
|
||||
let published = state
|
||||
.spacetime_client()
|
||||
.publish_bark_battle_work(BarkBattleWorkPublishRecordInput {
|
||||
draft_id: payload.draft_id,
|
||||
owner_user_id: authenticated.claims().user_id().to_string(),
|
||||
work_id,
|
||||
published_snapshot_json,
|
||||
published_at_micros: current_utc_micros(),
|
||||
})
|
||||
.await
|
||||
.map_err(|error| {
|
||||
bark_battle_error_response(&request_context, map_bark_battle_client_error(error))
|
||||
})?;
|
||||
let published = map_published_config_record(published, &request_context)?;
|
||||
Ok(json_success_body(Some(&request_context), published))
|
||||
}
|
||||
|
||||
pub async fn get_bark_battle_runtime_config(
|
||||
State(state): State<AppState>,
|
||||
Path(work_id): Path<String>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
Extension(authenticated): Extension<AuthenticatedAccessToken>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
ensure_non_empty(&request_context, &work_id, "workId")?;
|
||||
|
||||
let config = state
|
||||
.spacetime_client()
|
||||
.get_bark_battle_runtime_config(work_id, Some(authenticated.claims().user_id().to_string()))
|
||||
.await
|
||||
.map_err(|error| {
|
||||
bark_battle_error_response(&request_context, map_bark_battle_client_error(error))
|
||||
})?;
|
||||
let config = map_runtime_config_record(config, &request_context)?;
|
||||
|
||||
Ok(json_success_body(Some(&request_context), config))
|
||||
}
|
||||
|
||||
pub async fn start_bark_battle_run(
|
||||
State(state): State<AppState>,
|
||||
Path(work_id): Path<String>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
Extension(authenticated): Extension<AuthenticatedAccessToken>,
|
||||
payload: Result<Json<BarkBattleRunStartRequest>, JsonRejection>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
let maybe_payload = payload.ok().map(|Json(payload)| payload);
|
||||
let request = maybe_payload.unwrap_or_else(|| BarkBattleRunStartRequest {
|
||||
work_id: work_id.clone(),
|
||||
config_version: None,
|
||||
source_route: None,
|
||||
client_runtime_version: None,
|
||||
});
|
||||
let work_id = if request.work_id.trim().is_empty() {
|
||||
work_id
|
||||
} else {
|
||||
request.work_id.trim().to_string()
|
||||
};
|
||||
ensure_non_empty(&request_context, &work_id, "workId")?;
|
||||
|
||||
let owner_user_id = authenticated.claims().user_id().to_string();
|
||||
let runtime_config = state
|
||||
.spacetime_client()
|
||||
.get_bark_battle_runtime_config(work_id.clone(), Some(owner_user_id.clone()))
|
||||
.await
|
||||
.map_err(|error| {
|
||||
bark_battle_error_response(&request_context, map_bark_battle_client_error(error))
|
||||
})?;
|
||||
let runtime_config = map_runtime_config_record(runtime_config, &request_context)?;
|
||||
if !request.work_id.trim().is_empty() && request.work_id.trim() != work_id {
|
||||
return Err(bark_battle_bad_request(
|
||||
&request_context,
|
||||
"workId 与路径参数不一致",
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(expected_version) = request.config_version {
|
||||
if expected_version != runtime_config.config_version {
|
||||
return Err(bark_battle_bad_request(
|
||||
&request_context,
|
||||
"configVersion 与已发布配置不一致",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let client_started_at_micros = current_utc_micros();
|
||||
let run_token = build_prefixed_uuid_id(BARK_BATTLE_RUN_TOKEN_PREFIX);
|
||||
let run = state
|
||||
.spacetime_client()
|
||||
.start_bark_battle_run(BarkBattleRunStartRecordInput {
|
||||
run_id: build_prefixed_uuid_id(BARK_BATTLE_RUN_ID_PREFIX),
|
||||
run_token: run_token.clone(),
|
||||
owner_user_id: owner_user_id.clone(),
|
||||
work_id: work_id.clone(),
|
||||
config_version: u64::from(runtime_config.config_version),
|
||||
ruleset_version: runtime_config.ruleset_version.clone(),
|
||||
difficulty_preset: difficulty_to_spacetime_string(&runtime_config.difficulty_preset)
|
||||
.to_string(),
|
||||
client_started_at_micros,
|
||||
server_started_at_micros: client_started_at_micros,
|
||||
})
|
||||
.await
|
||||
.map_err(|error| {
|
||||
bark_battle_error_response(&request_context, map_bark_battle_client_error(error))
|
||||
})?;
|
||||
let run_snapshot = parse_run_record(run, &request_context)?;
|
||||
|
||||
record_work_play_start_after_success(
|
||||
&state,
|
||||
&request_context,
|
||||
WorkPlayTrackingDraft::new(
|
||||
BARK_BATTLE_PLAY_TYPE_ID,
|
||||
work_id.clone(),
|
||||
&authenticated,
|
||||
"/api/runtime/bark-battle/...",
|
||||
)
|
||||
.extra(json!({
|
||||
"runId": run_snapshot.run_id,
|
||||
"workId": work_id,
|
||||
"configVersion": runtime_config.config_version,
|
||||
"rulesetVersion": runtime_config.ruleset_version,
|
||||
"difficultyPreset": runtime_config.difficulty_preset,
|
||||
"sourceRoute": request.source_route,
|
||||
"clientRuntimeVersion": request.client_runtime_version,
|
||||
})),
|
||||
)
|
||||
.await;
|
||||
|
||||
let server_started_at = format_timestamp_micros(run_snapshot.server_started_at_micros);
|
||||
let expires_at = format_timestamp_micros(
|
||||
run_snapshot
|
||||
.server_started_at_micros
|
||||
.saturating_add(BARK_BATTLE_RUN_TTL_SECONDS * 1_000_000),
|
||||
);
|
||||
|
||||
Ok(json_success_body(
|
||||
Some(&request_context),
|
||||
BarkBattleRunStartResponse {
|
||||
run_id: run_snapshot.run_id,
|
||||
run_token,
|
||||
work_id: run_snapshot.work_id,
|
||||
config_version: runtime_config.config_version,
|
||||
ruleset_version: runtime_config.ruleset_version.clone(),
|
||||
difficulty_preset: runtime_config.difficulty_preset.clone(),
|
||||
runtime_config,
|
||||
server_started_at,
|
||||
expires_at,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn get_bark_battle_run(
|
||||
State(state): State<AppState>,
|
||||
Path(run_id): Path<String>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
Extension(authenticated): Extension<AuthenticatedAccessToken>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
ensure_non_empty(&request_context, &run_id, "runId")?;
|
||||
let run = state
|
||||
.spacetime_client()
|
||||
.get_bark_battle_run(run_id, authenticated.claims().user_id().to_string())
|
||||
.await
|
||||
.map_err(|error| {
|
||||
bark_battle_error_response(&request_context, map_bark_battle_client_error(error))
|
||||
})?;
|
||||
let run = parse_run_record(run, &request_context)?;
|
||||
|
||||
Ok(json_success_body(Some(&request_context), run))
|
||||
}
|
||||
|
||||
pub async fn finish_bark_battle_run(
|
||||
State(state): State<AppState>,
|
||||
Path(run_id): Path<String>,
|
||||
Extension(request_context): Extension<RequestContext>,
|
||||
Extension(authenticated): Extension<AuthenticatedAccessToken>,
|
||||
payload: Result<Json<BarkBattleRunFinishRequest>, JsonRejection>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
let Json(payload) = bark_battle_json(payload, &request_context)?;
|
||||
ensure_non_empty(&request_context, &run_id, "runId")?;
|
||||
ensure_non_empty(&request_context, &payload.work_id, "workId")?;
|
||||
ensure_non_empty(&request_context, &payload.run_token, "runToken")?;
|
||||
if payload.run_id != run_id {
|
||||
return Err(bark_battle_bad_request(
|
||||
&request_context,
|
||||
"runId 与路径参数不一致",
|
||||
));
|
||||
}
|
||||
if payload.ruleset_version != BARK_BATTLE_RULESET_VERSION_V1 {
|
||||
return Err(bark_battle_bad_request(
|
||||
&request_context,
|
||||
"rulesetVersion 不支持",
|
||||
));
|
||||
}
|
||||
|
||||
let client_finished_at_micros = parse_client_time_to_micros(&payload.client_finished_at)
|
||||
.map_err(|message| bark_battle_bad_request(&request_context, &message))?;
|
||||
let derived = &payload.derived_metrics;
|
||||
let opponent_final_energy = derive_server_opponent_final_energy(derived);
|
||||
let metrics_json = serde_json::to_string(&json!({
|
||||
"clientStartedAt": payload.client_started_at,
|
||||
"clientFinishedAt": payload.client_finished_at,
|
||||
"durationMs": payload.duration_ms,
|
||||
"derivedMetrics": payload.derived_metrics,
|
||||
"clientResult": payload.client_result,
|
||||
"sampleDigest": payload.sample_digest,
|
||||
"clientRuntimeVersion": payload.client_runtime_version,
|
||||
}))
|
||||
.unwrap_or_else(|_| "{}".to_string());
|
||||
let derived_metrics_json = serde_json::to_string(derived).unwrap_or_else(|_| "{}".to_string());
|
||||
|
||||
let run = state
|
||||
.spacetime_client()
|
||||
.finish_bark_battle_run(BarkBattleRunFinishRecordInput {
|
||||
run_id,
|
||||
run_token: payload.run_token,
|
||||
owner_user_id: authenticated.claims().user_id().to_string(),
|
||||
work_id: payload.work_id.clone(),
|
||||
config_version: u64::from(payload.config_version),
|
||||
ruleset_version: payload.ruleset_version.clone(),
|
||||
difficulty_preset: difficulty_to_spacetime_string(&payload.difficulty_preset)
|
||||
.to_string(),
|
||||
client_finished_at_micros,
|
||||
server_finished_at_micros: current_utc_micros(),
|
||||
duration_ms: payload.duration_ms,
|
||||
trigger_count: u64::from(derived.trigger_count),
|
||||
max_volume_millis: unit_to_millis(derived.max_volume),
|
||||
average_volume_millis: unit_to_millis(derived.average_volume),
|
||||
final_energy_millis: energy_to_millis(derived.final_energy),
|
||||
opponent_final_energy_millis: energy_to_millis(opponent_final_energy),
|
||||
max_combo: derived.combo_max,
|
||||
metrics_json,
|
||||
derived_metrics_json,
|
||||
})
|
||||
.await
|
||||
.map_err(|error| {
|
||||
bark_battle_error_response(&request_context, map_bark_battle_client_error(error))
|
||||
})?;
|
||||
let run = parse_run_record(run, &request_context)?;
|
||||
|
||||
Ok(json_success_body(
|
||||
Some(&request_context),
|
||||
map_finish_response(run, &payload.derived_metrics),
|
||||
))
|
||||
}
|
||||
|
||||
fn map_finish_response(
|
||||
run: BarkBattleRunSnapshotRecord,
|
||||
fallback_metrics: &BarkBattleDerivedMetrics,
|
||||
) -> BarkBattleRunFinishResponse {
|
||||
let score_summary =
|
||||
parse_score_summary(&run.metrics_json).unwrap_or_else(|| BarkBattleScoreSummary {
|
||||
duration_ms: 0,
|
||||
trigger_count: fallback_metrics.trigger_count,
|
||||
max_volume: fallback_metrics.max_volume,
|
||||
average_volume: fallback_metrics.average_volume,
|
||||
final_energy: fallback_metrics.final_energy,
|
||||
combo_max: fallback_metrics.combo_max,
|
||||
});
|
||||
BarkBattleRunFinishResponse {
|
||||
status: parse_finish_status(&run.validation_status),
|
||||
run_id: run.run_id,
|
||||
work_id: run.work_id,
|
||||
config_version: run.config_version.min(u64::from(u32::MAX)) as u32,
|
||||
ruleset_version: run.ruleset_version,
|
||||
difficulty_preset: parse_difficulty_lossy(&run.difficulty_preset),
|
||||
server_result: parse_server_result_lossy(run.server_result.as_deref()),
|
||||
score_summary,
|
||||
leaderboard_score: run.leaderboard_score,
|
||||
anti_cheat_flags: parse_string_vec(&run.anti_cheat_flags_json),
|
||||
updated_at: format_timestamp_micros(
|
||||
run.server_finished_at_micros
|
||||
.unwrap_or(run.server_started_at_micros),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_run_record(
|
||||
value: BarkBattleRunRecord,
|
||||
request_context: &RequestContext,
|
||||
) -> Result<BarkBattleRunSnapshotRecord, Response> {
|
||||
serde_json::from_value(value).map_err(|error| {
|
||||
bark_battle_error_response(
|
||||
request_context,
|
||||
AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
|
||||
"provider": BARK_BATTLE_RUNTIME_PROVIDER,
|
||||
"message": format!("Bark Battle run JSON 解析失败: {error}"),
|
||||
})),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_draft_snapshot_record(
|
||||
value: Value,
|
||||
request_context: &RequestContext,
|
||||
) -> Result<BarkBattleDraftConfigSnapshotRecord, Response> {
|
||||
serde_json::from_value(value)
|
||||
.map_err(|error| bark_battle_snapshot_parse_error(request_context, "draft config", error))
|
||||
}
|
||||
|
||||
fn parse_runtime_snapshot_record(
|
||||
value: Value,
|
||||
request_context: &RequestContext,
|
||||
) -> Result<BarkBattleRuntimeConfigSnapshotRecord, Response> {
|
||||
serde_json::from_value(value)
|
||||
.map_err(|error| bark_battle_snapshot_parse_error(request_context, "runtime config", error))
|
||||
}
|
||||
|
||||
fn map_draft_config_record(
|
||||
value: Value,
|
||||
request_context: &RequestContext,
|
||||
) -> Result<BarkBattleDraftConfig, Response> {
|
||||
let snapshot = parse_draft_snapshot_record(value, request_context)?;
|
||||
let editor_config = parse_editor_config_record(&snapshot.config_json, request_context)?;
|
||||
Ok(BarkBattleDraftConfig {
|
||||
draft_id: snapshot.draft_id,
|
||||
title: editor_config.title,
|
||||
description: editor_config.description,
|
||||
theme_preset: editor_config.theme_preset,
|
||||
player_dog_skin_preset: editor_config.player_dog_skin_preset,
|
||||
opponent_dog_skin_preset: editor_config.opponent_dog_skin_preset,
|
||||
difficulty_preset: editor_config.difficulty_preset,
|
||||
leaderboard_enabled: editor_config.leaderboard_enabled,
|
||||
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||
})
|
||||
}
|
||||
|
||||
fn map_runtime_config_record(
|
||||
value: Value,
|
||||
request_context: &RequestContext,
|
||||
) -> Result<shared_contracts::bark_battle::BarkBattleRuntimeConfig, Response> {
|
||||
let snapshot = parse_runtime_snapshot_record(value, request_context)?;
|
||||
let editor_config = parse_editor_config_record(&snapshot.config_json, request_context)?;
|
||||
let ruleset = BarkBattleRuleset::v1();
|
||||
Ok(shared_contracts::bark_battle::BarkBattleRuntimeConfig {
|
||||
work_id: snapshot.work_id,
|
||||
config_version: snapshot.config_version.min(u64::from(u32::MAX)) as u32,
|
||||
ruleset_version: snapshot.ruleset_version,
|
||||
play_type_id: BARK_BATTLE_PLAY_TYPE_ID.to_string(),
|
||||
duration_ms: ruleset.standard_duration_ms,
|
||||
energy_min: 0.0,
|
||||
energy_max: 100.0,
|
||||
draw_threshold: ruleset.draw_threshold_energy as f32,
|
||||
min_bark_gap_ms: ruleset.min_bark_gap_ms,
|
||||
difficulty_preset: editor_config.difficulty_preset,
|
||||
theme_preset: editor_config.theme_preset,
|
||||
player_dog_skin_preset: editor_config.player_dog_skin_preset,
|
||||
opponent_dog_skin_preset: editor_config.opponent_dog_skin_preset,
|
||||
leaderboard_enabled: editor_config.leaderboard_enabled,
|
||||
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||
})
|
||||
}
|
||||
|
||||
fn map_published_config_record(
|
||||
value: Value,
|
||||
request_context: &RequestContext,
|
||||
) -> Result<BarkBattlePublishedConfig, Response> {
|
||||
let snapshot = parse_runtime_snapshot_record(value, request_context)?;
|
||||
let editor_config = parse_editor_config_record(&snapshot.config_json, request_context)?;
|
||||
Ok(BarkBattlePublishedConfig {
|
||||
work_id: snapshot.work_id,
|
||||
draft_id: snapshot.source_draft_id,
|
||||
config_version: snapshot.config_version.min(u64::from(u32::MAX)) as u32,
|
||||
ruleset_version: snapshot.ruleset_version,
|
||||
play_type_id: BARK_BATTLE_PLAY_TYPE_ID.to_string(),
|
||||
title: editor_config.title,
|
||||
description: editor_config.description,
|
||||
theme_preset: editor_config.theme_preset,
|
||||
player_dog_skin_preset: editor_config.player_dog_skin_preset,
|
||||
opponent_dog_skin_preset: editor_config.opponent_dog_skin_preset,
|
||||
difficulty_preset: editor_config.difficulty_preset,
|
||||
leaderboard_enabled: editor_config.leaderboard_enabled,
|
||||
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||
published_at: format_timestamp_micros(snapshot.published_at_micros),
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_editor_config_record(
|
||||
config_json: &str,
|
||||
request_context: &RequestContext,
|
||||
) -> Result<BarkBattleConfigEditorPayload, Response> {
|
||||
serde_json::from_str(config_json).map_err(|error| {
|
||||
bark_battle_error_response(
|
||||
request_context,
|
||||
AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
|
||||
"provider": BARK_BATTLE_RUNTIME_PROVIDER,
|
||||
"message": format!("Bark Battle configJson 解析失败: {error}"),
|
||||
})),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn bark_battle_snapshot_parse_error(
|
||||
request_context: &RequestContext,
|
||||
label: &str,
|
||||
error: serde_json::Error,
|
||||
) -> Response {
|
||||
bark_battle_error_response(
|
||||
request_context,
|
||||
AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
|
||||
"provider": BARK_BATTLE_RUNTIME_PROVIDER,
|
||||
"message": format!("Bark Battle {label} JSON 解析失败: {error}"),
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
fn bark_battle_json<T>(
|
||||
payload: Result<Json<T>, JsonRejection>,
|
||||
request_context: &RequestContext,
|
||||
) -> Result<Json<T>, Response> {
|
||||
payload.map_err(|error| {
|
||||
bark_battle_error_response(
|
||||
request_context,
|
||||
AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
|
||||
"provider": BARK_BATTLE_RUNTIME_PROVIDER,
|
||||
"message": error.body_text(),
|
||||
})),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn ensure_non_empty(
|
||||
request_context: &RequestContext,
|
||||
value: &str,
|
||||
field_name: &str,
|
||||
) -> Result<(), Response> {
|
||||
if value.trim().is_empty() {
|
||||
return Err(bark_battle_bad_request(
|
||||
request_context,
|
||||
&format!("{field_name} is required"),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn bark_battle_bad_request(request_context: &RequestContext, message: &str) -> Response {
|
||||
bark_battle_error_response(
|
||||
request_context,
|
||||
AppError::from_status(StatusCode::BAD_REQUEST).with_details(json!({
|
||||
"provider": BARK_BATTLE_RUNTIME_PROVIDER,
|
||||
"message": message,
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
fn map_bark_battle_client_error(error: SpacetimeClientError) -> AppError {
|
||||
let status = match &error {
|
||||
SpacetimeClientError::Runtime(_) => StatusCode::BAD_REQUEST,
|
||||
SpacetimeClientError::Procedure(message)
|
||||
if message.contains("不存在")
|
||||
|| message.contains("not found")
|
||||
|| message.contains("does not exist") =>
|
||||
{
|
||||
StatusCode::NOT_FOUND
|
||||
}
|
||||
SpacetimeClientError::Procedure(message)
|
||||
if message.contains("不能为空")
|
||||
|| message.contains("不匹配")
|
||||
|| message.contains("不支持")
|
||||
|| message.contains("已结束")
|
||||
|| message.contains("已存在") =>
|
||||
{
|
||||
StatusCode::BAD_REQUEST
|
||||
}
|
||||
_ => StatusCode::BAD_GATEWAY,
|
||||
};
|
||||
|
||||
AppError::from_status(status).with_details(json!({
|
||||
"provider": "spacetimedb",
|
||||
"message": error.to_string(),
|
||||
}))
|
||||
}
|
||||
|
||||
fn bark_battle_error_response(request_context: &RequestContext, error: AppError) -> Response {
|
||||
let mut response = error.into_response_with_context(Some(request_context));
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("x-genarrative-provider"),
|
||||
header::HeaderValue::from_static(BARK_BATTLE_RUNTIME_PROVIDER),
|
||||
);
|
||||
response
|
||||
}
|
||||
|
||||
fn parse_client_time_to_micros(value: &str) -> Result<i64, String> {
|
||||
let trimmed = value.trim();
|
||||
if trimmed.is_empty() {
|
||||
return Err("client timestamp is required".to_string());
|
||||
}
|
||||
if let Ok(micros) = trimmed.parse::<i64>() {
|
||||
return Ok(micros);
|
||||
}
|
||||
parse_rfc3339(trimmed).map(offset_datetime_to_unix_micros)
|
||||
}
|
||||
|
||||
fn current_utc_micros() -> i64 {
|
||||
let duration = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default();
|
||||
(duration.as_secs() as i64) * 1_000_000 + i64::from(duration.subsec_micros())
|
||||
}
|
||||
|
||||
fn unit_to_millis(value: f32) -> u32 {
|
||||
(value.clamp(0.0, 1.0) * 1_000.0).round() as u32
|
||||
}
|
||||
|
||||
fn energy_to_millis(value: f32) -> u32 {
|
||||
(value.clamp(0.0, 100.0) * 1_000.0).round() as u32
|
||||
}
|
||||
|
||||
fn derive_server_opponent_final_energy(metrics: &BarkBattleDerivedMetrics) -> f32 {
|
||||
let ruleset = BarkBattleRuleset::v1();
|
||||
let pressure = (metrics.average_volume * 24.0)
|
||||
+ (metrics.max_volume * 16.0)
|
||||
+ (metrics.trigger_count as f32 * 0.35)
|
||||
+ (metrics.combo_max as f32 * 0.2);
|
||||
(ruleset.max_final_energy - pressure).clamp(ruleset.min_final_energy, ruleset.max_final_energy)
|
||||
}
|
||||
|
||||
fn difficulty_to_spacetime_string(value: &BarkBattleDifficultyPreset) -> &'static str {
|
||||
match value {
|
||||
BarkBattleDifficultyPreset::Easy => "easy",
|
||||
BarkBattleDifficultyPreset::Normal => "normal",
|
||||
BarkBattleDifficultyPreset::Hard => "hard",
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_difficulty(value: &str) -> Result<BarkBattleDifficultyPreset, AppError> {
|
||||
match value {
|
||||
"easy" => Ok(BarkBattleDifficultyPreset::Easy),
|
||||
"normal" => Ok(BarkBattleDifficultyPreset::Normal),
|
||||
"hard" => Ok(BarkBattleDifficultyPreset::Hard),
|
||||
_ => Err(
|
||||
AppError::from_status(StatusCode::BAD_GATEWAY).with_details(json!({
|
||||
"provider": BARK_BATTLE_RUNTIME_PROVIDER,
|
||||
"message": format!("Bark Battle difficultyPreset 不支持: {value}"),
|
||||
})),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_difficulty_lossy(value: &str) -> BarkBattleDifficultyPreset {
|
||||
parse_difficulty(value).unwrap_or(BarkBattleDifficultyPreset::Normal)
|
||||
}
|
||||
|
||||
fn parse_finish_status(value: &str) -> BarkBattleFinishStatus {
|
||||
match value {
|
||||
"accepted" => BarkBattleFinishStatus::Accepted,
|
||||
"accepted_with_flags" => BarkBattleFinishStatus::AcceptedWithFlags,
|
||||
"rejected" => BarkBattleFinishStatus::Rejected,
|
||||
_ => BarkBattleFinishStatus::Rejected,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_server_result_lossy(value: Option<&str>) -> BarkBattleServerResult {
|
||||
match value {
|
||||
Some("player_win") => BarkBattleServerResult::PlayerWin,
|
||||
Some("opponent_win") => BarkBattleServerResult::OpponentWin,
|
||||
Some("draw") => BarkBattleServerResult::Draw,
|
||||
_ => BarkBattleServerResult::Draw,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_score_summary(metrics_json: &str) -> Option<BarkBattleScoreSummary> {
|
||||
let value: Value = serde_json::from_str(metrics_json).ok()?;
|
||||
let derived = value.get("derivedMetrics")?;
|
||||
Some(BarkBattleScoreSummary {
|
||||
duration_ms: value.get("durationMs")?.as_u64()?,
|
||||
trigger_count: derived
|
||||
.get("triggerCount")?
|
||||
.as_u64()?
|
||||
.min(u64::from(u32::MAX)) as u32,
|
||||
max_volume: derived.get("maxVolume")?.as_f64()? as f32,
|
||||
average_volume: derived.get("averageVolume")?.as_f64()? as f32,
|
||||
final_energy: derived.get("finalEnergy")?.as_f64()? as f32,
|
||||
combo_max: derived.get("comboMax")?.as_u64()?.min(u64::from(u32::MAX)) as u32,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_string_vec(value: &str) -> Vec<String> {
|
||||
serde_json::from_str(value).unwrap_or_default()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn format_rfc3339_or_timestamp_micros(micros: i64) -> String {
|
||||
let seconds = micros.div_euclid(1_000_000);
|
||||
let subsec_micros = micros.rem_euclid(1_000_000);
|
||||
let Ok(value) = OffsetDateTime::from_unix_timestamp(seconds)
|
||||
.map(|value| value + TimeDuration::microseconds(subsec_micros))
|
||||
else {
|
||||
return format_timestamp_micros(micros);
|
||||
};
|
||||
format_rfc3339(value).unwrap_or_else(|_| format_timestamp_micros(micros))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn unit_and_energy_are_clamped_to_spacetime_millis() {
|
||||
assert_eq!(unit_to_millis(0.625), 625);
|
||||
assert_eq!(unit_to_millis(3.0), 1000);
|
||||
assert_eq!(energy_to_millis(88.456), 88_456);
|
||||
assert_eq!(energy_to_millis(120.0), 100_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_rfc3339_and_numeric_client_timestamps() {
|
||||
assert_eq!(
|
||||
parse_client_time_to_micros("1713686401234567").unwrap(),
|
||||
1_713_686_401_234_567
|
||||
);
|
||||
assert_eq!(
|
||||
parse_client_time_to_micros("2024-04-21T04:00:01.234567Z").unwrap(),
|
||||
1_713_672_001_234_567
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -78,6 +78,9 @@ pub fn resolve_creation_entry_route_id(path: &str) -> Option<&'static str> {
|
||||
if normalized.starts_with("/api/runtime/match3d") {
|
||||
return Some("match3d");
|
||||
}
|
||||
if normalized.starts_with("/api/runtime/bark-battle") {
|
||||
return Some("bark-battle");
|
||||
}
|
||||
if normalized.starts_with("/api/runtime/square-hole") {
|
||||
return Some("square-hole");
|
||||
}
|
||||
@@ -117,6 +120,7 @@ pub(crate) fn test_creation_entry_config_response()
|
||||
test_creation_type("big-fish", false, true, 20),
|
||||
test_creation_type("puzzle", true, true, 30),
|
||||
test_creation_type("match3d", true, true, 40),
|
||||
test_creation_type("bark-battle", true, true, 45),
|
||||
test_creation_type("square-hole", false, true, 50),
|
||||
test_creation_type("visual-novel", true, false, 60),
|
||||
test_creation_type("airp", true, false, 70),
|
||||
@@ -172,6 +176,10 @@ mod tests {
|
||||
resolve_creation_entry_route_id("/api/creation/visual-novel/sessions"),
|
||||
Some("visual-novel"),
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_creation_entry_route_id("/api/runtime/bark-battle/works/work-1/config"),
|
||||
Some("bark-battle"),
|
||||
);
|
||||
assert_eq!(resolve_creation_entry_route_id("/healthz"), None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ mod auth_payload;
|
||||
mod auth_public_user;
|
||||
mod auth_session;
|
||||
mod auth_sessions;
|
||||
mod bark_battle;
|
||||
mod big_fish;
|
||||
mod big_fish_agent_turn;
|
||||
mod big_fish_draft_compiler;
|
||||
|
||||
@@ -57,8 +57,8 @@ use spacetime_client::{
|
||||
PuzzleAgentMessageRecord, PuzzleAgentMessageSubmitRecordInput,
|
||||
PuzzleAgentSessionCreateRecordInput, PuzzleAgentSessionRecord,
|
||||
PuzzleAgentSuggestedActionRecord, PuzzleAnchorItemRecord, PuzzleAnchorPackRecord,
|
||||
PuzzleAudioAssetRecord, PuzzleCreatorIntentRecord, PuzzleDraftLevelRecord, PuzzleFormDraftRecord,
|
||||
PuzzleFormDraftSaveRecordInput, PuzzleGeneratedImageCandidateRecord,
|
||||
PuzzleAudioAssetRecord, PuzzleCreatorIntentRecord, PuzzleDraftLevelRecord,
|
||||
PuzzleFormDraftRecord, PuzzleFormDraftSaveRecordInput, PuzzleGeneratedImageCandidateRecord,
|
||||
PuzzleGeneratedImagesSaveRecordInput, PuzzleLeaderboardEntryRecord,
|
||||
PuzzleLeaderboardSubmitRecordInput, PuzzlePublishRecordInput, PuzzleRecommendedNextWorkRecord,
|
||||
PuzzleResultDraftRecord, PuzzleResultPreviewBlockerRecord, PuzzleResultPreviewFindingRecord,
|
||||
@@ -2061,7 +2061,9 @@ fn map_puzzle_draft_level_response(level: PuzzleDraftLevelRecord) -> PuzzleDraft
|
||||
level_name: level.level_name,
|
||||
picture_description: level.picture_description,
|
||||
picture_reference: level.picture_reference,
|
||||
background_music: level.background_music.map(map_puzzle_audio_asset_record_response),
|
||||
background_music: level
|
||||
.background_music
|
||||
.map(map_puzzle_audio_asset_record_response),
|
||||
candidates: level
|
||||
.candidates
|
||||
.into_iter()
|
||||
@@ -2667,7 +2669,9 @@ fn parse_puzzle_level_records_from_module_json(
|
||||
level_name: level.level_name,
|
||||
picture_description: level.picture_description,
|
||||
picture_reference: level.picture_reference,
|
||||
background_music: level.background_music.map(map_puzzle_audio_asset_domain_record),
|
||||
background_music: level
|
||||
.background_music
|
||||
.map(map_puzzle_audio_asset_domain_record),
|
||||
candidates: level
|
||||
.candidates
|
||||
.into_iter()
|
||||
@@ -4608,8 +4612,7 @@ mod tests {
|
||||
|
||||
let levels_json = serialize_puzzle_levels_response(&request_context, &[level])
|
||||
.expect("levels should serialize");
|
||||
let payload: Value =
|
||||
serde_json::from_str(&levels_json).expect("levels json should parse");
|
||||
let payload: Value = serde_json::from_str(&levels_json).expect("levels json should parse");
|
||||
assert_eq!(
|
||||
payload[0]["background_music"]["audio_src"],
|
||||
Value::String("/generated-puzzle-assets/audio.mp3".to_string())
|
||||
|
||||
14
server-rs/crates/module-bark-battle/Cargo.toml
Normal file
14
server-rs/crates/module-bark-battle/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "module-bark-battle"
|
||||
edition.workspace = true
|
||||
version.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = { workspace = true }
|
||||
162
server-rs/crates/module-bark-battle/src/domain.rs
Normal file
162
server-rs/crates/module-bark-battle/src/domain.rs
Normal file
@@ -0,0 +1,162 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const BARK_BATTLE_RULESET_VERSION_V1: &str = "bark-battle-ruleset-v1";
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DifficultyPreset {
|
||||
Easy,
|
||||
Normal,
|
||||
Hard,
|
||||
}
|
||||
|
||||
impl DifficultyPreset {
|
||||
pub fn ai_preset_key(self) -> &'static str {
|
||||
match self {
|
||||
Self::Easy => "bark-battle-ai-easy",
|
||||
Self::Normal => "bark-battle-ai-normal",
|
||||
Self::Hard => "bark-battle-ai-hard",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct RulesetThresholdsSignature {
|
||||
pub standard_duration_ms: u64,
|
||||
pub min_duration_ms: u64,
|
||||
pub max_duration_ms: u64,
|
||||
pub min_bark_gap_ms: u64,
|
||||
pub trigger_count_tolerance: u32,
|
||||
pub min_volume: f32,
|
||||
pub max_volume: f32,
|
||||
pub min_average_volume: f32,
|
||||
pub max_average_volume: f32,
|
||||
pub min_final_energy: f32,
|
||||
pub max_final_energy: f32,
|
||||
pub min_combo: u32,
|
||||
pub max_combo: u32,
|
||||
pub draw_threshold_energy: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct BarkBattleRuleset {
|
||||
pub version: &'static str,
|
||||
pub difficulty: DifficultyPreset,
|
||||
pub ai_preset_key: &'static str,
|
||||
pub standard_duration_ms: u64,
|
||||
pub min_duration_ms: u64,
|
||||
pub max_duration_ms: u64,
|
||||
pub min_bark_gap_ms: u64,
|
||||
pub trigger_count_tolerance: u32,
|
||||
pub min_volume: f32,
|
||||
pub max_volume: f32,
|
||||
pub min_average_volume: f32,
|
||||
pub max_average_volume: f32,
|
||||
pub min_final_energy: f32,
|
||||
pub max_final_energy: f32,
|
||||
pub min_combo: u32,
|
||||
pub max_combo: u32,
|
||||
pub draw_threshold_energy: u32,
|
||||
}
|
||||
|
||||
impl BarkBattleRuleset {
|
||||
pub fn v1() -> Self {
|
||||
Self::for_difficulty(DifficultyPreset::Normal)
|
||||
}
|
||||
|
||||
pub fn for_difficulty(difficulty: DifficultyPreset) -> Self {
|
||||
Self {
|
||||
version: BARK_BATTLE_RULESET_VERSION_V1,
|
||||
difficulty,
|
||||
ai_preset_key: difficulty.ai_preset_key(),
|
||||
standard_duration_ms: 30_000,
|
||||
min_duration_ms: 28_000,
|
||||
max_duration_ms: 35_000,
|
||||
min_bark_gap_ms: 250,
|
||||
trigger_count_tolerance: 2,
|
||||
min_volume: 0.0,
|
||||
max_volume: 1.0,
|
||||
min_average_volume: 0.0,
|
||||
max_average_volume: 1.0,
|
||||
min_final_energy: 0.0,
|
||||
max_final_energy: 100.0,
|
||||
min_combo: 0,
|
||||
max_combo: 999,
|
||||
draw_threshold_energy: 3,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn thresholds_signature(&self) -> RulesetThresholdsSignature {
|
||||
RulesetThresholdsSignature {
|
||||
standard_duration_ms: self.standard_duration_ms,
|
||||
min_duration_ms: self.min_duration_ms,
|
||||
max_duration_ms: self.max_duration_ms,
|
||||
min_bark_gap_ms: self.min_bark_gap_ms,
|
||||
trigger_count_tolerance: self.trigger_count_tolerance,
|
||||
min_volume: self.min_volume,
|
||||
max_volume: self.max_volume,
|
||||
min_average_volume: self.min_average_volume,
|
||||
max_average_volume: self.max_average_volume,
|
||||
min_final_energy: self.min_final_energy,
|
||||
max_final_energy: self.max_final_energy,
|
||||
min_combo: self.min_combo,
|
||||
max_combo: self.max_combo,
|
||||
draw_threshold_energy: self.draw_threshold_energy,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct BarkBattleFinishMetrics {
|
||||
pub duration_ms: u64,
|
||||
pub trigger_count: u64,
|
||||
/// 归一化音量,合法范围为 0.0..=1.0。
|
||||
pub max_volume: f32,
|
||||
pub average_volume: f32,
|
||||
pub final_energy: f32,
|
||||
pub max_combo: u32,
|
||||
pub finished_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum FinishValidationDecision {
|
||||
Accepted,
|
||||
AcceptedWithFlags,
|
||||
Rejected,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AntiCheatFlag {
|
||||
DurationTooShort,
|
||||
DurationTooLong,
|
||||
TriggerCountTooHigh,
|
||||
MaxVolumeOutOfRange,
|
||||
AverageVolumeOutOfRange,
|
||||
FinalEnergyOutOfRange,
|
||||
MaxComboOutOfRange,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FinishValidation {
|
||||
pub decision: FinishValidationDecision,
|
||||
pub anti_cheat_flags: Vec<AntiCheatFlag>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BattleResult {
|
||||
PlayerWin,
|
||||
OpponentWin,
|
||||
Draw,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct BarkBattleLeaderboardScore {
|
||||
pub final_energy_millis: u32,
|
||||
pub trigger_count: u64,
|
||||
pub max_volume_millis: u32,
|
||||
pub duration_closeness_ms: u64,
|
||||
pub finished_at_micros: i64,
|
||||
}
|
||||
5
server-rs/crates/module-bark-battle/src/lib.rs
Normal file
5
server-rs/crates/module-bark-battle/src/lib.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
pub mod domain;
|
||||
pub mod scoring;
|
||||
|
||||
pub use domain::*;
|
||||
pub use scoring::*;
|
||||
316
server-rs/crates/module-bark-battle/src/scoring.rs
Normal file
316
server-rs/crates/module-bark-battle/src/scoring.rs
Normal file
@@ -0,0 +1,316 @@
|
||||
use crate::domain::*;
|
||||
|
||||
pub fn validate_finish_metrics(
|
||||
ruleset: &BarkBattleRuleset,
|
||||
metrics: &BarkBattleFinishMetrics,
|
||||
) -> FinishValidation {
|
||||
let mut flags = Vec::new();
|
||||
let mut rejected = false;
|
||||
|
||||
if metrics.duration_ms < ruleset.min_duration_ms {
|
||||
flags.push(AntiCheatFlag::DurationTooShort);
|
||||
rejected = true;
|
||||
}
|
||||
if metrics.duration_ms > ruleset.max_duration_ms {
|
||||
flags.push(AntiCheatFlag::DurationTooLong);
|
||||
rejected = true;
|
||||
}
|
||||
|
||||
let max_trigger_count =
|
||||
metrics.duration_ms / ruleset.min_bark_gap_ms + u64::from(ruleset.trigger_count_tolerance);
|
||||
if metrics.trigger_count > max_trigger_count {
|
||||
flags.push(AntiCheatFlag::TriggerCountTooHigh);
|
||||
}
|
||||
|
||||
if !is_in_range(metrics.max_volume, ruleset.min_volume, ruleset.max_volume) {
|
||||
flags.push(AntiCheatFlag::MaxVolumeOutOfRange);
|
||||
rejected = true;
|
||||
}
|
||||
if !is_in_range(
|
||||
metrics.average_volume,
|
||||
ruleset.min_average_volume,
|
||||
ruleset.max_average_volume,
|
||||
) {
|
||||
flags.push(AntiCheatFlag::AverageVolumeOutOfRange);
|
||||
rejected = true;
|
||||
}
|
||||
if !is_in_range(
|
||||
metrics.final_energy,
|
||||
ruleset.min_final_energy,
|
||||
ruleset.max_final_energy,
|
||||
) {
|
||||
flags.push(AntiCheatFlag::FinalEnergyOutOfRange);
|
||||
rejected = true;
|
||||
}
|
||||
if metrics.max_combo < ruleset.min_combo || metrics.max_combo > ruleset.max_combo {
|
||||
flags.push(AntiCheatFlag::MaxComboOutOfRange);
|
||||
rejected = true;
|
||||
}
|
||||
|
||||
let decision = if rejected {
|
||||
FinishValidationDecision::Rejected
|
||||
} else if flags.is_empty() {
|
||||
FinishValidationDecision::Accepted
|
||||
} else {
|
||||
FinishValidationDecision::AcceptedWithFlags
|
||||
};
|
||||
|
||||
FinishValidation {
|
||||
decision,
|
||||
anti_cheat_flags: flags,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn adjudicate_result(
|
||||
ruleset: &BarkBattleRuleset,
|
||||
player_final_energy: f32,
|
||||
opponent_final_energy: f32,
|
||||
) -> BattleResult {
|
||||
let delta = player_final_energy - opponent_final_energy;
|
||||
if delta.abs() <= ruleset.draw_threshold_energy as f32 {
|
||||
BattleResult::Draw
|
||||
} else if delta > 0.0 {
|
||||
BattleResult::PlayerWin
|
||||
} else {
|
||||
BattleResult::OpponentWin
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_leaderboard_score(
|
||||
ruleset: &BarkBattleRuleset,
|
||||
metrics: &BarkBattleFinishMetrics,
|
||||
validation: &FinishValidation,
|
||||
result: BattleResult,
|
||||
) -> Option<BarkBattleLeaderboardScore> {
|
||||
if result != BattleResult::PlayerWin
|
||||
|| validation.decision == FinishValidationDecision::Rejected
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(BarkBattleLeaderboardScore {
|
||||
final_energy_millis: to_millis(metrics.final_energy),
|
||||
trigger_count: metrics.trigger_count,
|
||||
max_volume_millis: to_millis(metrics.max_volume),
|
||||
duration_closeness_ms: metrics.duration_ms.abs_diff(ruleset.standard_duration_ms),
|
||||
finished_at_micros: metrics.finished_at_micros,
|
||||
})
|
||||
}
|
||||
|
||||
fn is_in_range(value: f32, min: f32, max: f32) -> bool {
|
||||
value.is_finite() && value >= min && value <= max
|
||||
}
|
||||
|
||||
fn to_millis(value: f32) -> u32 {
|
||||
(value * 1_000.0).round().clamp(0.0, u32::MAX as f32) as u32
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::*;
|
||||
|
||||
fn metrics(duration_ms: u64) -> BarkBattleFinishMetrics {
|
||||
BarkBattleFinishMetrics {
|
||||
duration_ms,
|
||||
trigger_count: 10,
|
||||
max_volume: 0.8,
|
||||
average_volume: 0.6,
|
||||
final_energy: 60.0,
|
||||
max_combo: 5,
|
||||
finished_at_micros: 1_000_000,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_uses_contract_snake_case_for_domain_enums() {
|
||||
assert_eq!(
|
||||
serde_json::to_value(DifficultyPreset::Easy).expect("serialize difficulty"),
|
||||
serde_json::json!("easy")
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::to_value(FinishValidationDecision::AcceptedWithFlags)
|
||||
.expect("serialize decision"),
|
||||
serde_json::json!("accepted_with_flags")
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::to_value(AntiCheatFlag::AverageVolumeOutOfRange)
|
||||
.expect("serialize anti-cheat flag"),
|
||||
serde_json::json!("average_volume_out_of_range")
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::to_value(BattleResult::PlayerWin).expect("serialize battle result"),
|
||||
serde_json::json!("player_win")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accepts_duration_inside_28s_to_35s_window() {
|
||||
let ruleset = BarkBattleRuleset::v1();
|
||||
|
||||
assert_eq!(
|
||||
validate_finish_metrics(&ruleset, &metrics(28_000)).decision,
|
||||
FinishValidationDecision::Accepted
|
||||
);
|
||||
assert_eq!(
|
||||
validate_finish_metrics(&ruleset, &metrics(35_000)).decision,
|
||||
FinishValidationDecision::Accepted
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_or_flags_extreme_duration() {
|
||||
let ruleset = BarkBattleRuleset::v1();
|
||||
|
||||
assert_ne!(
|
||||
validate_finish_metrics(&ruleset, &metrics(1_000)).decision,
|
||||
FinishValidationDecision::Accepted
|
||||
);
|
||||
assert_ne!(
|
||||
validate_finish_metrics(&ruleset, &metrics(300_000)).decision,
|
||||
FinishValidationDecision::Accepted
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flags_trigger_count_above_physical_limit_with_tolerance() {
|
||||
let ruleset = BarkBattleRuleset::v1();
|
||||
let mut input = metrics(30_000);
|
||||
input.trigger_count = input.duration_ms / ruleset.min_bark_gap_ms
|
||||
+ u64::from(ruleset.trigger_count_tolerance)
|
||||
+ 1;
|
||||
|
||||
let validation = validate_finish_metrics(&ruleset, &input);
|
||||
|
||||
assert_eq!(
|
||||
validation.decision,
|
||||
FinishValidationDecision::AcceptedWithFlags
|
||||
);
|
||||
assert!(
|
||||
validation
|
||||
.anti_cheat_flags
|
||||
.contains(&AntiCheatFlag::TriggerCountTooHigh)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_final_energy_outside_range() {
|
||||
let ruleset = BarkBattleRuleset::v1();
|
||||
let mut input = metrics(30_000);
|
||||
input.final_energy = ruleset.max_final_energy + 0.1;
|
||||
|
||||
let validation = validate_finish_metrics(&ruleset, &input);
|
||||
|
||||
assert_eq!(validation.decision, FinishValidationDecision::Rejected);
|
||||
assert!(
|
||||
validation
|
||||
.anti_cheat_flags
|
||||
.contains(&AntiCheatFlag::FinalEnergyOutOfRange)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leaderboard_score_only_for_player_win_and_not_rejected() {
|
||||
let ruleset = BarkBattleRuleset::v1();
|
||||
let input = metrics(30_000);
|
||||
let validation = validate_finish_metrics(&ruleset, &input);
|
||||
|
||||
assert!(
|
||||
compute_leaderboard_score(&ruleset, &input, &validation, BattleResult::PlayerWin)
|
||||
.is_some()
|
||||
);
|
||||
assert!(
|
||||
compute_leaderboard_score(&ruleset, &input, &validation, BattleResult::Draw).is_none()
|
||||
);
|
||||
assert!(
|
||||
compute_leaderboard_score(&ruleset, &input, &validation, BattleResult::OpponentWin)
|
||||
.is_none()
|
||||
);
|
||||
|
||||
let rejected = FinishValidation {
|
||||
decision: FinishValidationDecision::Rejected,
|
||||
anti_cheat_flags: vec![AntiCheatFlag::DurationTooShort],
|
||||
};
|
||||
assert!(
|
||||
compute_leaderboard_score(&ruleset, &input, &rejected, BattleResult::PlayerWin)
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adjudicates_draw_threshold_boundaries() {
|
||||
let ruleset = BarkBattleRuleset::v1();
|
||||
assert_eq!(adjudicate_result(&ruleset, 53.0, 50.0), BattleResult::Draw);
|
||||
assert_eq!(
|
||||
adjudicate_result(&ruleset, 53.1, 50.0),
|
||||
BattleResult::PlayerWin
|
||||
);
|
||||
assert_eq!(
|
||||
adjudicate_result(&ruleset, 46.9, 50.0),
|
||||
BattleResult::OpponentWin
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validates_inclusive_metric_boundaries_and_rejects_non_finite() {
|
||||
let ruleset = BarkBattleRuleset::v1();
|
||||
let mut input = metrics(30_000);
|
||||
input.trigger_count = input.duration_ms / ruleset.min_bark_gap_ms
|
||||
+ u64::from(ruleset.trigger_count_tolerance);
|
||||
input.max_volume = ruleset.min_volume;
|
||||
input.final_energy = ruleset.max_final_energy;
|
||||
input.max_combo = ruleset.max_combo;
|
||||
assert_eq!(
|
||||
validate_finish_metrics(&ruleset, &input).decision,
|
||||
FinishValidationDecision::Accepted
|
||||
);
|
||||
|
||||
input.max_volume = f32::NAN;
|
||||
assert_eq!(
|
||||
validate_finish_metrics(&ruleset, &input).decision,
|
||||
FinishValidationDecision::Rejected
|
||||
);
|
||||
input.max_volume = 0.8;
|
||||
input.average_volume = ruleset.max_average_volume + 0.1;
|
||||
let validation = validate_finish_metrics(&ruleset, &input);
|
||||
assert_eq!(validation.decision, FinishValidationDecision::Rejected);
|
||||
assert!(
|
||||
validation
|
||||
.anti_cheat_flags
|
||||
.contains(&AntiCheatFlag::AverageVolumeOutOfRange)
|
||||
);
|
||||
input.average_volume = 0.6;
|
||||
input.final_energy = f32::INFINITY;
|
||||
assert_eq!(
|
||||
validate_finish_metrics(&ruleset, &input).decision,
|
||||
FinishValidationDecision::Rejected
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leaderboard_score_allows_flagged_but_accepted_player_wins() {
|
||||
let ruleset = BarkBattleRuleset::v1();
|
||||
let input = metrics(30_000);
|
||||
let validation = FinishValidation {
|
||||
decision: FinishValidationDecision::AcceptedWithFlags,
|
||||
anti_cheat_flags: vec![AntiCheatFlag::TriggerCountTooHigh],
|
||||
};
|
||||
|
||||
assert!(
|
||||
compute_leaderboard_score(&ruleset, &input, &validation, BattleResult::PlayerWin)
|
||||
.is_some()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn difficulty_changes_only_ai_preset_key() {
|
||||
let easy = BarkBattleRuleset::for_difficulty(DifficultyPreset::Easy);
|
||||
let normal = BarkBattleRuleset::for_difficulty(DifficultyPreset::Normal);
|
||||
let hard = BarkBattleRuleset::for_difficulty(DifficultyPreset::Hard);
|
||||
|
||||
assert_eq!(easy.thresholds_signature(), normal.thresholds_signature());
|
||||
assert_eq!(normal.thresholds_signature(), hard.thresholds_signature());
|
||||
assert_eq!(easy.ai_preset_key, "bark-battle-ai-easy");
|
||||
assert_eq!(normal.ai_preset_key, "bark-battle-ai-normal");
|
||||
assert_eq!(hard.ai_preset_key, "bark-battle-ai-hard");
|
||||
}
|
||||
}
|
||||
497
server-rs/crates/shared-contracts/src/bark_battle.rs
Normal file
497
server-rs/crates/shared-contracts/src/bark_battle.rs
Normal file
@@ -0,0 +1,497 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BarkBattleDifficultyPreset {
|
||||
Easy,
|
||||
Normal,
|
||||
Hard,
|
||||
}
|
||||
|
||||
impl Default for BarkBattleDifficultyPreset {
|
||||
fn default() -> Self {
|
||||
Self::Normal
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BarkBattleServerResult {
|
||||
PlayerWin,
|
||||
OpponentWin,
|
||||
Draw,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BarkBattleFinishStatus {
|
||||
Accepted,
|
||||
AcceptedWithFlags,
|
||||
Rejected,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleConfigEditorPayload {
|
||||
pub title: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub description: Option<String>,
|
||||
pub theme_preset: String,
|
||||
pub player_dog_skin_preset: String,
|
||||
pub opponent_dog_skin_preset: String,
|
||||
#[serde(default)]
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
pub leaderboard_enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleDraftCreateRequest {
|
||||
pub title: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub description: Option<String>,
|
||||
pub theme_preset: String,
|
||||
pub player_dog_skin_preset: String,
|
||||
pub opponent_dog_skin_preset: String,
|
||||
#[serde(default)]
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
pub leaderboard_enabled: bool,
|
||||
}
|
||||
|
||||
impl From<BarkBattleDraftCreateRequest> for BarkBattleConfigEditorPayload {
|
||||
fn from(value: BarkBattleDraftCreateRequest) -> Self {
|
||||
Self {
|
||||
title: value.title,
|
||||
description: value.description,
|
||||
theme_preset: value.theme_preset,
|
||||
player_dog_skin_preset: value.player_dog_skin_preset,
|
||||
opponent_dog_skin_preset: value.opponent_dog_skin_preset,
|
||||
difficulty_preset: value.difficulty_preset,
|
||||
leaderboard_enabled: value.leaderboard_enabled,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleWorkPublishRequest {
|
||||
pub draft_id: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub work_id: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub published_snapshot: Option<BarkBattleConfigEditorPayload>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleDraftConfig {
|
||||
pub draft_id: String,
|
||||
pub title: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub description: Option<String>,
|
||||
pub theme_preset: String,
|
||||
pub player_dog_skin_preset: String,
|
||||
pub opponent_dog_skin_preset: String,
|
||||
#[serde(default)]
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
impl Default for BarkBattleDraftConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
draft_id: String::new(),
|
||||
title: String::new(),
|
||||
description: None,
|
||||
theme_preset: String::new(),
|
||||
player_dog_skin_preset: String::new(),
|
||||
opponent_dog_skin_preset: String::new(),
|
||||
difficulty_preset: BarkBattleDifficultyPreset::Normal,
|
||||
leaderboard_enabled: true,
|
||||
updated_at: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattlePublishedConfig {
|
||||
pub work_id: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub draft_id: Option<String>,
|
||||
pub config_version: u32,
|
||||
pub ruleset_version: String,
|
||||
pub play_type_id: String,
|
||||
pub title: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub description: Option<String>,
|
||||
pub theme_preset: String,
|
||||
pub player_dog_skin_preset: String,
|
||||
pub opponent_dog_skin_preset: String,
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub updated_at: String,
|
||||
pub published_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleRuntimeConfig {
|
||||
pub work_id: String,
|
||||
pub config_version: u32,
|
||||
pub ruleset_version: String,
|
||||
pub play_type_id: String,
|
||||
pub duration_ms: u64,
|
||||
pub energy_min: f32,
|
||||
pub energy_max: f32,
|
||||
pub draw_threshold: f32,
|
||||
pub min_bark_gap_ms: u64,
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
pub theme_preset: String,
|
||||
pub player_dog_skin_preset: String,
|
||||
pub opponent_dog_skin_preset: String,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleRunStartRequest {
|
||||
pub work_id: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub config_version: Option<u32>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub source_route: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub client_runtime_version: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleRunStartResponse {
|
||||
pub run_id: String,
|
||||
pub run_token: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u32,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
pub runtime_config: BarkBattleRuntimeConfig,
|
||||
pub server_started_at: String,
|
||||
pub expires_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleDerivedMetrics {
|
||||
pub trigger_count: u32,
|
||||
pub max_volume: f32,
|
||||
pub average_volume: f32,
|
||||
pub final_energy: f32,
|
||||
pub combo_max: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleRunFinishRequest {
|
||||
pub work_id: String,
|
||||
pub run_id: String,
|
||||
pub run_token: String,
|
||||
pub config_version: u32,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
pub client_started_at: String,
|
||||
pub client_finished_at: String,
|
||||
pub duration_ms: u64,
|
||||
pub derived_metrics: BarkBattleDerivedMetrics,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub client_result: Option<BarkBattleServerResult>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub sample_digest: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub client_runtime_version: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleScoreSummary {
|
||||
pub duration_ms: u64,
|
||||
pub trigger_count: u32,
|
||||
pub max_volume: f32,
|
||||
pub average_volume: f32,
|
||||
pub final_energy: f32,
|
||||
pub combo_max: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleRunFinishResponse {
|
||||
pub status: BarkBattleFinishStatus,
|
||||
pub run_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u32,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
pub server_result: BarkBattleServerResult,
|
||||
pub score_summary: BarkBattleScoreSummary,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub leaderboard_score: Option<u64>,
|
||||
#[serde(default)]
|
||||
pub anti_cheat_flags: Vec<String>,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleLeaderboardEntry {
|
||||
pub rank: u32,
|
||||
pub run_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u32,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
pub display_name: String,
|
||||
pub server_result: BarkBattleServerResult,
|
||||
pub score_summary: BarkBattleScoreSummary,
|
||||
pub leaderboard_score: u64,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleLeaderboardResponse {
|
||||
pub work_id: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub config_version: Option<u32>,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
#[serde(default)]
|
||||
pub entries: Vec<BarkBattleLeaderboardEntry>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub viewer_best: Option<BarkBattleLeaderboardEntry>,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattlePersonalHistoryItem {
|
||||
pub run_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u32,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
pub server_result: BarkBattleServerResult,
|
||||
pub score_summary: BarkBattleScoreSummary,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub leaderboard_score: Option<u64>,
|
||||
#[serde(default)]
|
||||
pub anti_cheat_flags: Vec<String>,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattlePersonalBestSummary {
|
||||
pub work_id: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub config_version: Option<u32>,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub best_leaderboard_score: Option<u64>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub best_final_energy: Option<f32>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub best_trigger_count: Option<u32>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub best_max_volume: Option<f32>,
|
||||
pub win_count: u64,
|
||||
pub draw_count: u64,
|
||||
pub loss_count: u64,
|
||||
pub finish_count: u64,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattlePersonalHistoryResponse {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub work_id: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub difficulty_preset: Option<BarkBattleDifficultyPreset>,
|
||||
#[serde(default)]
|
||||
pub items: Vec<BarkBattlePersonalHistoryItem>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub best_summary: Option<BarkBattlePersonalBestSummary>,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleWorkStats {
|
||||
pub work_id: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub config_version: Option<u32>,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: BarkBattleDifficultyPreset,
|
||||
pub play_start_count: u64,
|
||||
pub finish_count: u64,
|
||||
pub win_count: u64,
|
||||
pub draw_count: u64,
|
||||
pub loss_count: u64,
|
||||
pub flagged_count: u64,
|
||||
pub leaderboard_entry_count: u64,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub best_leaderboard_score: Option<u64>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub best_final_energy: Option<f32>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub average_final_energy: Option<f32>,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn draft_config_defaults_to_normal_difficulty() {
|
||||
let config = BarkBattleDraftConfig::default();
|
||||
|
||||
assert_eq!(config.difficulty_preset, BarkBattleDifficultyPreset::Normal);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_requests_carry_config_and_ruleset_identity() {
|
||||
let start = BarkBattleRunStartRequest {
|
||||
work_id: "work-1".to_string(),
|
||||
config_version: Some(3),
|
||||
source_route: Some("gallery".to_string()),
|
||||
client_runtime_version: Some("runtime-v1".to_string()),
|
||||
};
|
||||
let start_payload = serde_json::to_value(start).expect("start request should serialize");
|
||||
assert_eq!(start_payload["workId"], json!("work-1"));
|
||||
assert_eq!(start_payload["configVersion"], json!(3));
|
||||
assert_eq!(start_payload["sourceRoute"], json!("gallery"));
|
||||
|
||||
let finish = BarkBattleRunFinishRequest {
|
||||
work_id: "work-1".to_string(),
|
||||
run_id: "run-1".to_string(),
|
||||
run_token: "token-1".to_string(),
|
||||
config_version: 3,
|
||||
ruleset_version: "bark-battle-ruleset-v1".to_string(),
|
||||
difficulty_preset: BarkBattleDifficultyPreset::Hard,
|
||||
client_started_at: "2026-05-13T11:00:00Z".to_string(),
|
||||
client_finished_at: "2026-05-13T11:00:30Z".to_string(),
|
||||
duration_ms: 30_000,
|
||||
derived_metrics: BarkBattleDerivedMetrics {
|
||||
trigger_count: 12,
|
||||
max_volume: 0.95,
|
||||
average_volume: 0.62,
|
||||
final_energy: 88.5,
|
||||
combo_max: 7,
|
||||
},
|
||||
client_result: Some(BarkBattleServerResult::PlayerWin),
|
||||
sample_digest: Some("digest-1".to_string()),
|
||||
client_runtime_version: None,
|
||||
};
|
||||
let finish_payload = serde_json::to_value(finish).expect("finish request should serialize");
|
||||
assert_eq!(finish_payload["configVersion"], json!(3));
|
||||
assert_eq!(
|
||||
finish_payload["rulesetVersion"],
|
||||
json!("bark-battle-ruleset-v1")
|
||||
);
|
||||
assert_eq!(finish_payload["difficultyPreset"], json!("hard"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn optional_fields_are_omitted_when_absent() {
|
||||
let draft = BarkBattleDraftConfig::default();
|
||||
let payload = serde_json::to_value(draft).expect("draft should serialize");
|
||||
assert!(!payload.as_object().unwrap().contains_key("description"));
|
||||
|
||||
let response = BarkBattlePersonalHistoryResponse {
|
||||
work_id: None,
|
||||
difficulty_preset: None,
|
||||
items: Vec::new(),
|
||||
best_summary: None,
|
||||
updated_at: "2026-05-13T11:00:00Z".to_string(),
|
||||
};
|
||||
let payload = serde_json::to_value(response).expect("history response should serialize");
|
||||
assert!(!payload.as_object().unwrap().contains_key("workId"));
|
||||
assert!(
|
||||
!payload
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.contains_key("difficultyPreset")
|
||||
);
|
||||
assert!(!payload.as_object().unwrap().contains_key("bestSummary"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finish_response_serializes_player_win_and_accepted() {
|
||||
let response = BarkBattleRunFinishResponse {
|
||||
status: BarkBattleFinishStatus::Accepted,
|
||||
run_id: "run-1".to_string(),
|
||||
work_id: "work-1".to_string(),
|
||||
config_version: 3,
|
||||
ruleset_version: "bark-battle-ruleset-v1".to_string(),
|
||||
difficulty_preset: BarkBattleDifficultyPreset::Normal,
|
||||
server_result: BarkBattleServerResult::PlayerWin,
|
||||
score_summary: BarkBattleScoreSummary {
|
||||
duration_ms: 30_000,
|
||||
trigger_count: 12,
|
||||
max_volume: 0.95,
|
||||
average_volume: 0.62,
|
||||
final_energy: 88.5,
|
||||
combo_max: 7,
|
||||
},
|
||||
leaderboard_score: Some(98_765),
|
||||
anti_cheat_flags: Vec::new(),
|
||||
updated_at: "2026-05-13T11:00:00Z".to_string(),
|
||||
};
|
||||
|
||||
let payload = serde_json::to_value(response).expect("finish response should serialize");
|
||||
|
||||
assert_eq!(payload["runId"], json!("run-1"));
|
||||
assert_eq!(payload["status"], json!("accepted"));
|
||||
assert_eq!(payload["serverResult"], json!("player_win"));
|
||||
assert_eq!(payload["leaderboardScore"], json!(98_765));
|
||||
assert_eq!(payload["scoreSummary"]["finalEnergy"], json!(88.5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn work_stats_fields_are_constructible() {
|
||||
let stats = BarkBattleWorkStats {
|
||||
work_id: "work-1".to_string(),
|
||||
config_version: Some(3),
|
||||
ruleset_version: "bark-battle-ruleset-v1".to_string(),
|
||||
difficulty_preset: BarkBattleDifficultyPreset::Normal,
|
||||
play_start_count: 10,
|
||||
finish_count: 9,
|
||||
win_count: 5,
|
||||
draw_count: 2,
|
||||
loss_count: 2,
|
||||
flagged_count: 1,
|
||||
leaderboard_entry_count: 4,
|
||||
best_leaderboard_score: Some(98_765),
|
||||
best_final_energy: Some(97.5),
|
||||
average_final_energy: Some(73.25),
|
||||
updated_at: "2026-05-13T11:00:00Z".to_string(),
|
||||
};
|
||||
|
||||
assert_eq!(stats.work_id, "work-1");
|
||||
assert_eq!(stats.play_start_count, 10);
|
||||
assert_eq!(stats.finish_count, 9);
|
||||
assert_eq!(stats.win_count, 5);
|
||||
assert_eq!(stats.draw_count, 2);
|
||||
assert_eq!(stats.loss_count, 2);
|
||||
assert_eq!(stats.flagged_count, 1);
|
||||
assert_eq!(stats.leaderboard_entry_count, 4);
|
||||
assert_eq!(stats.best_leaderboard_score, Some(98_765));
|
||||
assert_eq!(stats.best_final_energy, Some(97.5));
|
||||
assert_eq!(stats.average_final_energy, Some(73.25));
|
||||
assert_eq!(stats.updated_at, "2026-05-13T11:00:00Z");
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ pub mod api;
|
||||
#[cfg(feature = "oss-contracts")]
|
||||
pub mod assets;
|
||||
pub mod auth;
|
||||
pub mod bark_battle;
|
||||
pub mod big_fish;
|
||||
pub mod big_fish_works;
|
||||
pub mod creation_agent_document_input;
|
||||
|
||||
138
server-rs/crates/spacetime-client/src/bark_battle.rs
Normal file
138
server-rs/crates/spacetime-client/src/bark_battle.rs
Normal file
@@ -0,0 +1,138 @@
|
||||
use super::*;
|
||||
|
||||
pub type BarkBattleDraftCreateRecordInput = BarkBattleDraftCreateInput;
|
||||
pub type BarkBattleDraftConfigUpsertRecordInput = BarkBattleDraftConfigUpsertInput;
|
||||
pub type BarkBattleWorkPublishRecordInput = BarkBattleWorkPublishInput;
|
||||
pub type BarkBattleRunStartRecordInput = BarkBattleRunStartInput;
|
||||
pub type BarkBattleRunFinishRecordInput = BarkBattleRunFinishInput;
|
||||
|
||||
impl SpacetimeClient {
|
||||
pub async fn create_bark_battle_draft(
|
||||
&self,
|
||||
input: BarkBattleDraftCreateRecordInput,
|
||||
) -> Result<BarkBattleDraftConfigRecord, SpacetimeClientError> {
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.create_bark_battle_draft_then(input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_bark_battle_draft_config_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn update_bark_battle_draft_config(
|
||||
&self,
|
||||
input: BarkBattleDraftConfigUpsertRecordInput,
|
||||
) -> Result<BarkBattleDraftConfigRecord, SpacetimeClientError> {
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.update_bark_battle_draft_config_then(input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_bark_battle_draft_config_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn publish_bark_battle_work(
|
||||
&self,
|
||||
input: BarkBattleWorkPublishRecordInput,
|
||||
) -> Result<BarkBattleRuntimeConfigRecord, SpacetimeClientError> {
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.publish_bark_battle_work_then(input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_bark_battle_runtime_config_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_bark_battle_runtime_config(
|
||||
&self,
|
||||
work_id: String,
|
||||
owner_user_id: Option<String>,
|
||||
) -> Result<BarkBattleRuntimeConfigRecord, SpacetimeClientError> {
|
||||
let input = BarkBattleRuntimeConfigGetInput {
|
||||
work_id,
|
||||
owner_user_id,
|
||||
};
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.get_bark_battle_runtime_config_then(input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_bark_battle_runtime_config_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn start_bark_battle_run(
|
||||
&self,
|
||||
input: BarkBattleRunStartRecordInput,
|
||||
) -> Result<BarkBattleRunRecord, SpacetimeClientError> {
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.start_bark_battle_run_then(input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_bark_battle_run_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn finish_bark_battle_run(
|
||||
&self,
|
||||
input: BarkBattleRunFinishRecordInput,
|
||||
) -> Result<BarkBattleRunRecord, SpacetimeClientError> {
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.finish_bark_battle_run_then(input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_bark_battle_run_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_bark_battle_run(
|
||||
&self,
|
||||
run_id: String,
|
||||
owner_user_id: String,
|
||||
) -> Result<BarkBattleRunRecord, SpacetimeClientError> {
|
||||
let input = BarkBattleRunGetInput {
|
||||
run_id,
|
||||
owner_user_id,
|
||||
};
|
||||
self.call_after_connect(move |connection, sender| {
|
||||
connection
|
||||
.procedures()
|
||||
.get_bark_battle_run_then(input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
|
||||
.and_then(map_bark_battle_run_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
}
|
||||
@@ -6,21 +6,22 @@ mod mapper;
|
||||
use mapper::*;
|
||||
pub use mapper::{
|
||||
AiResultReferenceRecord, AiTaskMutationRecord, AiTaskRecord, AiTaskStageRecord,
|
||||
AiTextChunkRecord, BattleStateRecord, BigFishAgentMessageRecord, BigFishAnchorItemRecord,
|
||||
BigFishAnchorPackRecord, BigFishAssetCoverageRecord, BigFishAssetGenerateRecordInput,
|
||||
BigFishAssetSlotRecord, BigFishBackgroundBlueprintRecord, BigFishDraftCompileRecordInput,
|
||||
BigFishGameDraftRecord, BigFishInputSubmitRecordInput, BigFishLevelBlueprintRecord,
|
||||
BigFishLikeReportRecordInput, BigFishMessageFinalizeRecordInput,
|
||||
AiTextChunkRecord, BarkBattleDraftConfigRecord, BarkBattleRunRecord,
|
||||
BarkBattleRuntimeConfigRecord, BattleStateRecord, BigFishAgentMessageRecord,
|
||||
BigFishAnchorItemRecord, BigFishAnchorPackRecord, BigFishAssetCoverageRecord,
|
||||
BigFishAssetGenerateRecordInput, BigFishAssetSlotRecord, BigFishBackgroundBlueprintRecord,
|
||||
BigFishDraftCompileRecordInput, BigFishGameDraftRecord, BigFishInputSubmitRecordInput,
|
||||
BigFishLevelBlueprintRecord, BigFishLikeReportRecordInput, BigFishMessageFinalizeRecordInput,
|
||||
BigFishMessageSubmitRecordInput, BigFishPlayReportRecordInput, BigFishRunStartRecordInput,
|
||||
BigFishRuntimeEntityRecord, BigFishRuntimeParamsRecord, BigFishRuntimeRunRecord,
|
||||
BigFishSessionCreateRecordInput, BigFishSessionRecord, BigFishVector2Record,
|
||||
BigFishWorkRemixRecordInput, BigFishWorkSummaryRecord, CreationEntryConfigRecord,
|
||||
CustomWorldAgentActionExecuteRecord,
|
||||
CustomWorldAgentActionExecuteRecordInput, CustomWorldAgentCheckpointRecord,
|
||||
CustomWorldAgentMessageFinalizeRecordInput, CustomWorldAgentMessageRecord,
|
||||
CustomWorldAgentMessageSubmitRecordInput, CustomWorldAgentOperationProgressRecordInput,
|
||||
CustomWorldAgentOperationRecord, CustomWorldAgentSessionCreateRecordInput,
|
||||
CustomWorldAgentSessionRecord, CustomWorldCheckpointRecord, CustomWorldDraftCardDetailRecord,
|
||||
CustomWorldAgentActionExecuteRecord, CustomWorldAgentActionExecuteRecordInput,
|
||||
CustomWorldAgentCheckpointRecord, CustomWorldAgentMessageFinalizeRecordInput,
|
||||
CustomWorldAgentMessageRecord, CustomWorldAgentMessageSubmitRecordInput,
|
||||
CustomWorldAgentOperationProgressRecordInput, CustomWorldAgentOperationRecord,
|
||||
CustomWorldAgentSessionCreateRecordInput, CustomWorldAgentSessionRecord,
|
||||
CustomWorldCheckpointRecord, CustomWorldDraftCardDetailRecord,
|
||||
CustomWorldDraftCardDetailSectionRecord, CustomWorldDraftCardRecord,
|
||||
CustomWorldGalleryEntryRecord, CustomWorldLibraryEntryRecord, CustomWorldLibraryMutationRecord,
|
||||
CustomWorldProfileLikeReportRecordInput, CustomWorldProfilePlayReportRecordInput,
|
||||
@@ -42,15 +43,14 @@ pub use mapper::{
|
||||
PuzzleAgentSessionRecord, PuzzleAgentSuggestedActionRecord, PuzzleAnchorItemRecord,
|
||||
PuzzleAnchorPackRecord, PuzzleAudioAssetRecord, PuzzleBoardRecord, PuzzleCellPositionRecord,
|
||||
PuzzleCreatorIntentRecord, PuzzleDraftLevelRecord, PuzzleFormDraftRecord,
|
||||
PuzzleFormDraftSaveRecordInput,
|
||||
PuzzleGeneratedImageCandidateRecord, PuzzleGeneratedImagesSaveRecordInput,
|
||||
PuzzleLeaderboardEntryRecord, PuzzleLeaderboardSubmitRecordInput, PuzzleMergedGroupRecord,
|
||||
PuzzlePieceStateRecord, PuzzlePublishRecordInput, PuzzleRecommendedNextWorkRecord,
|
||||
PuzzleResultDraftRecord, PuzzleResultPreviewBlockerRecord, PuzzleResultPreviewFindingRecord,
|
||||
PuzzleResultPreviewRecord, PuzzleRunDragRecordInput, PuzzleRunNextLevelRecordInput,
|
||||
PuzzleRunPauseRecordInput, PuzzleRunPropRecordInput, PuzzleRunRecord,
|
||||
PuzzleRunStartRecordInput, PuzzleRunSwapRecordInput, PuzzleRuntimeLevelRecord,
|
||||
PuzzleSelectCoverImageRecordInput, PuzzleWorkLikeReportRecordInput,
|
||||
PuzzleFormDraftSaveRecordInput, PuzzleGeneratedImageCandidateRecord,
|
||||
PuzzleGeneratedImagesSaveRecordInput, PuzzleLeaderboardEntryRecord,
|
||||
PuzzleLeaderboardSubmitRecordInput, PuzzleMergedGroupRecord, PuzzlePieceStateRecord,
|
||||
PuzzlePublishRecordInput, PuzzleRecommendedNextWorkRecord, PuzzleResultDraftRecord,
|
||||
PuzzleResultPreviewBlockerRecord, PuzzleResultPreviewFindingRecord, PuzzleResultPreviewRecord,
|
||||
PuzzleRunDragRecordInput, PuzzleRunNextLevelRecordInput, PuzzleRunPauseRecordInput,
|
||||
PuzzleRunPropRecordInput, PuzzleRunRecord, PuzzleRunStartRecordInput, PuzzleRunSwapRecordInput,
|
||||
PuzzleRuntimeLevelRecord, PuzzleSelectCoverImageRecordInput, PuzzleWorkLikeReportRecordInput,
|
||||
PuzzleWorkPointIncentiveClaimRecordInput, PuzzleWorkProfileRecord, PuzzleWorkRemixRecordInput,
|
||||
PuzzleWorkUpsertRecordInput, ResolveCombatActionRecord, ResolveNpcBattleInteractionInput,
|
||||
SquareHoleAgentMessageFinalizeRecordInput, SquareHoleAgentMessageRecord,
|
||||
@@ -74,6 +74,12 @@ pub use mapper::{
|
||||
pub mod ai;
|
||||
pub mod assets;
|
||||
pub mod auth;
|
||||
pub mod bark_battle;
|
||||
pub use bark_battle::{
|
||||
BarkBattleDraftConfigUpsertRecordInput, BarkBattleDraftCreateRecordInput,
|
||||
BarkBattleRunFinishRecordInput, BarkBattleRunStartRecordInput,
|
||||
BarkBattleWorkPublishRecordInput,
|
||||
};
|
||||
pub mod big_fish;
|
||||
pub mod combat;
|
||||
pub mod custom_world;
|
||||
|
||||
@@ -720,6 +720,42 @@ pub(crate) fn map_asset_history_list_result(
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub type BarkBattleDraftConfigRecord = serde_json::Value;
|
||||
pub type BarkBattleRuntimeConfigRecord = serde_json::Value;
|
||||
pub type BarkBattleRunRecord = serde_json::Value;
|
||||
|
||||
pub(crate) fn map_bark_battle_draft_config_procedure_result(
|
||||
result: BarkBattleProcedureResult,
|
||||
) -> Result<BarkBattleDraftConfigRecord, SpacetimeClientError> {
|
||||
parse_bark_battle_row_json(result, "Bark Battle draft config")
|
||||
}
|
||||
|
||||
pub(crate) fn map_bark_battle_runtime_config_procedure_result(
|
||||
result: BarkBattleProcedureResult,
|
||||
) -> Result<BarkBattleRuntimeConfigRecord, SpacetimeClientError> {
|
||||
parse_bark_battle_row_json(result, "Bark Battle runtime config")
|
||||
}
|
||||
|
||||
pub(crate) fn map_bark_battle_run_procedure_result(
|
||||
result: BarkBattleProcedureResult,
|
||||
) -> Result<BarkBattleRunRecord, SpacetimeClientError> {
|
||||
parse_bark_battle_row_json(result, "Bark Battle run")
|
||||
}
|
||||
|
||||
fn parse_bark_battle_row_json<T: serde::de::DeserializeOwned>(
|
||||
result: BarkBattleProcedureResult,
|
||||
label: &'static str,
|
||||
) -> Result<T, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
let row_json = result
|
||||
.row_json
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot(label))?;
|
||||
serde_json::from_str(&row_json)
|
||||
.map_err(|error| SpacetimeClientError::Runtime(format!("{label} JSON 解析失败: {error}")))
|
||||
}
|
||||
|
||||
pub type CreationEntryConfigRecord =
|
||||
shared_contracts::creation_entry_config::CreationEntryConfigResponse;
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// 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 BarkBattleDraftConfigRow {
|
||||
pub draft_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub config_json: String,
|
||||
pub editor_state_json: String,
|
||||
pub created_at: __sdk::Timestamp,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleDraftConfigRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `BarkBattleDraftConfigRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct BarkBattleDraftConfigRowCols {
|
||||
pub draft_id: __sdk::__query_builder::Col<BarkBattleDraftConfigRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<BarkBattleDraftConfigRow, String>,
|
||||
pub work_id: __sdk::__query_builder::Col<BarkBattleDraftConfigRow, String>,
|
||||
pub config_version: __sdk::__query_builder::Col<BarkBattleDraftConfigRow, u64>,
|
||||
pub ruleset_version: __sdk::__query_builder::Col<BarkBattleDraftConfigRow, String>,
|
||||
pub difficulty_preset: __sdk::__query_builder::Col<BarkBattleDraftConfigRow, String>,
|
||||
pub leaderboard_enabled: __sdk::__query_builder::Col<BarkBattleDraftConfigRow, bool>,
|
||||
pub config_json: __sdk::__query_builder::Col<BarkBattleDraftConfigRow, String>,
|
||||
pub editor_state_json: __sdk::__query_builder::Col<BarkBattleDraftConfigRow, String>,
|
||||
pub created_at: __sdk::__query_builder::Col<BarkBattleDraftConfigRow, __sdk::Timestamp>,
|
||||
pub updated_at: __sdk::__query_builder::Col<BarkBattleDraftConfigRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for BarkBattleDraftConfigRow {
|
||||
type Cols = BarkBattleDraftConfigRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
BarkBattleDraftConfigRowCols {
|
||||
draft_id: __sdk::__query_builder::Col::new(table_name, "draft_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
work_id: __sdk::__query_builder::Col::new(table_name, "work_id"),
|
||||
config_version: __sdk::__query_builder::Col::new(table_name, "config_version"),
|
||||
ruleset_version: __sdk::__query_builder::Col::new(table_name, "ruleset_version"),
|
||||
difficulty_preset: __sdk::__query_builder::Col::new(table_name, "difficulty_preset"),
|
||||
leaderboard_enabled: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"leaderboard_enabled",
|
||||
),
|
||||
config_json: __sdk::__query_builder::Col::new(table_name, "config_json"),
|
||||
editor_state_json: __sdk::__query_builder::Col::new(table_name, "editor_state_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 `BarkBattleDraftConfigRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct BarkBattleDraftConfigRowIxCols {
|
||||
pub draft_id: __sdk::__query_builder::IxCol<BarkBattleDraftConfigRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::IxCol<BarkBattleDraftConfigRow, String>,
|
||||
pub work_id: __sdk::__query_builder::IxCol<BarkBattleDraftConfigRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for BarkBattleDraftConfigRow {
|
||||
type IxCols = BarkBattleDraftConfigRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
BarkBattleDraftConfigRowIxCols {
|
||||
draft_id: __sdk::__query_builder::IxCol::new(table_name, "draft_id"),
|
||||
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
|
||||
work_id: __sdk::__query_builder::IxCol::new(table_name, "work_id"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for BarkBattleDraftConfigRow {}
|
||||
@@ -0,0 +1,162 @@
|
||||
// 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 super::bark_battle_draft_config_row_type::BarkBattleDraftConfigRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `bark_battle_draft_config`.
|
||||
///
|
||||
/// Obtain a handle from the [`BarkBattleDraftConfigTableAccess::bark_battle_draft_config`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.bark_battle_draft_config()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_draft_config().on_insert(...)`.
|
||||
pub struct BarkBattleDraftConfigTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<BarkBattleDraftConfigRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `bark_battle_draft_config`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait BarkBattleDraftConfigTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`BarkBattleDraftConfigTableHandle`], which mediates access to the table `bark_battle_draft_config`.
|
||||
fn bark_battle_draft_config(&self) -> BarkBattleDraftConfigTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl BarkBattleDraftConfigTableAccess for super::RemoteTables {
|
||||
fn bark_battle_draft_config(&self) -> BarkBattleDraftConfigTableHandle<'_> {
|
||||
BarkBattleDraftConfigTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<BarkBattleDraftConfigRow>("bark_battle_draft_config"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattleDraftConfigInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct BarkBattleDraftConfigDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for BarkBattleDraftConfigTableHandle<'ctx> {
|
||||
type Row = BarkBattleDraftConfigRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = BarkBattleDraftConfigRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = BarkBattleDraftConfigInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleDraftConfigInsertCallbackId {
|
||||
BarkBattleDraftConfigInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: BarkBattleDraftConfigInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = BarkBattleDraftConfigDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleDraftConfigDeleteCallbackId {
|
||||
BarkBattleDraftConfigDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: BarkBattleDraftConfigDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattleDraftConfigUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for BarkBattleDraftConfigTableHandle<'ctx> {
|
||||
type UpdateCallbackId = BarkBattleDraftConfigUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleDraftConfigUpdateCallbackId {
|
||||
BarkBattleDraftConfigUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: BarkBattleDraftConfigUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `draft_id` unique index on the table `bark_battle_draft_config`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`BarkBattleDraftConfigDraftIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_draft_config().draft_id().find(...)`.
|
||||
pub struct BarkBattleDraftConfigDraftIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<BarkBattleDraftConfigRow, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattleDraftConfigTableHandle<'ctx> {
|
||||
/// Get a handle on the `draft_id` unique index on the table `bark_battle_draft_config`.
|
||||
pub fn draft_id(&self) -> BarkBattleDraftConfigDraftIdUnique<'ctx> {
|
||||
BarkBattleDraftConfigDraftIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("draft_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattleDraftConfigDraftIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `draft_id` column value is equal to `col_val`,
|
||||
/// if such a row is present in the client cache.
|
||||
pub fn find(&self, col_val: &String) -> Option<BarkBattleDraftConfigRow> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table =
|
||||
client_cache.get_or_make_table::<BarkBattleDraftConfigRow>("bark_battle_draft_config");
|
||||
_table.add_unique_constraint::<String>("draft_id", |row| &row.draft_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<BarkBattleDraftConfigRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<BarkBattleDraftConfigRow>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `BarkBattleDraftConfigRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait bark_battle_draft_configQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `BarkBattleDraftConfigRow`.
|
||||
fn bark_battle_draft_config(&self) -> __sdk::__query_builder::Table<BarkBattleDraftConfigRow>;
|
||||
}
|
||||
|
||||
impl bark_battle_draft_configQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn bark_battle_draft_config(&self) -> __sdk::__query_builder::Table<BarkBattleDraftConfigRow> {
|
||||
__sdk::__query_builder::Table::new("bark_battle_draft_config")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// 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 BarkBattleDraftConfigUpsertInput {
|
||||
pub draft_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub config_json: String,
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleDraftConfigUpsertInput {
|
||||
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 BarkBattleDraftCreateInput {
|
||||
pub draft_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub title: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub theme_preset: String,
|
||||
pub player_dog_skin_preset: String,
|
||||
pub opponent_dog_skin_preset: String,
|
||||
pub difficulty_preset: Option<String>,
|
||||
pub leaderboard_enabled: Option<bool>,
|
||||
pub editor_state_json: Option<String>,
|
||||
pub created_at_micros: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleDraftCreateInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// 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 BarkBattleLeaderboardEntryRow {
|
||||
pub leaderboard_entry_id: String,
|
||||
pub work_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub run_id: String,
|
||||
pub score_id: String,
|
||||
pub leaderboard_score: u64,
|
||||
pub final_energy: f32,
|
||||
pub trigger_count: u64,
|
||||
pub max_volume: f32,
|
||||
pub duration_closeness_ms: u64,
|
||||
pub finished_at_micros: i64,
|
||||
pub created_at: __sdk::Timestamp,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleLeaderboardEntryRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `BarkBattleLeaderboardEntryRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct BarkBattleLeaderboardEntryRowCols {
|
||||
pub leaderboard_entry_id: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, String>,
|
||||
pub work_id: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, String>,
|
||||
pub run_id: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, String>,
|
||||
pub score_id: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, String>,
|
||||
pub leaderboard_score: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, u64>,
|
||||
pub final_energy: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, f32>,
|
||||
pub trigger_count: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, u64>,
|
||||
pub max_volume: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, f32>,
|
||||
pub duration_closeness_ms: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, u64>,
|
||||
pub finished_at_micros: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, i64>,
|
||||
pub created_at: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, __sdk::Timestamp>,
|
||||
pub updated_at: __sdk::__query_builder::Col<BarkBattleLeaderboardEntryRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for BarkBattleLeaderboardEntryRow {
|
||||
type Cols = BarkBattleLeaderboardEntryRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
BarkBattleLeaderboardEntryRowCols {
|
||||
leaderboard_entry_id: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"leaderboard_entry_id",
|
||||
),
|
||||
work_id: __sdk::__query_builder::Col::new(table_name, "work_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
run_id: __sdk::__query_builder::Col::new(table_name, "run_id"),
|
||||
score_id: __sdk::__query_builder::Col::new(table_name, "score_id"),
|
||||
leaderboard_score: __sdk::__query_builder::Col::new(table_name, "leaderboard_score"),
|
||||
final_energy: __sdk::__query_builder::Col::new(table_name, "final_energy"),
|
||||
trigger_count: __sdk::__query_builder::Col::new(table_name, "trigger_count"),
|
||||
max_volume: __sdk::__query_builder::Col::new(table_name, "max_volume"),
|
||||
duration_closeness_ms: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"duration_closeness_ms",
|
||||
),
|
||||
finished_at_micros: __sdk::__query_builder::Col::new(table_name, "finished_at_micros"),
|
||||
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 `BarkBattleLeaderboardEntryRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct BarkBattleLeaderboardEntryRowIxCols {
|
||||
pub leaderboard_entry_id: __sdk::__query_builder::IxCol<BarkBattleLeaderboardEntryRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for BarkBattleLeaderboardEntryRow {
|
||||
type IxCols = BarkBattleLeaderboardEntryRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
BarkBattleLeaderboardEntryRowIxCols {
|
||||
leaderboard_entry_id: __sdk::__query_builder::IxCol::new(
|
||||
table_name,
|
||||
"leaderboard_entry_id",
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for BarkBattleLeaderboardEntryRow {}
|
||||
@@ -0,0 +1,171 @@
|
||||
// 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 super::bark_battle_leaderboard_entry_row_type::BarkBattleLeaderboardEntryRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `bark_battle_leaderboard_entry`.
|
||||
///
|
||||
/// Obtain a handle from the [`BarkBattleLeaderboardEntryTableAccess::bark_battle_leaderboard_entry`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.bark_battle_leaderboard_entry()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_leaderboard_entry().on_insert(...)`.
|
||||
pub struct BarkBattleLeaderboardEntryTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<BarkBattleLeaderboardEntryRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `bark_battle_leaderboard_entry`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait BarkBattleLeaderboardEntryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`BarkBattleLeaderboardEntryTableHandle`], which mediates access to the table `bark_battle_leaderboard_entry`.
|
||||
fn bark_battle_leaderboard_entry(&self) -> BarkBattleLeaderboardEntryTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl BarkBattleLeaderboardEntryTableAccess for super::RemoteTables {
|
||||
fn bark_battle_leaderboard_entry(&self) -> BarkBattleLeaderboardEntryTableHandle<'_> {
|
||||
BarkBattleLeaderboardEntryTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<BarkBattleLeaderboardEntryRow>("bark_battle_leaderboard_entry"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattleLeaderboardEntryInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct BarkBattleLeaderboardEntryDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for BarkBattleLeaderboardEntryTableHandle<'ctx> {
|
||||
type Row = BarkBattleLeaderboardEntryRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = BarkBattleLeaderboardEntryRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = BarkBattleLeaderboardEntryInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleLeaderboardEntryInsertCallbackId {
|
||||
BarkBattleLeaderboardEntryInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: BarkBattleLeaderboardEntryInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = BarkBattleLeaderboardEntryDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleLeaderboardEntryDeleteCallbackId {
|
||||
BarkBattleLeaderboardEntryDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: BarkBattleLeaderboardEntryDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattleLeaderboardEntryUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for BarkBattleLeaderboardEntryTableHandle<'ctx> {
|
||||
type UpdateCallbackId = BarkBattleLeaderboardEntryUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleLeaderboardEntryUpdateCallbackId {
|
||||
BarkBattleLeaderboardEntryUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: BarkBattleLeaderboardEntryUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `leaderboard_entry_id` unique index on the table `bark_battle_leaderboard_entry`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`BarkBattleLeaderboardEntryLeaderboardEntryIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_leaderboard_entry().leaderboard_entry_id().find(...)`.
|
||||
pub struct BarkBattleLeaderboardEntryLeaderboardEntryIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<BarkBattleLeaderboardEntryRow, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattleLeaderboardEntryTableHandle<'ctx> {
|
||||
/// Get a handle on the `leaderboard_entry_id` unique index on the table `bark_battle_leaderboard_entry`.
|
||||
pub fn leaderboard_entry_id(&self) -> BarkBattleLeaderboardEntryLeaderboardEntryIdUnique<'ctx> {
|
||||
BarkBattleLeaderboardEntryLeaderboardEntryIdUnique {
|
||||
imp: self
|
||||
.imp
|
||||
.get_unique_constraint::<String>("leaderboard_entry_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattleLeaderboardEntryLeaderboardEntryIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `leaderboard_entry_id` column value is equal to `col_val`,
|
||||
/// if such a row is present in the client cache.
|
||||
pub fn find(&self, col_val: &String) -> Option<BarkBattleLeaderboardEntryRow> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache
|
||||
.get_or_make_table::<BarkBattleLeaderboardEntryRow>("bark_battle_leaderboard_entry");
|
||||
_table.add_unique_constraint::<String>("leaderboard_entry_id", |row| &row.leaderboard_entry_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<BarkBattleLeaderboardEntryRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse(
|
||||
"TableUpdate<BarkBattleLeaderboardEntryRow>",
|
||||
"TableUpdate",
|
||||
)
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `BarkBattleLeaderboardEntryRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait bark_battle_leaderboard_entryQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `BarkBattleLeaderboardEntryRow`.
|
||||
fn bark_battle_leaderboard_entry(
|
||||
&self,
|
||||
) -> __sdk::__query_builder::Table<BarkBattleLeaderboardEntryRow>;
|
||||
}
|
||||
|
||||
impl bark_battle_leaderboard_entryQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn bark_battle_leaderboard_entry(
|
||||
&self,
|
||||
) -> __sdk::__query_builder::Table<BarkBattleLeaderboardEntryRow> {
|
||||
__sdk::__query_builder::Table::new("bark_battle_leaderboard_entry")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// 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 BarkBattlePersonalBestProjectionRow {
|
||||
pub personal_best_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub run_id: String,
|
||||
pub score_id: String,
|
||||
pub leaderboard_entry_id: Option<String>,
|
||||
pub leaderboard_score: Option<u64>,
|
||||
pub final_energy: f32,
|
||||
pub trigger_count: u64,
|
||||
pub max_volume: f32,
|
||||
pub duration_closeness_ms: u64,
|
||||
pub server_result: String,
|
||||
pub validation_status: String,
|
||||
pub finished_at_micros: i64,
|
||||
pub summary_json: String,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattlePersonalBestProjectionRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `BarkBattlePersonalBestProjectionRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct BarkBattlePersonalBestProjectionRowCols {
|
||||
pub personal_best_id: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, String>,
|
||||
pub work_id: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, String>,
|
||||
pub run_id: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, String>,
|
||||
pub score_id: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, String>,
|
||||
pub leaderboard_entry_id:
|
||||
__sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, Option<String>>,
|
||||
pub leaderboard_score:
|
||||
__sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, Option<u64>>,
|
||||
pub final_energy: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, f32>,
|
||||
pub trigger_count: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, u64>,
|
||||
pub max_volume: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, f32>,
|
||||
pub duration_closeness_ms:
|
||||
__sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, u64>,
|
||||
pub server_result: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, String>,
|
||||
pub validation_status: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, String>,
|
||||
pub finished_at_micros: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, i64>,
|
||||
pub summary_json: __sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, String>,
|
||||
pub updated_at:
|
||||
__sdk::__query_builder::Col<BarkBattlePersonalBestProjectionRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for BarkBattlePersonalBestProjectionRow {
|
||||
type Cols = BarkBattlePersonalBestProjectionRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
BarkBattlePersonalBestProjectionRowCols {
|
||||
personal_best_id: __sdk::__query_builder::Col::new(table_name, "personal_best_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
work_id: __sdk::__query_builder::Col::new(table_name, "work_id"),
|
||||
run_id: __sdk::__query_builder::Col::new(table_name, "run_id"),
|
||||
score_id: __sdk::__query_builder::Col::new(table_name, "score_id"),
|
||||
leaderboard_entry_id: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"leaderboard_entry_id",
|
||||
),
|
||||
leaderboard_score: __sdk::__query_builder::Col::new(table_name, "leaderboard_score"),
|
||||
final_energy: __sdk::__query_builder::Col::new(table_name, "final_energy"),
|
||||
trigger_count: __sdk::__query_builder::Col::new(table_name, "trigger_count"),
|
||||
max_volume: __sdk::__query_builder::Col::new(table_name, "max_volume"),
|
||||
duration_closeness_ms: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"duration_closeness_ms",
|
||||
),
|
||||
server_result: __sdk::__query_builder::Col::new(table_name, "server_result"),
|
||||
validation_status: __sdk::__query_builder::Col::new(table_name, "validation_status"),
|
||||
finished_at_micros: __sdk::__query_builder::Col::new(table_name, "finished_at_micros"),
|
||||
summary_json: __sdk::__query_builder::Col::new(table_name, "summary_json"),
|
||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indexed column accessor struct for the table `BarkBattlePersonalBestProjectionRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct BarkBattlePersonalBestProjectionRowIxCols {
|
||||
pub personal_best_id:
|
||||
__sdk::__query_builder::IxCol<BarkBattlePersonalBestProjectionRow, String>,
|
||||
pub work_id: __sdk::__query_builder::IxCol<BarkBattlePersonalBestProjectionRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for BarkBattlePersonalBestProjectionRow {
|
||||
type IxCols = BarkBattlePersonalBestProjectionRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
BarkBattlePersonalBestProjectionRowIxCols {
|
||||
personal_best_id: __sdk::__query_builder::IxCol::new(table_name, "personal_best_id"),
|
||||
work_id: __sdk::__query_builder::IxCol::new(table_name, "work_id"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for BarkBattlePersonalBestProjectionRow {}
|
||||
@@ -0,0 +1,174 @@
|
||||
// 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 super::bark_battle_personal_best_projection_row_type::BarkBattlePersonalBestProjectionRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `bark_battle_personal_best_projection`.
|
||||
///
|
||||
/// Obtain a handle from the [`BarkBattlePersonalBestProjectionTableAccess::bark_battle_personal_best_projection`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.bark_battle_personal_best_projection()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_personal_best_projection().on_insert(...)`.
|
||||
pub struct BarkBattlePersonalBestProjectionTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<BarkBattlePersonalBestProjectionRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `bark_battle_personal_best_projection`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait BarkBattlePersonalBestProjectionTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`BarkBattlePersonalBestProjectionTableHandle`], which mediates access to the table `bark_battle_personal_best_projection`.
|
||||
fn bark_battle_personal_best_projection(
|
||||
&self,
|
||||
) -> BarkBattlePersonalBestProjectionTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl BarkBattlePersonalBestProjectionTableAccess for super::RemoteTables {
|
||||
fn bark_battle_personal_best_projection(
|
||||
&self,
|
||||
) -> BarkBattlePersonalBestProjectionTableHandle<'_> {
|
||||
BarkBattlePersonalBestProjectionTableHandle {
|
||||
imp: self.imp.get_table::<BarkBattlePersonalBestProjectionRow>(
|
||||
"bark_battle_personal_best_projection",
|
||||
),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattlePersonalBestProjectionInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct BarkBattlePersonalBestProjectionDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for BarkBattlePersonalBestProjectionTableHandle<'ctx> {
|
||||
type Row = BarkBattlePersonalBestProjectionRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = BarkBattlePersonalBestProjectionRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = BarkBattlePersonalBestProjectionInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattlePersonalBestProjectionInsertCallbackId {
|
||||
BarkBattlePersonalBestProjectionInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: BarkBattlePersonalBestProjectionInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = BarkBattlePersonalBestProjectionDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattlePersonalBestProjectionDeleteCallbackId {
|
||||
BarkBattlePersonalBestProjectionDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: BarkBattlePersonalBestProjectionDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattlePersonalBestProjectionUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for BarkBattlePersonalBestProjectionTableHandle<'ctx> {
|
||||
type UpdateCallbackId = BarkBattlePersonalBestProjectionUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattlePersonalBestProjectionUpdateCallbackId {
|
||||
BarkBattlePersonalBestProjectionUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: BarkBattlePersonalBestProjectionUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `personal_best_id` unique index on the table `bark_battle_personal_best_projection`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`BarkBattlePersonalBestProjectionPersonalBestIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_personal_best_projection().personal_best_id().find(...)`.
|
||||
pub struct BarkBattlePersonalBestProjectionPersonalBestIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<BarkBattlePersonalBestProjectionRow, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattlePersonalBestProjectionTableHandle<'ctx> {
|
||||
/// Get a handle on the `personal_best_id` unique index on the table `bark_battle_personal_best_projection`.
|
||||
pub fn personal_best_id(&self) -> BarkBattlePersonalBestProjectionPersonalBestIdUnique<'ctx> {
|
||||
BarkBattlePersonalBestProjectionPersonalBestIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("personal_best_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattlePersonalBestProjectionPersonalBestIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `personal_best_id` column value is equal to `col_val`,
|
||||
/// if such a row is present in the client cache.
|
||||
pub fn find(&self, col_val: &String) -> Option<BarkBattlePersonalBestProjectionRow> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache.get_or_make_table::<BarkBattlePersonalBestProjectionRow>(
|
||||
"bark_battle_personal_best_projection",
|
||||
);
|
||||
_table.add_unique_constraint::<String>("personal_best_id", |row| &row.personal_best_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<BarkBattlePersonalBestProjectionRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse(
|
||||
"TableUpdate<BarkBattlePersonalBestProjectionRow>",
|
||||
"TableUpdate",
|
||||
)
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `BarkBattlePersonalBestProjectionRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait bark_battle_personal_best_projectionQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `BarkBattlePersonalBestProjectionRow`.
|
||||
fn bark_battle_personal_best_projection(
|
||||
&self,
|
||||
) -> __sdk::__query_builder::Table<BarkBattlePersonalBestProjectionRow>;
|
||||
}
|
||||
|
||||
impl bark_battle_personal_best_projectionQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn bark_battle_personal_best_projection(
|
||||
&self,
|
||||
) -> __sdk::__query_builder::Table<BarkBattlePersonalBestProjectionRow> {
|
||||
__sdk::__query_builder::Table::new("bark_battle_personal_best_projection")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// 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 BarkBattleProcedureResult {
|
||||
pub ok: bool,
|
||||
pub row_json: Option<String>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleProcedureResult {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
// 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 BarkBattlePublishedConfigRow {
|
||||
pub work_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub source_draft_id: Option<String>,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub config_json: String,
|
||||
pub published_snapshot_json: String,
|
||||
pub created_at: __sdk::Timestamp,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
pub published_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattlePublishedConfigRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `BarkBattlePublishedConfigRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct BarkBattlePublishedConfigRowCols {
|
||||
pub work_id: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, String>,
|
||||
pub source_draft_id: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, Option<String>>,
|
||||
pub config_version: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, u64>,
|
||||
pub ruleset_version: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, String>,
|
||||
pub difficulty_preset: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, String>,
|
||||
pub leaderboard_enabled: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, bool>,
|
||||
pub config_json: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, String>,
|
||||
pub published_snapshot_json: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, String>,
|
||||
pub created_at: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, __sdk::Timestamp>,
|
||||
pub updated_at: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, __sdk::Timestamp>,
|
||||
pub published_at: __sdk::__query_builder::Col<BarkBattlePublishedConfigRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for BarkBattlePublishedConfigRow {
|
||||
type Cols = BarkBattlePublishedConfigRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
BarkBattlePublishedConfigRowCols {
|
||||
work_id: __sdk::__query_builder::Col::new(table_name, "work_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
source_draft_id: __sdk::__query_builder::Col::new(table_name, "source_draft_id"),
|
||||
config_version: __sdk::__query_builder::Col::new(table_name, "config_version"),
|
||||
ruleset_version: __sdk::__query_builder::Col::new(table_name, "ruleset_version"),
|
||||
difficulty_preset: __sdk::__query_builder::Col::new(table_name, "difficulty_preset"),
|
||||
leaderboard_enabled: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"leaderboard_enabled",
|
||||
),
|
||||
config_json: __sdk::__query_builder::Col::new(table_name, "config_json"),
|
||||
published_snapshot_json: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"published_snapshot_json",
|
||||
),
|
||||
created_at: __sdk::__query_builder::Col::new(table_name, "created_at"),
|
||||
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 `BarkBattlePublishedConfigRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct BarkBattlePublishedConfigRowIxCols {
|
||||
pub owner_user_id: __sdk::__query_builder::IxCol<BarkBattlePublishedConfigRow, String>,
|
||||
pub work_id: __sdk::__query_builder::IxCol<BarkBattlePublishedConfigRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for BarkBattlePublishedConfigRow {
|
||||
type IxCols = BarkBattlePublishedConfigRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
BarkBattlePublishedConfigRowIxCols {
|
||||
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
|
||||
work_id: __sdk::__query_builder::IxCol::new(table_name, "work_id"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for BarkBattlePublishedConfigRow {}
|
||||
@@ -0,0 +1,169 @@
|
||||
// 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 super::bark_battle_published_config_row_type::BarkBattlePublishedConfigRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `bark_battle_published_config`.
|
||||
///
|
||||
/// Obtain a handle from the [`BarkBattlePublishedConfigTableAccess::bark_battle_published_config`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.bark_battle_published_config()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_published_config().on_insert(...)`.
|
||||
pub struct BarkBattlePublishedConfigTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<BarkBattlePublishedConfigRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `bark_battle_published_config`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait BarkBattlePublishedConfigTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`BarkBattlePublishedConfigTableHandle`], which mediates access to the table `bark_battle_published_config`.
|
||||
fn bark_battle_published_config(&self) -> BarkBattlePublishedConfigTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl BarkBattlePublishedConfigTableAccess for super::RemoteTables {
|
||||
fn bark_battle_published_config(&self) -> BarkBattlePublishedConfigTableHandle<'_> {
|
||||
BarkBattlePublishedConfigTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<BarkBattlePublishedConfigRow>("bark_battle_published_config"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattlePublishedConfigInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct BarkBattlePublishedConfigDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for BarkBattlePublishedConfigTableHandle<'ctx> {
|
||||
type Row = BarkBattlePublishedConfigRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = BarkBattlePublishedConfigRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = BarkBattlePublishedConfigInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattlePublishedConfigInsertCallbackId {
|
||||
BarkBattlePublishedConfigInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: BarkBattlePublishedConfigInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = BarkBattlePublishedConfigDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattlePublishedConfigDeleteCallbackId {
|
||||
BarkBattlePublishedConfigDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: BarkBattlePublishedConfigDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattlePublishedConfigUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for BarkBattlePublishedConfigTableHandle<'ctx> {
|
||||
type UpdateCallbackId = BarkBattlePublishedConfigUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattlePublishedConfigUpdateCallbackId {
|
||||
BarkBattlePublishedConfigUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: BarkBattlePublishedConfigUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `work_id` unique index on the table `bark_battle_published_config`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`BarkBattlePublishedConfigWorkIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_published_config().work_id().find(...)`.
|
||||
pub struct BarkBattlePublishedConfigWorkIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<BarkBattlePublishedConfigRow, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattlePublishedConfigTableHandle<'ctx> {
|
||||
/// Get a handle on the `work_id` unique index on the table `bark_battle_published_config`.
|
||||
pub fn work_id(&self) -> BarkBattlePublishedConfigWorkIdUnique<'ctx> {
|
||||
BarkBattlePublishedConfigWorkIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("work_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattlePublishedConfigWorkIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `work_id` column value is equal to `col_val`,
|
||||
/// if such a row is present in the client cache.
|
||||
pub fn find(&self, col_val: &String) -> Option<BarkBattlePublishedConfigRow> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache
|
||||
.get_or_make_table::<BarkBattlePublishedConfigRow>("bark_battle_published_config");
|
||||
_table.add_unique_constraint::<String>("work_id", |row| &row.work_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<BarkBattlePublishedConfigRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse(
|
||||
"TableUpdate<BarkBattlePublishedConfigRow>",
|
||||
"TableUpdate",
|
||||
)
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `BarkBattlePublishedConfigRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait bark_battle_published_configQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `BarkBattlePublishedConfigRow`.
|
||||
fn bark_battle_published_config(
|
||||
&self,
|
||||
) -> __sdk::__query_builder::Table<BarkBattlePublishedConfigRow>;
|
||||
}
|
||||
|
||||
impl bark_battle_published_configQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn bark_battle_published_config(
|
||||
&self,
|
||||
) -> __sdk::__query_builder::Table<BarkBattlePublishedConfigRow> {
|
||||
__sdk::__query_builder::Table::new("bark_battle_published_config")
|
||||
}
|
||||
}
|
||||
@@ -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 BarkBattleRunFinishInput {
|
||||
pub run_id: String,
|
||||
pub run_token: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub client_finished_at_micros: i64,
|
||||
pub server_finished_at_micros: i64,
|
||||
pub duration_ms: u64,
|
||||
pub trigger_count: u64,
|
||||
pub max_volume_millis: u32,
|
||||
pub average_volume_millis: u32,
|
||||
pub final_energy_millis: u32,
|
||||
pub opponent_final_energy_millis: u32,
|
||||
pub max_combo: u32,
|
||||
pub metrics_json: String,
|
||||
pub derived_metrics_json: String,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleRunFinishInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// 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 BarkBattleRunGetInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleRunGetInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// 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 BarkBattleRunStartInput {
|
||||
pub run_id: String,
|
||||
pub run_token: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub client_started_at_micros: i64,
|
||||
pub server_started_at_micros: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleRunStartInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// 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 BarkBattleRuntimeConfigGetInput {
|
||||
pub work_id: String,
|
||||
pub owner_user_id: Option<String>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleRuntimeConfigGetInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
// 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 BarkBattleRuntimeRunRow {
|
||||
pub run_id: String,
|
||||
pub run_token_hash: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub status: String,
|
||||
pub client_started_at_micros: i64,
|
||||
pub server_started_at: __sdk::Timestamp,
|
||||
pub client_finished_at_micros: Option<i64>,
|
||||
pub server_finished_at: Option<__sdk::Timestamp>,
|
||||
pub metrics_json: String,
|
||||
pub server_result: Option<String>,
|
||||
pub validation_status: String,
|
||||
pub anti_cheat_flags_json: String,
|
||||
pub leaderboard_score: Option<u64>,
|
||||
pub score_id: Option<String>,
|
||||
pub created_at: __sdk::Timestamp,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleRuntimeRunRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `BarkBattleRuntimeRunRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct BarkBattleRuntimeRunRowCols {
|
||||
pub run_id: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, String>,
|
||||
pub run_token_hash: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, String>,
|
||||
pub work_id: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, String>,
|
||||
pub config_version: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, u64>,
|
||||
pub ruleset_version: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, String>,
|
||||
pub difficulty_preset: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, String>,
|
||||
pub leaderboard_enabled: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, bool>,
|
||||
pub status: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, String>,
|
||||
pub client_started_at_micros: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, i64>,
|
||||
pub server_started_at: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, __sdk::Timestamp>,
|
||||
pub client_finished_at_micros:
|
||||
__sdk::__query_builder::Col<BarkBattleRuntimeRunRow, Option<i64>>,
|
||||
pub server_finished_at:
|
||||
__sdk::__query_builder::Col<BarkBattleRuntimeRunRow, Option<__sdk::Timestamp>>,
|
||||
pub metrics_json: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, String>,
|
||||
pub server_result: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, Option<String>>,
|
||||
pub validation_status: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, String>,
|
||||
pub anti_cheat_flags_json: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, String>,
|
||||
pub leaderboard_score: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, Option<u64>>,
|
||||
pub score_id: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, Option<String>>,
|
||||
pub created_at: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, __sdk::Timestamp>,
|
||||
pub updated_at: __sdk::__query_builder::Col<BarkBattleRuntimeRunRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for BarkBattleRuntimeRunRow {
|
||||
type Cols = BarkBattleRuntimeRunRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
BarkBattleRuntimeRunRowCols {
|
||||
run_id: __sdk::__query_builder::Col::new(table_name, "run_id"),
|
||||
run_token_hash: __sdk::__query_builder::Col::new(table_name, "run_token_hash"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
work_id: __sdk::__query_builder::Col::new(table_name, "work_id"),
|
||||
config_version: __sdk::__query_builder::Col::new(table_name, "config_version"),
|
||||
ruleset_version: __sdk::__query_builder::Col::new(table_name, "ruleset_version"),
|
||||
difficulty_preset: __sdk::__query_builder::Col::new(table_name, "difficulty_preset"),
|
||||
leaderboard_enabled: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"leaderboard_enabled",
|
||||
),
|
||||
status: __sdk::__query_builder::Col::new(table_name, "status"),
|
||||
client_started_at_micros: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"client_started_at_micros",
|
||||
),
|
||||
server_started_at: __sdk::__query_builder::Col::new(table_name, "server_started_at"),
|
||||
client_finished_at_micros: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"client_finished_at_micros",
|
||||
),
|
||||
server_finished_at: __sdk::__query_builder::Col::new(table_name, "server_finished_at"),
|
||||
metrics_json: __sdk::__query_builder::Col::new(table_name, "metrics_json"),
|
||||
server_result: __sdk::__query_builder::Col::new(table_name, "server_result"),
|
||||
validation_status: __sdk::__query_builder::Col::new(table_name, "validation_status"),
|
||||
anti_cheat_flags_json: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"anti_cheat_flags_json",
|
||||
),
|
||||
leaderboard_score: __sdk::__query_builder::Col::new(table_name, "leaderboard_score"),
|
||||
score_id: __sdk::__query_builder::Col::new(table_name, "score_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 `BarkBattleRuntimeRunRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct BarkBattleRuntimeRunRowIxCols {
|
||||
pub owner_user_id: __sdk::__query_builder::IxCol<BarkBattleRuntimeRunRow, String>,
|
||||
pub run_id: __sdk::__query_builder::IxCol<BarkBattleRuntimeRunRow, String>,
|
||||
pub work_id: __sdk::__query_builder::IxCol<BarkBattleRuntimeRunRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for BarkBattleRuntimeRunRow {
|
||||
type IxCols = BarkBattleRuntimeRunRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
BarkBattleRuntimeRunRowIxCols {
|
||||
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
|
||||
run_id: __sdk::__query_builder::IxCol::new(table_name, "run_id"),
|
||||
work_id: __sdk::__query_builder::IxCol::new(table_name, "work_id"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for BarkBattleRuntimeRunRow {}
|
||||
@@ -0,0 +1,162 @@
|
||||
// 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 super::bark_battle_runtime_run_row_type::BarkBattleRuntimeRunRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `bark_battle_runtime_run`.
|
||||
///
|
||||
/// Obtain a handle from the [`BarkBattleRuntimeRunTableAccess::bark_battle_runtime_run`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.bark_battle_runtime_run()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_runtime_run().on_insert(...)`.
|
||||
pub struct BarkBattleRuntimeRunTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<BarkBattleRuntimeRunRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `bark_battle_runtime_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait BarkBattleRuntimeRunTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`BarkBattleRuntimeRunTableHandle`], which mediates access to the table `bark_battle_runtime_run`.
|
||||
fn bark_battle_runtime_run(&self) -> BarkBattleRuntimeRunTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl BarkBattleRuntimeRunTableAccess for super::RemoteTables {
|
||||
fn bark_battle_runtime_run(&self) -> BarkBattleRuntimeRunTableHandle<'_> {
|
||||
BarkBattleRuntimeRunTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<BarkBattleRuntimeRunRow>("bark_battle_runtime_run"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattleRuntimeRunInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct BarkBattleRuntimeRunDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for BarkBattleRuntimeRunTableHandle<'ctx> {
|
||||
type Row = BarkBattleRuntimeRunRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = BarkBattleRuntimeRunRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = BarkBattleRuntimeRunInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleRuntimeRunInsertCallbackId {
|
||||
BarkBattleRuntimeRunInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: BarkBattleRuntimeRunInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = BarkBattleRuntimeRunDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleRuntimeRunDeleteCallbackId {
|
||||
BarkBattleRuntimeRunDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: BarkBattleRuntimeRunDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattleRuntimeRunUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for BarkBattleRuntimeRunTableHandle<'ctx> {
|
||||
type UpdateCallbackId = BarkBattleRuntimeRunUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleRuntimeRunUpdateCallbackId {
|
||||
BarkBattleRuntimeRunUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: BarkBattleRuntimeRunUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `run_id` unique index on the table `bark_battle_runtime_run`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`BarkBattleRuntimeRunRunIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_runtime_run().run_id().find(...)`.
|
||||
pub struct BarkBattleRuntimeRunRunIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<BarkBattleRuntimeRunRow, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattleRuntimeRunTableHandle<'ctx> {
|
||||
/// Get a handle on the `run_id` unique index on the table `bark_battle_runtime_run`.
|
||||
pub fn run_id(&self) -> BarkBattleRuntimeRunRunIdUnique<'ctx> {
|
||||
BarkBattleRuntimeRunRunIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("run_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattleRuntimeRunRunIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `run_id` column value is equal to `col_val`,
|
||||
/// if such a row is present in the client cache.
|
||||
pub fn find(&self, col_val: &String) -> Option<BarkBattleRuntimeRunRow> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table =
|
||||
client_cache.get_or_make_table::<BarkBattleRuntimeRunRow>("bark_battle_runtime_run");
|
||||
_table.add_unique_constraint::<String>("run_id", |row| &row.run_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<BarkBattleRuntimeRunRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<BarkBattleRuntimeRunRow>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `BarkBattleRuntimeRunRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait bark_battle_runtime_runQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `BarkBattleRuntimeRunRow`.
|
||||
fn bark_battle_runtime_run(&self) -> __sdk::__query_builder::Table<BarkBattleRuntimeRunRow>;
|
||||
}
|
||||
|
||||
impl bark_battle_runtime_runQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn bark_battle_runtime_run(&self) -> __sdk::__query_builder::Table<BarkBattleRuntimeRunRow> {
|
||||
__sdk::__query_builder::Table::new("bark_battle_runtime_run")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
// 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 BarkBattleScoreRecordRow {
|
||||
pub score_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub run_id: String,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub metrics_json: String,
|
||||
pub derived_metrics_json: String,
|
||||
pub server_result: String,
|
||||
pub validation_status: String,
|
||||
pub anti_cheat_flags_json: String,
|
||||
pub leaderboard_score: Option<u64>,
|
||||
pub recorded_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleScoreRecordRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `BarkBattleScoreRecordRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct BarkBattleScoreRecordRowCols {
|
||||
pub score_id: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, String>,
|
||||
pub work_id: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, String>,
|
||||
pub run_id: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, String>,
|
||||
pub config_version: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, u64>,
|
||||
pub ruleset_version: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, String>,
|
||||
pub difficulty_preset: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, String>,
|
||||
pub leaderboard_enabled: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, bool>,
|
||||
pub metrics_json: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, String>,
|
||||
pub derived_metrics_json: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, String>,
|
||||
pub server_result: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, String>,
|
||||
pub validation_status: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, String>,
|
||||
pub anti_cheat_flags_json: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, String>,
|
||||
pub leaderboard_score: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, Option<u64>>,
|
||||
pub recorded_at: __sdk::__query_builder::Col<BarkBattleScoreRecordRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for BarkBattleScoreRecordRow {
|
||||
type Cols = BarkBattleScoreRecordRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
BarkBattleScoreRecordRowCols {
|
||||
score_id: __sdk::__query_builder::Col::new(table_name, "score_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
work_id: __sdk::__query_builder::Col::new(table_name, "work_id"),
|
||||
run_id: __sdk::__query_builder::Col::new(table_name, "run_id"),
|
||||
config_version: __sdk::__query_builder::Col::new(table_name, "config_version"),
|
||||
ruleset_version: __sdk::__query_builder::Col::new(table_name, "ruleset_version"),
|
||||
difficulty_preset: __sdk::__query_builder::Col::new(table_name, "difficulty_preset"),
|
||||
leaderboard_enabled: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"leaderboard_enabled",
|
||||
),
|
||||
metrics_json: __sdk::__query_builder::Col::new(table_name, "metrics_json"),
|
||||
derived_metrics_json: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"derived_metrics_json",
|
||||
),
|
||||
server_result: __sdk::__query_builder::Col::new(table_name, "server_result"),
|
||||
validation_status: __sdk::__query_builder::Col::new(table_name, "validation_status"),
|
||||
anti_cheat_flags_json: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"anti_cheat_flags_json",
|
||||
),
|
||||
leaderboard_score: __sdk::__query_builder::Col::new(table_name, "leaderboard_score"),
|
||||
recorded_at: __sdk::__query_builder::Col::new(table_name, "recorded_at"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indexed column accessor struct for the table `BarkBattleScoreRecordRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct BarkBattleScoreRecordRowIxCols {
|
||||
pub owner_user_id: __sdk::__query_builder::IxCol<BarkBattleScoreRecordRow, String>,
|
||||
pub run_id: __sdk::__query_builder::IxCol<BarkBattleScoreRecordRow, String>,
|
||||
pub score_id: __sdk::__query_builder::IxCol<BarkBattleScoreRecordRow, String>,
|
||||
pub work_id: __sdk::__query_builder::IxCol<BarkBattleScoreRecordRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for BarkBattleScoreRecordRow {
|
||||
type IxCols = BarkBattleScoreRecordRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
BarkBattleScoreRecordRowIxCols {
|
||||
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
|
||||
run_id: __sdk::__query_builder::IxCol::new(table_name, "run_id"),
|
||||
score_id: __sdk::__query_builder::IxCol::new(table_name, "score_id"),
|
||||
work_id: __sdk::__query_builder::IxCol::new(table_name, "work_id"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for BarkBattleScoreRecordRow {}
|
||||
@@ -0,0 +1,162 @@
|
||||
// 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 super::bark_battle_score_record_row_type::BarkBattleScoreRecordRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `bark_battle_score_record`.
|
||||
///
|
||||
/// Obtain a handle from the [`BarkBattleScoreRecordTableAccess::bark_battle_score_record`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.bark_battle_score_record()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_score_record().on_insert(...)`.
|
||||
pub struct BarkBattleScoreRecordTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<BarkBattleScoreRecordRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `bark_battle_score_record`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait BarkBattleScoreRecordTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`BarkBattleScoreRecordTableHandle`], which mediates access to the table `bark_battle_score_record`.
|
||||
fn bark_battle_score_record(&self) -> BarkBattleScoreRecordTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl BarkBattleScoreRecordTableAccess for super::RemoteTables {
|
||||
fn bark_battle_score_record(&self) -> BarkBattleScoreRecordTableHandle<'_> {
|
||||
BarkBattleScoreRecordTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<BarkBattleScoreRecordRow>("bark_battle_score_record"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattleScoreRecordInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct BarkBattleScoreRecordDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for BarkBattleScoreRecordTableHandle<'ctx> {
|
||||
type Row = BarkBattleScoreRecordRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = BarkBattleScoreRecordRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = BarkBattleScoreRecordInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleScoreRecordInsertCallbackId {
|
||||
BarkBattleScoreRecordInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: BarkBattleScoreRecordInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = BarkBattleScoreRecordDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleScoreRecordDeleteCallbackId {
|
||||
BarkBattleScoreRecordDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: BarkBattleScoreRecordDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattleScoreRecordUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for BarkBattleScoreRecordTableHandle<'ctx> {
|
||||
type UpdateCallbackId = BarkBattleScoreRecordUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleScoreRecordUpdateCallbackId {
|
||||
BarkBattleScoreRecordUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: BarkBattleScoreRecordUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `score_id` unique index on the table `bark_battle_score_record`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`BarkBattleScoreRecordScoreIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_score_record().score_id().find(...)`.
|
||||
pub struct BarkBattleScoreRecordScoreIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<BarkBattleScoreRecordRow, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattleScoreRecordTableHandle<'ctx> {
|
||||
/// Get a handle on the `score_id` unique index on the table `bark_battle_score_record`.
|
||||
pub fn score_id(&self) -> BarkBattleScoreRecordScoreIdUnique<'ctx> {
|
||||
BarkBattleScoreRecordScoreIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("score_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattleScoreRecordScoreIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `score_id` column value is equal to `col_val`,
|
||||
/// if such a row is present in the client cache.
|
||||
pub fn find(&self, col_val: &String) -> Option<BarkBattleScoreRecordRow> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table =
|
||||
client_cache.get_or_make_table::<BarkBattleScoreRecordRow>("bark_battle_score_record");
|
||||
_table.add_unique_constraint::<String>("score_id", |row| &row.score_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<BarkBattleScoreRecordRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<BarkBattleScoreRecordRow>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `BarkBattleScoreRecordRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait bark_battle_score_recordQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `BarkBattleScoreRecordRow`.
|
||||
fn bark_battle_score_record(&self) -> __sdk::__query_builder::Table<BarkBattleScoreRecordRow>;
|
||||
}
|
||||
|
||||
impl bark_battle_score_recordQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn bark_battle_score_record(&self) -> __sdk::__query_builder::Table<BarkBattleScoreRecordRow> {
|
||||
__sdk::__query_builder::Table::new("bark_battle_score_record")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct BarkBattleWorkPublishInput {
|
||||
pub draft_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub published_snapshot_json: Option<String>,
|
||||
pub published_at_micros: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleWorkPublishInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
// 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 BarkBattleWorkStatsProjectionRow {
|
||||
pub work_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub play_count: u64,
|
||||
pub finished_count: u64,
|
||||
pub accepted_score_count: u64,
|
||||
pub leaderboard_entry_count: u64,
|
||||
pub best_leaderboard_score: Option<u64>,
|
||||
pub best_score_id: Option<String>,
|
||||
pub best_run_id: Option<String>,
|
||||
pub average_final_energy: f32,
|
||||
pub average_trigger_count: f32,
|
||||
pub last_finished_at_micros: Option<i64>,
|
||||
pub stats_json: String,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for BarkBattleWorkStatsProjectionRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `BarkBattleWorkStatsProjectionRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct BarkBattleWorkStatsProjectionRowCols {
|
||||
pub work_id: __sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, String>,
|
||||
pub play_count: __sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, u64>,
|
||||
pub finished_count: __sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, u64>,
|
||||
pub accepted_score_count: __sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, u64>,
|
||||
pub leaderboard_entry_count: __sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, u64>,
|
||||
pub best_leaderboard_score:
|
||||
__sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, Option<u64>>,
|
||||
pub best_score_id:
|
||||
__sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, Option<String>>,
|
||||
pub best_run_id: __sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, Option<String>>,
|
||||
pub average_final_energy: __sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, f32>,
|
||||
pub average_trigger_count: __sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, f32>,
|
||||
pub last_finished_at_micros:
|
||||
__sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, Option<i64>>,
|
||||
pub stats_json: __sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, String>,
|
||||
pub updated_at: __sdk::__query_builder::Col<BarkBattleWorkStatsProjectionRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for BarkBattleWorkStatsProjectionRow {
|
||||
type Cols = BarkBattleWorkStatsProjectionRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
BarkBattleWorkStatsProjectionRowCols {
|
||||
work_id: __sdk::__query_builder::Col::new(table_name, "work_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
play_count: __sdk::__query_builder::Col::new(table_name, "play_count"),
|
||||
finished_count: __sdk::__query_builder::Col::new(table_name, "finished_count"),
|
||||
accepted_score_count: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"accepted_score_count",
|
||||
),
|
||||
leaderboard_entry_count: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"leaderboard_entry_count",
|
||||
),
|
||||
best_leaderboard_score: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"best_leaderboard_score",
|
||||
),
|
||||
best_score_id: __sdk::__query_builder::Col::new(table_name, "best_score_id"),
|
||||
best_run_id: __sdk::__query_builder::Col::new(table_name, "best_run_id"),
|
||||
average_final_energy: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"average_final_energy",
|
||||
),
|
||||
average_trigger_count: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"average_trigger_count",
|
||||
),
|
||||
last_finished_at_micros: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"last_finished_at_micros",
|
||||
),
|
||||
stats_json: __sdk::__query_builder::Col::new(table_name, "stats_json"),
|
||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indexed column accessor struct for the table `BarkBattleWorkStatsProjectionRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct BarkBattleWorkStatsProjectionRowIxCols {
|
||||
pub owner_user_id: __sdk::__query_builder::IxCol<BarkBattleWorkStatsProjectionRow, String>,
|
||||
pub work_id: __sdk::__query_builder::IxCol<BarkBattleWorkStatsProjectionRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for BarkBattleWorkStatsProjectionRow {
|
||||
type IxCols = BarkBattleWorkStatsProjectionRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
BarkBattleWorkStatsProjectionRowIxCols {
|
||||
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
|
||||
work_id: __sdk::__query_builder::IxCol::new(table_name, "work_id"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for BarkBattleWorkStatsProjectionRow {}
|
||||
@@ -0,0 +1,169 @@
|
||||
// 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 super::bark_battle_work_stats_projection_row_type::BarkBattleWorkStatsProjectionRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `bark_battle_work_stats_projection`.
|
||||
///
|
||||
/// Obtain a handle from the [`BarkBattleWorkStatsProjectionTableAccess::bark_battle_work_stats_projection`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.bark_battle_work_stats_projection()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_work_stats_projection().on_insert(...)`.
|
||||
pub struct BarkBattleWorkStatsProjectionTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<BarkBattleWorkStatsProjectionRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `bark_battle_work_stats_projection`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait BarkBattleWorkStatsProjectionTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`BarkBattleWorkStatsProjectionTableHandle`], which mediates access to the table `bark_battle_work_stats_projection`.
|
||||
fn bark_battle_work_stats_projection(&self) -> BarkBattleWorkStatsProjectionTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl BarkBattleWorkStatsProjectionTableAccess for super::RemoteTables {
|
||||
fn bark_battle_work_stats_projection(&self) -> BarkBattleWorkStatsProjectionTableHandle<'_> {
|
||||
BarkBattleWorkStatsProjectionTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<BarkBattleWorkStatsProjectionRow>("bark_battle_work_stats_projection"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattleWorkStatsProjectionInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct BarkBattleWorkStatsProjectionDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for BarkBattleWorkStatsProjectionTableHandle<'ctx> {
|
||||
type Row = BarkBattleWorkStatsProjectionRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = BarkBattleWorkStatsProjectionRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = BarkBattleWorkStatsProjectionInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleWorkStatsProjectionInsertCallbackId {
|
||||
BarkBattleWorkStatsProjectionInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: BarkBattleWorkStatsProjectionInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = BarkBattleWorkStatsProjectionDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleWorkStatsProjectionDeleteCallbackId {
|
||||
BarkBattleWorkStatsProjectionDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: BarkBattleWorkStatsProjectionDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BarkBattleWorkStatsProjectionUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for BarkBattleWorkStatsProjectionTableHandle<'ctx> {
|
||||
type UpdateCallbackId = BarkBattleWorkStatsProjectionUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> BarkBattleWorkStatsProjectionUpdateCallbackId {
|
||||
BarkBattleWorkStatsProjectionUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: BarkBattleWorkStatsProjectionUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `work_id` unique index on the table `bark_battle_work_stats_projection`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`BarkBattleWorkStatsProjectionWorkIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.bark_battle_work_stats_projection().work_id().find(...)`.
|
||||
pub struct BarkBattleWorkStatsProjectionWorkIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<BarkBattleWorkStatsProjectionRow, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattleWorkStatsProjectionTableHandle<'ctx> {
|
||||
/// Get a handle on the `work_id` unique index on the table `bark_battle_work_stats_projection`.
|
||||
pub fn work_id(&self) -> BarkBattleWorkStatsProjectionWorkIdUnique<'ctx> {
|
||||
BarkBattleWorkStatsProjectionWorkIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("work_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> BarkBattleWorkStatsProjectionWorkIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `work_id` column value is equal to `col_val`,
|
||||
/// if such a row is present in the client cache.
|
||||
pub fn find(&self, col_val: &String) -> Option<BarkBattleWorkStatsProjectionRow> {
|
||||
self.imp.find(col_val)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache
|
||||
.get_or_make_table::<BarkBattleWorkStatsProjectionRow>("bark_battle_work_stats_projection");
|
||||
_table.add_unique_constraint::<String>("work_id", |row| &row.work_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<BarkBattleWorkStatsProjectionRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse(
|
||||
"TableUpdate<BarkBattleWorkStatsProjectionRow>",
|
||||
"TableUpdate",
|
||||
)
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `BarkBattleWorkStatsProjectionRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait bark_battle_work_stats_projectionQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `BarkBattleWorkStatsProjectionRow`.
|
||||
fn bark_battle_work_stats_projection(
|
||||
&self,
|
||||
) -> __sdk::__query_builder::Table<BarkBattleWorkStatsProjectionRow>;
|
||||
}
|
||||
|
||||
impl bark_battle_work_stats_projectionQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn bark_battle_work_stats_projection(
|
||||
&self,
|
||||
) -> __sdk::__query_builder::Table<BarkBattleWorkStatsProjectionRow> {
|
||||
__sdk::__query_builder::Table::new("bark_battle_work_stats_projection")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::bark_battle_draft_create_input_type::BarkBattleDraftCreateInput;
|
||||
use super::bark_battle_procedure_result_type::BarkBattleProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct CreateBarkBattleDraftArgs {
|
||||
pub input: BarkBattleDraftCreateInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for CreateBarkBattleDraftArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `create_bark_battle_draft`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait create_bark_battle_draft {
|
||||
fn create_bark_battle_draft(&self, input: BarkBattleDraftCreateInput) {
|
||||
self.create_bark_battle_draft_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn create_bark_battle_draft_then(
|
||||
&self,
|
||||
input: BarkBattleDraftCreateInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl create_bark_battle_draft for super::RemoteProcedures {
|
||||
fn create_bark_battle_draft_then(
|
||||
&self,
|
||||
input: BarkBattleDraftCreateInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, BarkBattleProcedureResult>(
|
||||
"create_bark_battle_draft",
|
||||
CreateBarkBattleDraftArgs { input },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::bark_battle_procedure_result_type::BarkBattleProcedureResult;
|
||||
use super::bark_battle_run_finish_input_type::BarkBattleRunFinishInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct FinishBarkBattleRunArgs {
|
||||
pub input: BarkBattleRunFinishInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for FinishBarkBattleRunArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `finish_bark_battle_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait finish_bark_battle_run {
|
||||
fn finish_bark_battle_run(&self, input: BarkBattleRunFinishInput) {
|
||||
self.finish_bark_battle_run_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn finish_bark_battle_run_then(
|
||||
&self,
|
||||
input: BarkBattleRunFinishInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl finish_bark_battle_run for super::RemoteProcedures {
|
||||
fn finish_bark_battle_run_then(
|
||||
&self,
|
||||
input: BarkBattleRunFinishInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, BarkBattleProcedureResult>(
|
||||
"finish_bark_battle_run",
|
||||
FinishBarkBattleRunArgs { input },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::bark_battle_procedure_result_type::BarkBattleProcedureResult;
|
||||
use super::bark_battle_run_get_input_type::BarkBattleRunGetInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct GetBarkBattleRunArgs {
|
||||
pub input: BarkBattleRunGetInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for GetBarkBattleRunArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `get_bark_battle_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait get_bark_battle_run {
|
||||
fn get_bark_battle_run(&self, input: BarkBattleRunGetInput) {
|
||||
self.get_bark_battle_run_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn get_bark_battle_run_then(
|
||||
&self,
|
||||
input: BarkBattleRunGetInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl get_bark_battle_run for super::RemoteProcedures {
|
||||
fn get_bark_battle_run_then(
|
||||
&self,
|
||||
input: BarkBattleRunGetInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, BarkBattleProcedureResult>(
|
||||
"get_bark_battle_run",
|
||||
GetBarkBattleRunArgs { input },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::bark_battle_procedure_result_type::BarkBattleProcedureResult;
|
||||
use super::bark_battle_runtime_config_get_input_type::BarkBattleRuntimeConfigGetInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct GetBarkBattleRuntimeConfigArgs {
|
||||
pub input: BarkBattleRuntimeConfigGetInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for GetBarkBattleRuntimeConfigArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `get_bark_battle_runtime_config`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait get_bark_battle_runtime_config {
|
||||
fn get_bark_battle_runtime_config(&self, input: BarkBattleRuntimeConfigGetInput) {
|
||||
self.get_bark_battle_runtime_config_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn get_bark_battle_runtime_config_then(
|
||||
&self,
|
||||
input: BarkBattleRuntimeConfigGetInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl get_bark_battle_runtime_config for super::RemoteProcedures {
|
||||
fn get_bark_battle_runtime_config_then(
|
||||
&self,
|
||||
input: BarkBattleRuntimeConfigGetInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, BarkBattleProcedureResult>(
|
||||
"get_bark_battle_runtime_config",
|
||||
GetBarkBattleRuntimeConfigArgs { input },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
// This was generated using spacetimedb cli version 2.1.0 (commit 6981f48b4bc1a71c8dd9bdfe5a2c343f6370243d).
|
||||
// This was generated using spacetimedb cli version 2.2.0 (commit eb11e2f5c41dce6979715ad407996270d61329f6).
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
@@ -90,6 +90,28 @@ pub mod auth_store_snapshot_table;
|
||||
pub mod auth_store_snapshot_type;
|
||||
pub mod auth_store_snapshot_upsert_input_type;
|
||||
pub mod authorize_database_migration_operator_procedure;
|
||||
pub mod bark_battle_draft_config_row_type;
|
||||
pub mod bark_battle_draft_config_table;
|
||||
pub mod bark_battle_draft_config_upsert_input_type;
|
||||
pub mod bark_battle_draft_create_input_type;
|
||||
pub mod bark_battle_leaderboard_entry_row_type;
|
||||
pub mod bark_battle_leaderboard_entry_table;
|
||||
pub mod bark_battle_personal_best_projection_row_type;
|
||||
pub mod bark_battle_personal_best_projection_table;
|
||||
pub mod bark_battle_procedure_result_type;
|
||||
pub mod bark_battle_published_config_row_type;
|
||||
pub mod bark_battle_published_config_table;
|
||||
pub mod bark_battle_run_finish_input_type;
|
||||
pub mod bark_battle_run_get_input_type;
|
||||
pub mod bark_battle_run_start_input_type;
|
||||
pub mod bark_battle_runtime_config_get_input_type;
|
||||
pub mod bark_battle_runtime_run_row_type;
|
||||
pub mod bark_battle_runtime_run_table;
|
||||
pub mod bark_battle_score_record_row_type;
|
||||
pub mod bark_battle_score_record_table;
|
||||
pub mod bark_battle_work_publish_input_type;
|
||||
pub mod bark_battle_work_stats_projection_row_type;
|
||||
pub mod bark_battle_work_stats_projection_table;
|
||||
pub mod battle_mode_type;
|
||||
pub mod battle_state_input_type;
|
||||
pub mod battle_state_procedure_result_type;
|
||||
@@ -179,6 +201,7 @@ pub mod continue_story_and_return_procedure;
|
||||
pub mod continue_story_reducer;
|
||||
pub mod create_ai_task_and_return_procedure;
|
||||
pub mod create_ai_task_reducer;
|
||||
pub mod create_bark_battle_draft_procedure;
|
||||
pub mod create_battle_state_and_return_procedure;
|
||||
pub mod create_battle_state_reducer;
|
||||
pub mod create_big_fish_session_procedure;
|
||||
@@ -296,10 +319,13 @@ pub mod finalize_match_3_d_agent_message_turn_procedure;
|
||||
pub mod finalize_puzzle_agent_message_turn_procedure;
|
||||
pub mod finalize_square_hole_agent_message_turn_procedure;
|
||||
pub mod finalize_visual_novel_agent_message_turn_procedure;
|
||||
pub mod finish_bark_battle_run_procedure;
|
||||
pub mod finish_match_3_d_time_up_procedure;
|
||||
pub mod finish_square_hole_time_up_procedure;
|
||||
pub mod generate_big_fish_asset_procedure;
|
||||
pub mod get_auth_store_snapshot_procedure;
|
||||
pub mod get_bark_battle_run_procedure;
|
||||
pub mod get_bark_battle_runtime_config_procedure;
|
||||
pub mod get_battle_state_procedure;
|
||||
pub mod get_big_fish_run_procedure;
|
||||
pub mod get_big_fish_session_procedure;
|
||||
@@ -450,6 +476,7 @@ pub mod public_work_like_table;
|
||||
pub mod public_work_like_type;
|
||||
pub mod public_work_play_daily_stat_table;
|
||||
pub mod public_work_play_daily_stat_type;
|
||||
pub mod publish_bark_battle_work_procedure;
|
||||
pub mod publish_big_fish_game_procedure;
|
||||
pub mod publish_custom_world_profile_and_return_procedure;
|
||||
pub mod publish_custom_world_profile_reducer;
|
||||
@@ -712,6 +739,7 @@ pub mod square_hole_works_list_input_type;
|
||||
pub mod square_hole_works_procedure_result_type;
|
||||
pub mod start_ai_task_reducer;
|
||||
pub mod start_ai_task_stage_reducer;
|
||||
pub mod start_bark_battle_run_procedure;
|
||||
pub mod start_big_fish_run_procedure;
|
||||
pub mod start_match_3_d_run_procedure;
|
||||
pub mod start_puzzle_run_procedure;
|
||||
@@ -756,6 +784,7 @@ pub mod turn_in_quest_reducer;
|
||||
pub mod unequip_inventory_item_input_type;
|
||||
pub mod unpublish_custom_world_profile_and_return_procedure;
|
||||
pub mod unpublish_custom_world_profile_reducer;
|
||||
pub mod update_bark_battle_draft_config_procedure;
|
||||
pub mod update_match_3_d_work_procedure;
|
||||
pub mod update_puzzle_run_pause_procedure;
|
||||
pub mod update_puzzle_work_procedure;
|
||||
@@ -898,6 +927,28 @@ pub use auth_store_snapshot_table::*;
|
||||
pub use auth_store_snapshot_type::AuthStoreSnapshot;
|
||||
pub use auth_store_snapshot_upsert_input_type::AuthStoreSnapshotUpsertInput;
|
||||
pub use authorize_database_migration_operator_procedure::authorize_database_migration_operator;
|
||||
pub use bark_battle_draft_config_row_type::BarkBattleDraftConfigRow;
|
||||
pub use bark_battle_draft_config_table::*;
|
||||
pub use bark_battle_draft_config_upsert_input_type::BarkBattleDraftConfigUpsertInput;
|
||||
pub use bark_battle_draft_create_input_type::BarkBattleDraftCreateInput;
|
||||
pub use bark_battle_leaderboard_entry_row_type::BarkBattleLeaderboardEntryRow;
|
||||
pub use bark_battle_leaderboard_entry_table::*;
|
||||
pub use bark_battle_personal_best_projection_row_type::BarkBattlePersonalBestProjectionRow;
|
||||
pub use bark_battle_personal_best_projection_table::*;
|
||||
pub use bark_battle_procedure_result_type::BarkBattleProcedureResult;
|
||||
pub use bark_battle_published_config_row_type::BarkBattlePublishedConfigRow;
|
||||
pub use bark_battle_published_config_table::*;
|
||||
pub use bark_battle_run_finish_input_type::BarkBattleRunFinishInput;
|
||||
pub use bark_battle_run_get_input_type::BarkBattleRunGetInput;
|
||||
pub use bark_battle_run_start_input_type::BarkBattleRunStartInput;
|
||||
pub use bark_battle_runtime_config_get_input_type::BarkBattleRuntimeConfigGetInput;
|
||||
pub use bark_battle_runtime_run_row_type::BarkBattleRuntimeRunRow;
|
||||
pub use bark_battle_runtime_run_table::*;
|
||||
pub use bark_battle_score_record_row_type::BarkBattleScoreRecordRow;
|
||||
pub use bark_battle_score_record_table::*;
|
||||
pub use bark_battle_work_publish_input_type::BarkBattleWorkPublishInput;
|
||||
pub use bark_battle_work_stats_projection_row_type::BarkBattleWorkStatsProjectionRow;
|
||||
pub use bark_battle_work_stats_projection_table::*;
|
||||
pub use battle_mode_type::BattleMode;
|
||||
pub use battle_state_input_type::BattleStateInput;
|
||||
pub use battle_state_procedure_result_type::BattleStateProcedureResult;
|
||||
@@ -987,6 +1038,7 @@ pub use continue_story_and_return_procedure::continue_story_and_return;
|
||||
pub use continue_story_reducer::continue_story;
|
||||
pub use create_ai_task_and_return_procedure::create_ai_task_and_return;
|
||||
pub use create_ai_task_reducer::create_ai_task;
|
||||
pub use create_bark_battle_draft_procedure::create_bark_battle_draft;
|
||||
pub use create_battle_state_and_return_procedure::create_battle_state_and_return;
|
||||
pub use create_battle_state_reducer::create_battle_state;
|
||||
pub use create_big_fish_session_procedure::create_big_fish_session;
|
||||
@@ -1104,10 +1156,13 @@ pub use finalize_match_3_d_agent_message_turn_procedure::finalize_match_3_d_agen
|
||||
pub use finalize_puzzle_agent_message_turn_procedure::finalize_puzzle_agent_message_turn;
|
||||
pub use finalize_square_hole_agent_message_turn_procedure::finalize_square_hole_agent_message_turn;
|
||||
pub use finalize_visual_novel_agent_message_turn_procedure::finalize_visual_novel_agent_message_turn;
|
||||
pub use finish_bark_battle_run_procedure::finish_bark_battle_run;
|
||||
pub use finish_match_3_d_time_up_procedure::finish_match_3_d_time_up;
|
||||
pub use finish_square_hole_time_up_procedure::finish_square_hole_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_bark_battle_run_procedure::get_bark_battle_run;
|
||||
pub use get_bark_battle_runtime_config_procedure::get_bark_battle_runtime_config;
|
||||
pub use get_battle_state_procedure::get_battle_state;
|
||||
pub use get_big_fish_run_procedure::get_big_fish_run;
|
||||
pub use get_big_fish_session_procedure::get_big_fish_session;
|
||||
@@ -1258,6 +1313,7 @@ pub use public_work_like_table::*;
|
||||
pub use public_work_like_type::PublicWorkLike;
|
||||
pub use public_work_play_daily_stat_table::*;
|
||||
pub use public_work_play_daily_stat_type::PublicWorkPlayDailyStat;
|
||||
pub use publish_bark_battle_work_procedure::publish_bark_battle_work;
|
||||
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_profile_reducer::publish_custom_world_profile;
|
||||
@@ -1520,6 +1576,7 @@ pub use square_hole_works_list_input_type::SquareHoleWorksListInput;
|
||||
pub use square_hole_works_procedure_result_type::SquareHoleWorksProcedureResult;
|
||||
pub use start_ai_task_reducer::start_ai_task;
|
||||
pub use start_ai_task_stage_reducer::start_ai_task_stage;
|
||||
pub use start_bark_battle_run_procedure::start_bark_battle_run;
|
||||
pub use start_big_fish_run_procedure::start_big_fish_run;
|
||||
pub use start_match_3_d_run_procedure::start_match_3_d_run;
|
||||
pub use start_puzzle_run_procedure::start_puzzle_run;
|
||||
@@ -1564,6 +1621,7 @@ pub use turn_in_quest_reducer::turn_in_quest;
|
||||
pub use unequip_inventory_item_input_type::UnequipInventoryItemInput;
|
||||
pub use unpublish_custom_world_profile_and_return_procedure::unpublish_custom_world_profile_and_return;
|
||||
pub use unpublish_custom_world_profile_reducer::unpublish_custom_world_profile;
|
||||
pub use update_bark_battle_draft_config_procedure::update_bark_battle_draft_config;
|
||||
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;
|
||||
@@ -1905,6 +1963,13 @@ pub struct DbUpdate {
|
||||
asset_object: __sdk::TableUpdate<AssetObject>,
|
||||
auth_identity: __sdk::TableUpdate<AuthIdentity>,
|
||||
auth_store_snapshot: __sdk::TableUpdate<AuthStoreSnapshot>,
|
||||
bark_battle_draft_config: __sdk::TableUpdate<BarkBattleDraftConfigRow>,
|
||||
bark_battle_leaderboard_entry: __sdk::TableUpdate<BarkBattleLeaderboardEntryRow>,
|
||||
bark_battle_personal_best_projection: __sdk::TableUpdate<BarkBattlePersonalBestProjectionRow>,
|
||||
bark_battle_published_config: __sdk::TableUpdate<BarkBattlePublishedConfigRow>,
|
||||
bark_battle_runtime_run: __sdk::TableUpdate<BarkBattleRuntimeRunRow>,
|
||||
bark_battle_score_record: __sdk::TableUpdate<BarkBattleScoreRecordRow>,
|
||||
bark_battle_work_stats_projection: __sdk::TableUpdate<BarkBattleWorkStatsProjectionRow>,
|
||||
battle_state: __sdk::TableUpdate<BattleState>,
|
||||
big_fish_agent_message: __sdk::TableUpdate<BigFishAgentMessage>,
|
||||
big_fish_asset_slot: __sdk::TableUpdate<BigFishAssetSlot>,
|
||||
@@ -2015,6 +2080,33 @@ impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate {
|
||||
"auth_store_snapshot" => db_update
|
||||
.auth_store_snapshot
|
||||
.append(auth_store_snapshot_table::parse_table_update(table_update)?),
|
||||
"bark_battle_draft_config" => db_update.bark_battle_draft_config.append(
|
||||
bark_battle_draft_config_table::parse_table_update(table_update)?,
|
||||
),
|
||||
"bark_battle_leaderboard_entry" => db_update.bark_battle_leaderboard_entry.append(
|
||||
bark_battle_leaderboard_entry_table::parse_table_update(table_update)?,
|
||||
),
|
||||
"bark_battle_personal_best_projection" => {
|
||||
db_update.bark_battle_personal_best_projection.append(
|
||||
bark_battle_personal_best_projection_table::parse_table_update(
|
||||
table_update,
|
||||
)?,
|
||||
)
|
||||
}
|
||||
"bark_battle_published_config" => db_update.bark_battle_published_config.append(
|
||||
bark_battle_published_config_table::parse_table_update(table_update)?,
|
||||
),
|
||||
"bark_battle_runtime_run" => db_update.bark_battle_runtime_run.append(
|
||||
bark_battle_runtime_run_table::parse_table_update(table_update)?,
|
||||
),
|
||||
"bark_battle_score_record" => db_update.bark_battle_score_record.append(
|
||||
bark_battle_score_record_table::parse_table_update(table_update)?,
|
||||
),
|
||||
"bark_battle_work_stats_projection" => {
|
||||
db_update.bark_battle_work_stats_projection.append(
|
||||
bark_battle_work_stats_projection_table::parse_table_update(table_update)?,
|
||||
)
|
||||
}
|
||||
"battle_state" => db_update
|
||||
.battle_state
|
||||
.append(battle_state_table::parse_table_update(table_update)?),
|
||||
@@ -2293,6 +2385,48 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||
&self.auth_store_snapshot,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.snapshot_id);
|
||||
diff.bark_battle_draft_config = cache
|
||||
.apply_diff_to_table::<BarkBattleDraftConfigRow>(
|
||||
"bark_battle_draft_config",
|
||||
&self.bark_battle_draft_config,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.draft_id);
|
||||
diff.bark_battle_leaderboard_entry = cache
|
||||
.apply_diff_to_table::<BarkBattleLeaderboardEntryRow>(
|
||||
"bark_battle_leaderboard_entry",
|
||||
&self.bark_battle_leaderboard_entry,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.leaderboard_entry_id);
|
||||
diff.bark_battle_personal_best_projection = cache
|
||||
.apply_diff_to_table::<BarkBattlePersonalBestProjectionRow>(
|
||||
"bark_battle_personal_best_projection",
|
||||
&self.bark_battle_personal_best_projection,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.personal_best_id);
|
||||
diff.bark_battle_published_config = cache
|
||||
.apply_diff_to_table::<BarkBattlePublishedConfigRow>(
|
||||
"bark_battle_published_config",
|
||||
&self.bark_battle_published_config,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.work_id);
|
||||
diff.bark_battle_runtime_run = cache
|
||||
.apply_diff_to_table::<BarkBattleRuntimeRunRow>(
|
||||
"bark_battle_runtime_run",
|
||||
&self.bark_battle_runtime_run,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.run_id);
|
||||
diff.bark_battle_score_record = cache
|
||||
.apply_diff_to_table::<BarkBattleScoreRecordRow>(
|
||||
"bark_battle_score_record",
|
||||
&self.bark_battle_score_record,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.score_id);
|
||||
diff.bark_battle_work_stats_projection = cache
|
||||
.apply_diff_to_table::<BarkBattleWorkStatsProjectionRow>(
|
||||
"bark_battle_work_stats_projection",
|
||||
&self.bark_battle_work_stats_projection,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.work_id);
|
||||
diff.battle_state = cache
|
||||
.apply_diff_to_table::<BattleState>("battle_state", &self.battle_state)
|
||||
.with_updates_by_pk(|row| &row.battle_state_id);
|
||||
@@ -2690,6 +2824,27 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||
"auth_store_snapshot" => db_update
|
||||
.auth_store_snapshot
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"bark_battle_draft_config" => db_update
|
||||
.bark_battle_draft_config
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"bark_battle_leaderboard_entry" => db_update
|
||||
.bark_battle_leaderboard_entry
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"bark_battle_personal_best_projection" => db_update
|
||||
.bark_battle_personal_best_projection
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"bark_battle_published_config" => db_update
|
||||
.bark_battle_published_config
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"bark_battle_runtime_run" => db_update
|
||||
.bark_battle_runtime_run
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"bark_battle_score_record" => db_update
|
||||
.bark_battle_score_record
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"bark_battle_work_stats_projection" => db_update
|
||||
.bark_battle_work_stats_projection
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"battle_state" => db_update
|
||||
.battle_state
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
@@ -2943,6 +3098,27 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||
"auth_store_snapshot" => db_update
|
||||
.auth_store_snapshot
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"bark_battle_draft_config" => db_update
|
||||
.bark_battle_draft_config
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"bark_battle_leaderboard_entry" => db_update
|
||||
.bark_battle_leaderboard_entry
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"bark_battle_personal_best_projection" => db_update
|
||||
.bark_battle_personal_best_projection
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"bark_battle_published_config" => db_update
|
||||
.bark_battle_published_config
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"bark_battle_runtime_run" => db_update
|
||||
.bark_battle_runtime_run
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"bark_battle_score_record" => db_update
|
||||
.bark_battle_score_record
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"bark_battle_work_stats_projection" => db_update
|
||||
.bark_battle_work_stats_projection
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"battle_state" => db_update
|
||||
.battle_state
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
@@ -3176,6 +3352,15 @@ pub struct AppliedDiff<'r> {
|
||||
asset_object: __sdk::TableAppliedDiff<'r, AssetObject>,
|
||||
auth_identity: __sdk::TableAppliedDiff<'r, AuthIdentity>,
|
||||
auth_store_snapshot: __sdk::TableAppliedDiff<'r, AuthStoreSnapshot>,
|
||||
bark_battle_draft_config: __sdk::TableAppliedDiff<'r, BarkBattleDraftConfigRow>,
|
||||
bark_battle_leaderboard_entry: __sdk::TableAppliedDiff<'r, BarkBattleLeaderboardEntryRow>,
|
||||
bark_battle_personal_best_projection:
|
||||
__sdk::TableAppliedDiff<'r, BarkBattlePersonalBestProjectionRow>,
|
||||
bark_battle_published_config: __sdk::TableAppliedDiff<'r, BarkBattlePublishedConfigRow>,
|
||||
bark_battle_runtime_run: __sdk::TableAppliedDiff<'r, BarkBattleRuntimeRunRow>,
|
||||
bark_battle_score_record: __sdk::TableAppliedDiff<'r, BarkBattleScoreRecordRow>,
|
||||
bark_battle_work_stats_projection:
|
||||
__sdk::TableAppliedDiff<'r, BarkBattleWorkStatsProjectionRow>,
|
||||
battle_state: __sdk::TableAppliedDiff<'r, BattleState>,
|
||||
big_fish_agent_message: __sdk::TableAppliedDiff<'r, BigFishAgentMessage>,
|
||||
big_fish_asset_slot: __sdk::TableAppliedDiff<'r, BigFishAssetSlot>,
|
||||
@@ -3306,6 +3491,41 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
|
||||
&self.auth_store_snapshot,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<BarkBattleDraftConfigRow>(
|
||||
"bark_battle_draft_config",
|
||||
&self.bark_battle_draft_config,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<BarkBattleLeaderboardEntryRow>(
|
||||
"bark_battle_leaderboard_entry",
|
||||
&self.bark_battle_leaderboard_entry,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<BarkBattlePersonalBestProjectionRow>(
|
||||
"bark_battle_personal_best_projection",
|
||||
&self.bark_battle_personal_best_projection,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<BarkBattlePublishedConfigRow>(
|
||||
"bark_battle_published_config",
|
||||
&self.bark_battle_published_config,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<BarkBattleRuntimeRunRow>(
|
||||
"bark_battle_runtime_run",
|
||||
&self.bark_battle_runtime_run,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<BarkBattleScoreRecordRow>(
|
||||
"bark_battle_score_record",
|
||||
&self.bark_battle_score_record,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<BarkBattleWorkStatsProjectionRow>(
|
||||
"bark_battle_work_stats_projection",
|
||||
&self.bark_battle_work_stats_projection,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<BattleState>(
|
||||
"battle_state",
|
||||
&self.battle_state,
|
||||
@@ -4310,6 +4530,13 @@ impl __sdk::SpacetimeModule for RemoteModule {
|
||||
asset_object_table::register_table(client_cache);
|
||||
auth_identity_table::register_table(client_cache);
|
||||
auth_store_snapshot_table::register_table(client_cache);
|
||||
bark_battle_draft_config_table::register_table(client_cache);
|
||||
bark_battle_leaderboard_entry_table::register_table(client_cache);
|
||||
bark_battle_personal_best_projection_table::register_table(client_cache);
|
||||
bark_battle_published_config_table::register_table(client_cache);
|
||||
bark_battle_runtime_run_table::register_table(client_cache);
|
||||
bark_battle_score_record_table::register_table(client_cache);
|
||||
bark_battle_work_stats_projection_table::register_table(client_cache);
|
||||
battle_state_table::register_table(client_cache);
|
||||
big_fish_agent_message_table::register_table(client_cache);
|
||||
big_fish_asset_slot_table::register_table(client_cache);
|
||||
@@ -4392,6 +4619,13 @@ impl __sdk::SpacetimeModule for RemoteModule {
|
||||
"asset_object",
|
||||
"auth_identity",
|
||||
"auth_store_snapshot",
|
||||
"bark_battle_draft_config",
|
||||
"bark_battle_leaderboard_entry",
|
||||
"bark_battle_personal_best_projection",
|
||||
"bark_battle_published_config",
|
||||
"bark_battle_runtime_run",
|
||||
"bark_battle_score_record",
|
||||
"bark_battle_work_stats_projection",
|
||||
"battle_state",
|
||||
"big_fish_agent_message",
|
||||
"big_fish_asset_slot",
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::bark_battle_procedure_result_type::BarkBattleProcedureResult;
|
||||
use super::bark_battle_work_publish_input_type::BarkBattleWorkPublishInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct PublishBarkBattleWorkArgs {
|
||||
pub input: BarkBattleWorkPublishInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for PublishBarkBattleWorkArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `publish_bark_battle_work`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait publish_bark_battle_work {
|
||||
fn publish_bark_battle_work(&self, input: BarkBattleWorkPublishInput) {
|
||||
self.publish_bark_battle_work_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn publish_bark_battle_work_then(
|
||||
&self,
|
||||
input: BarkBattleWorkPublishInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl publish_bark_battle_work for super::RemoteProcedures {
|
||||
fn publish_bark_battle_work_then(
|
||||
&self,
|
||||
input: BarkBattleWorkPublishInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, BarkBattleProcedureResult>(
|
||||
"publish_bark_battle_work",
|
||||
PublishBarkBattleWorkArgs { input },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::bark_battle_procedure_result_type::BarkBattleProcedureResult;
|
||||
use super::bark_battle_run_start_input_type::BarkBattleRunStartInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct StartBarkBattleRunArgs {
|
||||
pub input: BarkBattleRunStartInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for StartBarkBattleRunArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `start_bark_battle_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait start_bark_battle_run {
|
||||
fn start_bark_battle_run(&self, input: BarkBattleRunStartInput) {
|
||||
self.start_bark_battle_run_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn start_bark_battle_run_then(
|
||||
&self,
|
||||
input: BarkBattleRunStartInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl start_bark_battle_run for super::RemoteProcedures {
|
||||
fn start_bark_battle_run_then(
|
||||
&self,
|
||||
input: BarkBattleRunStartInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, BarkBattleProcedureResult>(
|
||||
"start_bark_battle_run",
|
||||
StartBarkBattleRunArgs { input },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
#![allow(unused, clippy::all)]
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
use super::bark_battle_draft_config_upsert_input_type::BarkBattleDraftConfigUpsertInput;
|
||||
use super::bark_battle_procedure_result_type::BarkBattleProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct UpdateBarkBattleDraftConfigArgs {
|
||||
pub input: BarkBattleDraftConfigUpsertInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for UpdateBarkBattleDraftConfigArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `update_bark_battle_draft_config`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait update_bark_battle_draft_config {
|
||||
fn update_bark_battle_draft_config(&self, input: BarkBattleDraftConfigUpsertInput) {
|
||||
self.update_bark_battle_draft_config_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn update_bark_battle_draft_config_then(
|
||||
&self,
|
||||
input: BarkBattleDraftConfigUpsertInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl update_bark_battle_draft_config for super::RemoteProcedures {
|
||||
fn update_bark_battle_draft_config_then(
|
||||
&self,
|
||||
input: BarkBattleDraftConfigUpsertInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<BarkBattleProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, BarkBattleProcedureResult>(
|
||||
"update_bark_battle_draft_config",
|
||||
UpdateBarkBattleDraftConfigArgs { input },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
module-ai = { workspace = true, features = ["spacetime-types"] }
|
||||
module-assets = { workspace = true, features = ["spacetime-types"] }
|
||||
module-bark-battle = { workspace = true }
|
||||
module-big-fish = { workspace = true, features = ["spacetime-types"] }
|
||||
module-combat = { workspace = true, features = ["spacetime-types"] }
|
||||
module-inventory = { workspace = true, features = ["spacetime-types"] }
|
||||
@@ -26,6 +27,7 @@ module-runtime = { workspace = true, features = ["spacetime-types"] }
|
||||
module-runtime-item = { workspace = true, features = ["spacetime-types"] }
|
||||
module-square-hole = { workspace = true }
|
||||
module-story = { workspace = true, features = ["spacetime-types"] }
|
||||
sha2 = { workspace = true }
|
||||
shared-kernel = { workspace = true }
|
||||
spacetimedb = { workspace = true, features = ["unstable"] }
|
||||
spacetimedb-lib = { workspace = true, features = ["serde"] }
|
||||
|
||||
872
server-rs/crates/spacetime-module/src/bark_battle/mod.rs
Normal file
872
server-rs/crates/spacetime-module/src/bark_battle/mod.rs
Normal file
@@ -0,0 +1,872 @@
|
||||
use crate::*;
|
||||
use serde::Serialize;
|
||||
use serde::de::DeserializeOwned;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
pub(crate) mod tables;
|
||||
mod types;
|
||||
|
||||
pub use tables::*;
|
||||
pub use types::*;
|
||||
|
||||
#[spacetimedb::procedure]
|
||||
pub fn create_bark_battle_draft(
|
||||
ctx: &mut ProcedureContext,
|
||||
input: BarkBattleDraftCreateInput,
|
||||
) -> BarkBattleProcedureResult {
|
||||
match ctx.try_with_tx(|tx| create_bark_battle_draft_tx(tx, input.clone())) {
|
||||
Ok(snapshot) => bark_battle_json_result(&snapshot),
|
||||
Err(error) => bark_battle_error_result(error),
|
||||
}
|
||||
}
|
||||
|
||||
#[spacetimedb::procedure]
|
||||
pub fn update_bark_battle_draft_config(
|
||||
ctx: &mut ProcedureContext,
|
||||
input: BarkBattleDraftConfigUpsertInput,
|
||||
) -> BarkBattleProcedureResult {
|
||||
match ctx.try_with_tx(|tx| update_bark_battle_draft_config_tx(tx, input.clone())) {
|
||||
Ok(snapshot) => bark_battle_json_result(&snapshot),
|
||||
Err(error) => bark_battle_error_result(error),
|
||||
}
|
||||
}
|
||||
|
||||
#[spacetimedb::procedure]
|
||||
pub fn publish_bark_battle_work(
|
||||
ctx: &mut ProcedureContext,
|
||||
input: BarkBattleWorkPublishInput,
|
||||
) -> BarkBattleProcedureResult {
|
||||
match ctx.try_with_tx(|tx| publish_bark_battle_work_tx(tx, input.clone())) {
|
||||
Ok(snapshot) => bark_battle_json_result(&snapshot),
|
||||
Err(error) => bark_battle_error_result(error),
|
||||
}
|
||||
}
|
||||
|
||||
#[spacetimedb::procedure]
|
||||
pub fn get_bark_battle_runtime_config(
|
||||
ctx: &mut ProcedureContext,
|
||||
input: BarkBattleRuntimeConfigGetInput,
|
||||
) -> BarkBattleProcedureResult {
|
||||
match ctx.try_with_tx(|tx| get_bark_battle_runtime_config_tx(tx, input.clone())) {
|
||||
Ok(snapshot) => bark_battle_json_result(&snapshot),
|
||||
Err(error) => bark_battle_error_result(error),
|
||||
}
|
||||
}
|
||||
|
||||
#[spacetimedb::procedure]
|
||||
pub fn start_bark_battle_run(
|
||||
ctx: &mut ProcedureContext,
|
||||
input: BarkBattleRunStartInput,
|
||||
) -> BarkBattleProcedureResult {
|
||||
match ctx.try_with_tx(|tx| start_bark_battle_run_tx(tx, input.clone())) {
|
||||
Ok(snapshot) => bark_battle_json_result(&snapshot),
|
||||
Err(error) => bark_battle_error_result(error),
|
||||
}
|
||||
}
|
||||
|
||||
#[spacetimedb::procedure]
|
||||
pub fn finish_bark_battle_run(
|
||||
ctx: &mut ProcedureContext,
|
||||
input: BarkBattleRunFinishInput,
|
||||
) -> BarkBattleProcedureResult {
|
||||
match ctx.try_with_tx(|tx| finish_bark_battle_run_tx(tx, input.clone())) {
|
||||
Ok(snapshot) => bark_battle_json_result(&snapshot),
|
||||
Err(error) => bark_battle_error_result(error),
|
||||
}
|
||||
}
|
||||
|
||||
#[spacetimedb::procedure]
|
||||
pub fn get_bark_battle_run(
|
||||
ctx: &mut ProcedureContext,
|
||||
input: BarkBattleRunGetInput,
|
||||
) -> BarkBattleProcedureResult {
|
||||
match ctx.try_with_tx(|tx| get_bark_battle_run_tx(tx, input.clone())) {
|
||||
Ok(snapshot) => bark_battle_json_result(&snapshot),
|
||||
Err(error) => bark_battle_error_result(error),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_bark_battle_draft_tx(
|
||||
ctx: &ReducerContext,
|
||||
input: BarkBattleDraftCreateInput,
|
||||
) -> Result<BarkBattleDraftConfigSnapshot, String> {
|
||||
require_non_empty(&input.draft_id, "bark_battle draft_id")?;
|
||||
require_non_empty(&input.owner_user_id, "bark_battle owner_user_id")?;
|
||||
require_non_empty(&input.work_id, "bark_battle work_id")?;
|
||||
if ctx
|
||||
.db
|
||||
.bark_battle_draft_config()
|
||||
.draft_id()
|
||||
.find(&input.draft_id)
|
||||
.is_some()
|
||||
{
|
||||
return Err("bark_battle_draft_config.draft_id 已存在".to_string());
|
||||
}
|
||||
|
||||
let now = Timestamp::from_micros_since_unix_epoch(input.created_at_micros);
|
||||
let config = BarkBattleEditorConfigSnapshot {
|
||||
title: normalize_title(input.title.as_deref())?,
|
||||
description: normalize_optional_text(input.description.as_deref()),
|
||||
theme_preset: normalize_required_preset(&input.theme_preset, "theme_preset")?,
|
||||
player_dog_skin_preset: normalize_required_preset(
|
||||
&input.player_dog_skin_preset,
|
||||
"player_dog_skin_preset",
|
||||
)?,
|
||||
opponent_dog_skin_preset: normalize_required_preset(
|
||||
&input.opponent_dog_skin_preset,
|
||||
"opponent_dog_skin_preset",
|
||||
)?,
|
||||
difficulty_preset: normalize_difficulty(input.difficulty_preset.as_deref())?,
|
||||
leaderboard_enabled: input.leaderboard_enabled.unwrap_or(true),
|
||||
};
|
||||
let row = BarkBattleDraftConfigRow {
|
||||
draft_id: input.draft_id.clone(),
|
||||
owner_user_id: input.owner_user_id.clone(),
|
||||
work_id: input.work_id.clone(),
|
||||
config_version: 1,
|
||||
ruleset_version: BARK_BATTLE_DEFAULT_RULESET_VERSION.to_string(),
|
||||
difficulty_preset: config.difficulty_preset.clone(),
|
||||
leaderboard_enabled: config.leaderboard_enabled,
|
||||
config_json: to_json_string(&config),
|
||||
editor_state_json: normalize_json_string(
|
||||
input.editor_state_json.as_deref(),
|
||||
"editor_state_json",
|
||||
)?,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
};
|
||||
ctx.db.bark_battle_draft_config().insert(row.clone());
|
||||
Ok(draft_snapshot(&row))
|
||||
}
|
||||
|
||||
fn update_bark_battle_draft_config_tx(
|
||||
ctx: &ReducerContext,
|
||||
input: BarkBattleDraftConfigUpsertInput,
|
||||
) -> Result<BarkBattleDraftConfigSnapshot, String> {
|
||||
require_non_empty(&input.draft_id, "bark_battle draft_id")?;
|
||||
require_non_empty(&input.owner_user_id, "bark_battle owner_user_id")?;
|
||||
require_non_empty(&input.work_id, "bark_battle work_id")?;
|
||||
let editor_config = parse_editor_config(&input.config_json)?;
|
||||
validate_editor_config_snapshot(&editor_config)?;
|
||||
if editor_config.difficulty_preset != input.difficulty_preset
|
||||
|| editor_config.leaderboard_enabled != input.leaderboard_enabled
|
||||
{
|
||||
return Err("bark_battle config_json 与行字段不一致".to_string());
|
||||
}
|
||||
let updated_at = Timestamp::from_micros_since_unix_epoch(input.updated_at_micros);
|
||||
let existing = ctx
|
||||
.db
|
||||
.bark_battle_draft_config()
|
||||
.draft_id()
|
||||
.find(&input.draft_id)
|
||||
.ok_or_else(|| "bark_battle_draft_config.draft_id 不存在".to_string())?;
|
||||
if existing.owner_user_id != input.owner_user_id || existing.work_id != input.work_id {
|
||||
return Err("bark_battle draft owner/work 不匹配".to_string());
|
||||
}
|
||||
if input.config_version <= existing.config_version {
|
||||
return Err("bark_battle draft config_version 必须递增".to_string());
|
||||
}
|
||||
let mut row = existing;
|
||||
row.config_version = input.config_version;
|
||||
row.ruleset_version = normalize_ruleset_version(&input.ruleset_version)?;
|
||||
row.difficulty_preset = normalize_difficulty(Some(&input.difficulty_preset))?;
|
||||
row.leaderboard_enabled = input.leaderboard_enabled;
|
||||
row.config_json = input.config_json;
|
||||
row.updated_at = updated_at;
|
||||
ctx.db
|
||||
.bark_battle_draft_config()
|
||||
.draft_id()
|
||||
.update(row.clone());
|
||||
Ok(draft_snapshot(&row))
|
||||
}
|
||||
|
||||
fn publish_bark_battle_work_tx(
|
||||
ctx: &ReducerContext,
|
||||
input: BarkBattleWorkPublishInput,
|
||||
) -> Result<BarkBattleRuntimeConfigSnapshot, String> {
|
||||
require_non_empty(&input.draft_id, "bark_battle draft_id")?;
|
||||
require_non_empty(&input.owner_user_id, "bark_battle owner_user_id")?;
|
||||
require_non_empty(&input.work_id, "bark_battle work_id")?;
|
||||
let published_at = Timestamp::from_micros_since_unix_epoch(input.published_at_micros);
|
||||
let draft = ctx
|
||||
.db
|
||||
.bark_battle_draft_config()
|
||||
.draft_id()
|
||||
.find(&input.draft_id)
|
||||
.ok_or_else(|| "bark_battle draft 不存在".to_string())?;
|
||||
if draft.owner_user_id != input.owner_user_id || draft.work_id != input.work_id {
|
||||
return Err("bark_battle draft owner/work 不匹配".to_string());
|
||||
}
|
||||
let published = BarkBattlePublishedConfigRow {
|
||||
work_id: draft.work_id.clone(),
|
||||
owner_user_id: draft.owner_user_id.clone(),
|
||||
source_draft_id: Some(draft.draft_id.clone()),
|
||||
config_version: draft.config_version,
|
||||
ruleset_version: normalize_ruleset_version(&draft.ruleset_version)?,
|
||||
difficulty_preset: normalize_difficulty(Some(&draft.difficulty_preset))?,
|
||||
leaderboard_enabled: draft.leaderboard_enabled,
|
||||
config_json: draft.config_json.clone(),
|
||||
published_snapshot_json: match input.published_snapshot_json.as_deref() {
|
||||
Some(value) => normalize_json_string(Some(value), "published_snapshot_json")?,
|
||||
None => draft.config_json.clone(),
|
||||
},
|
||||
created_at: published_at,
|
||||
updated_at: published_at,
|
||||
published_at,
|
||||
};
|
||||
let mut published = published;
|
||||
match ctx
|
||||
.db
|
||||
.bark_battle_published_config()
|
||||
.work_id()
|
||||
.find(&published.work_id)
|
||||
{
|
||||
Some(existing) => {
|
||||
published.created_at = existing.created_at;
|
||||
ctx.db
|
||||
.bark_battle_published_config()
|
||||
.work_id()
|
||||
.update(published.clone());
|
||||
}
|
||||
None => {
|
||||
ctx.db
|
||||
.bark_battle_published_config()
|
||||
.insert(published.clone());
|
||||
}
|
||||
}
|
||||
Ok(runtime_config_snapshot(&published))
|
||||
}
|
||||
|
||||
fn get_bark_battle_runtime_config_tx(
|
||||
ctx: &ReducerContext,
|
||||
input: BarkBattleRuntimeConfigGetInput,
|
||||
) -> Result<BarkBattleRuntimeConfigSnapshot, String> {
|
||||
require_non_empty(&input.work_id, "bark_battle work_id")?;
|
||||
let row = ctx
|
||||
.db
|
||||
.bark_battle_published_config()
|
||||
.work_id()
|
||||
.find(&input.work_id)
|
||||
.ok_or_else(|| "bark_battle published config 不存在".to_string())?;
|
||||
if let Some(owner_user_id) = input.owner_user_id.as_deref() {
|
||||
if !owner_user_id.trim().is_empty() && row.owner_user_id != owner_user_id.trim() {
|
||||
return Err("bark_battle runtime config owner 不匹配".to_string());
|
||||
}
|
||||
}
|
||||
Ok(runtime_config_snapshot(&row))
|
||||
}
|
||||
|
||||
fn start_bark_battle_run_tx(
|
||||
ctx: &ReducerContext,
|
||||
input: BarkBattleRunStartInput,
|
||||
) -> Result<BarkBattleRunSnapshot, String> {
|
||||
require_non_empty(&input.run_id, "bark_battle run_id")?;
|
||||
require_non_empty(&input.run_token, "bark_battle run_token")?;
|
||||
require_non_empty(&input.owner_user_id, "bark_battle owner_user_id")?;
|
||||
require_non_empty(&input.work_id, "bark_battle work_id")?;
|
||||
let published = ctx
|
||||
.db
|
||||
.bark_battle_published_config()
|
||||
.work_id()
|
||||
.find(&input.work_id)
|
||||
.ok_or_else(|| "bark_battle published config 不存在".to_string())?;
|
||||
if published.config_version != input.config_version
|
||||
|| published.ruleset_version != input.ruleset_version
|
||||
|| published.difficulty_preset != input.difficulty_preset
|
||||
{
|
||||
return Err("bark_battle run config/ruleset/difficulty 不匹配".to_string());
|
||||
}
|
||||
if ctx
|
||||
.db
|
||||
.bark_battle_runtime_run()
|
||||
.run_id()
|
||||
.find(&input.run_id)
|
||||
.is_some()
|
||||
{
|
||||
return Err("bark_battle run_id 已存在".to_string());
|
||||
}
|
||||
let started_at = ctx.timestamp;
|
||||
let row = BarkBattleRuntimeRunRow {
|
||||
run_id: input.run_id,
|
||||
run_token_hash: hash_run_token(&input.run_token),
|
||||
owner_user_id: input.owner_user_id,
|
||||
work_id: input.work_id,
|
||||
config_version: input.config_version,
|
||||
ruleset_version: input.ruleset_version,
|
||||
difficulty_preset: input.difficulty_preset,
|
||||
leaderboard_enabled: published.leaderboard_enabled,
|
||||
status: BARK_BATTLE_RUN_RUNNING.to_string(),
|
||||
client_started_at_micros: input.client_started_at_micros,
|
||||
server_started_at: started_at,
|
||||
client_finished_at_micros: None,
|
||||
server_finished_at: None,
|
||||
metrics_json: "{}".to_string(),
|
||||
server_result: None,
|
||||
validation_status: BARK_BATTLE_VALIDATION_PENDING.to_string(),
|
||||
anti_cheat_flags_json: "[]".to_string(),
|
||||
leaderboard_score: None,
|
||||
score_id: None,
|
||||
created_at: started_at,
|
||||
updated_at: started_at,
|
||||
};
|
||||
ctx.db.bark_battle_runtime_run().insert(row.clone());
|
||||
upsert_initial_work_stats(ctx, &row);
|
||||
Ok(run_snapshot(&row))
|
||||
}
|
||||
|
||||
fn finish_bark_battle_run_tx(
|
||||
ctx: &ReducerContext,
|
||||
input: BarkBattleRunFinishInput,
|
||||
) -> Result<BarkBattleRunSnapshot, String> {
|
||||
require_non_empty(&input.run_id, "bark_battle run_id")?;
|
||||
require_non_empty(&input.run_token, "bark_battle run_token")?;
|
||||
let mut run = ctx
|
||||
.db
|
||||
.bark_battle_runtime_run()
|
||||
.run_id()
|
||||
.find(&input.run_id)
|
||||
.ok_or_else(|| "bark_battle run 不存在".to_string())?;
|
||||
if input.server_finished_at_micros > 0
|
||||
&& input.server_finished_at_micros < run.server_started_at.to_micros_since_unix_epoch()
|
||||
{
|
||||
return Err("bark_battle server_finished_at 早于 run start".to_string());
|
||||
}
|
||||
if ctx
|
||||
.timestamp
|
||||
.to_micros_since_unix_epoch()
|
||||
.saturating_sub(run.server_started_at.to_micros_since_unix_epoch())
|
||||
> 10 * 60 * 1_000_000
|
||||
{
|
||||
return Err("bark_battle run 已过期".to_string());
|
||||
}
|
||||
if run.run_token_hash != hash_run_token(&input.run_token) {
|
||||
return Err("bark_battle run_token 不匹配".to_string());
|
||||
}
|
||||
if run.status != BARK_BATTLE_RUN_RUNNING {
|
||||
return Err("bark_battle run 已结束".to_string());
|
||||
}
|
||||
if run.owner_user_id != input.owner_user_id
|
||||
|| run.work_id != input.work_id
|
||||
|| run.config_version != input.config_version
|
||||
|| run.ruleset_version != input.ruleset_version
|
||||
|| run.difficulty_preset != input.difficulty_preset
|
||||
{
|
||||
return Err("bark_battle finish identity/config 不匹配".to_string());
|
||||
}
|
||||
validate_json::<serde_json::Value>(&input.metrics_json, "metrics_json")?;
|
||||
validate_json::<serde_json::Value>(&input.derived_metrics_json, "derived_metrics_json")?;
|
||||
|
||||
let difficulty = parse_domain_difficulty(&input.difficulty_preset)?;
|
||||
let ruleset = module_bark_battle::BarkBattleRuleset::for_difficulty(difficulty);
|
||||
let finished_at = ctx.timestamp;
|
||||
let metrics = module_bark_battle::BarkBattleFinishMetrics {
|
||||
duration_ms: input.duration_ms,
|
||||
trigger_count: input.trigger_count,
|
||||
max_volume: millis_to_unit(input.max_volume_millis),
|
||||
average_volume: millis_to_unit(input.average_volume_millis),
|
||||
final_energy: millis_to_energy(input.final_energy_millis),
|
||||
max_combo: input.max_combo,
|
||||
finished_at_micros: finished_at.to_micros_since_unix_epoch(),
|
||||
};
|
||||
let validation = module_bark_battle::validate_finish_metrics(&ruleset, &metrics);
|
||||
let result = module_bark_battle::adjudicate_result(
|
||||
&ruleset,
|
||||
metrics.final_energy,
|
||||
millis_to_energy(input.opponent_final_energy_millis),
|
||||
);
|
||||
let leaderboard = if run.leaderboard_enabled {
|
||||
module_bark_battle::compute_leaderboard_score(&ruleset, &metrics, &validation, result)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let leaderboard_score = leaderboard.map(compose_leaderboard_score);
|
||||
let score_id = format!("score-{}", input.run_id);
|
||||
let validation_status = validation_status_to_string(validation.decision);
|
||||
let server_result = battle_result_to_string(result);
|
||||
let flags_json = to_json_string(&validation.anti_cheat_flags);
|
||||
|
||||
ctx.db
|
||||
.bark_battle_score_record()
|
||||
.insert(BarkBattleScoreRecordRow {
|
||||
score_id: score_id.clone(),
|
||||
owner_user_id: run.owner_user_id.clone(),
|
||||
work_id: run.work_id.clone(),
|
||||
run_id: run.run_id.clone(),
|
||||
config_version: run.config_version,
|
||||
ruleset_version: run.ruleset_version.clone(),
|
||||
difficulty_preset: run.difficulty_preset.clone(),
|
||||
leaderboard_enabled: run.leaderboard_enabled,
|
||||
metrics_json: input.metrics_json.clone(),
|
||||
derived_metrics_json: input.derived_metrics_json.clone(),
|
||||
server_result: server_result.clone(),
|
||||
validation_status: validation_status.clone(),
|
||||
anti_cheat_flags_json: flags_json.clone(),
|
||||
leaderboard_score,
|
||||
recorded_at: finished_at,
|
||||
});
|
||||
|
||||
if let Some(score) = leaderboard_score {
|
||||
ctx.db
|
||||
.bark_battle_leaderboard_entry()
|
||||
.insert(BarkBattleLeaderboardEntryRow {
|
||||
leaderboard_entry_id: format!("leaderboard-{}", input.run_id),
|
||||
work_id: run.work_id.clone(),
|
||||
owner_user_id: run.owner_user_id.clone(),
|
||||
run_id: run.run_id.clone(),
|
||||
score_id: score_id.clone(),
|
||||
leaderboard_score: score,
|
||||
final_energy: metrics.final_energy,
|
||||
trigger_count: metrics.trigger_count,
|
||||
max_volume: metrics.max_volume,
|
||||
duration_closeness_ms: input.duration_ms.abs_diff(ruleset.standard_duration_ms),
|
||||
finished_at_micros: finished_at.to_micros_since_unix_epoch(),
|
||||
created_at: finished_at,
|
||||
updated_at: finished_at,
|
||||
});
|
||||
}
|
||||
|
||||
run.status = BARK_BATTLE_RUN_FINISHED.to_string();
|
||||
run.client_finished_at_micros = Some(input.client_finished_at_micros);
|
||||
run.server_finished_at = Some(finished_at);
|
||||
run.metrics_json = input.metrics_json;
|
||||
run.server_result = Some(server_result.clone());
|
||||
run.validation_status = validation_status.clone();
|
||||
run.anti_cheat_flags_json = flags_json;
|
||||
run.leaderboard_score = leaderboard_score;
|
||||
run.score_id = Some(score_id.clone());
|
||||
run.updated_at = finished_at;
|
||||
ctx.db
|
||||
.bark_battle_runtime_run()
|
||||
.run_id()
|
||||
.update(run.clone());
|
||||
upsert_finished_projections(
|
||||
ctx,
|
||||
&run,
|
||||
&score_id,
|
||||
leaderboard_score,
|
||||
metrics.final_energy,
|
||||
metrics.trigger_count,
|
||||
metrics.max_volume,
|
||||
input.duration_ms.abs_diff(ruleset.standard_duration_ms),
|
||||
&server_result,
|
||||
&validation_status,
|
||||
finished_at.to_micros_since_unix_epoch(),
|
||||
finished_at,
|
||||
);
|
||||
Ok(run_snapshot(&run))
|
||||
}
|
||||
|
||||
fn get_bark_battle_run_tx(
|
||||
ctx: &ReducerContext,
|
||||
input: BarkBattleRunGetInput,
|
||||
) -> Result<BarkBattleRunSnapshot, String> {
|
||||
let row = ctx
|
||||
.db
|
||||
.bark_battle_runtime_run()
|
||||
.run_id()
|
||||
.find(&input.run_id)
|
||||
.ok_or_else(|| "bark_battle run 不存在".to_string())?;
|
||||
if row.owner_user_id != input.owner_user_id {
|
||||
return Err("bark_battle run owner 不匹配".to_string());
|
||||
}
|
||||
Ok(run_snapshot(&row))
|
||||
}
|
||||
|
||||
fn draft_snapshot(row: &BarkBattleDraftConfigRow) -> BarkBattleDraftConfigSnapshot {
|
||||
BarkBattleDraftConfigSnapshot {
|
||||
draft_id: row.draft_id.clone(),
|
||||
owner_user_id: row.owner_user_id.clone(),
|
||||
work_id: row.work_id.clone(),
|
||||
config_version: row.config_version,
|
||||
ruleset_version: row.ruleset_version.clone(),
|
||||
difficulty_preset: row.difficulty_preset.clone(),
|
||||
leaderboard_enabled: row.leaderboard_enabled,
|
||||
config_json: row.config_json.clone(),
|
||||
editor_state_json: row.editor_state_json.clone(),
|
||||
created_at_micros: row.created_at.to_micros_since_unix_epoch(),
|
||||
updated_at_micros: row.updated_at.to_micros_since_unix_epoch(),
|
||||
}
|
||||
}
|
||||
|
||||
fn runtime_config_snapshot(row: &BarkBattlePublishedConfigRow) -> BarkBattleRuntimeConfigSnapshot {
|
||||
BarkBattleRuntimeConfigSnapshot {
|
||||
work_id: row.work_id.clone(),
|
||||
owner_user_id: row.owner_user_id.clone(),
|
||||
source_draft_id: row.source_draft_id.clone(),
|
||||
config_version: row.config_version,
|
||||
ruleset_version: row.ruleset_version.clone(),
|
||||
difficulty_preset: row.difficulty_preset.clone(),
|
||||
leaderboard_enabled: row.leaderboard_enabled,
|
||||
config_json: row.config_json.clone(),
|
||||
published_snapshot_json: row.published_snapshot_json.clone(),
|
||||
published_at_micros: row.published_at.to_micros_since_unix_epoch(),
|
||||
updated_at_micros: row.updated_at.to_micros_since_unix_epoch(),
|
||||
}
|
||||
}
|
||||
|
||||
fn hash_run_token(token: &str) -> String {
|
||||
let digest = Sha256::digest(token.as_bytes());
|
||||
digest.iter().map(|byte| format!("{byte:02x}")).collect()
|
||||
}
|
||||
|
||||
fn normalize_json_string(value: Option<&str>, field_name: &str) -> Result<String, String> {
|
||||
let json = value.unwrap_or("{}").trim();
|
||||
validate_json::<serde_json::Value>(json, field_name)?;
|
||||
Ok(json.to_string())
|
||||
}
|
||||
|
||||
fn require_non_empty(value: &str, label: &str) -> Result<(), String> {
|
||||
if value.trim().is_empty() {
|
||||
Err(format!("{label} 不能为空"))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_editor_config_snapshot(config: &BarkBattleEditorConfigSnapshot) -> Result<(), String> {
|
||||
normalize_title(Some(&config.title))?;
|
||||
normalize_required_preset(&config.theme_preset, "theme_preset")?;
|
||||
normalize_required_preset(&config.player_dog_skin_preset, "player_dog_skin_preset")?;
|
||||
normalize_required_preset(&config.opponent_dog_skin_preset, "opponent_dog_skin_preset")?;
|
||||
normalize_difficulty(Some(&config.difficulty_preset))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn normalize_title(value: Option<&str>) -> Result<String, String> {
|
||||
let title = value.unwrap_or("汪汪声浪挑战").trim();
|
||||
if title.is_empty() {
|
||||
return Err("bark_battle title 不能为空".to_string());
|
||||
}
|
||||
if title.chars().count() > 40 {
|
||||
return Err("bark_battle title 不能超过 40 个字符".to_string());
|
||||
}
|
||||
Ok(title.to_string())
|
||||
}
|
||||
|
||||
fn normalize_optional_text(value: Option<&str>) -> String {
|
||||
value.unwrap_or_default().trim().chars().take(120).collect()
|
||||
}
|
||||
|
||||
fn normalize_required_preset(value: &str, field_name: &str) -> Result<String, String> {
|
||||
let preset = value.trim();
|
||||
if preset.is_empty() {
|
||||
return Err(format!("bark_battle {field_name} 不能为空"));
|
||||
}
|
||||
Ok(preset.to_string())
|
||||
}
|
||||
|
||||
fn normalize_ruleset_version(value: &str) -> Result<String, String> {
|
||||
let ruleset = value.trim();
|
||||
if ruleset != BARK_BATTLE_DEFAULT_RULESET_VERSION {
|
||||
return Err("bark_battle ruleset_version 不支持".to_string());
|
||||
}
|
||||
Ok(ruleset.to_string())
|
||||
}
|
||||
|
||||
fn normalize_difficulty(value: Option<&str>) -> Result<String, String> {
|
||||
let difficulty = value.unwrap_or(BARK_BATTLE_DIFFICULTY_NORMAL).trim();
|
||||
match difficulty {
|
||||
BARK_BATTLE_DIFFICULTY_EASY
|
||||
| BARK_BATTLE_DIFFICULTY_NORMAL
|
||||
| BARK_BATTLE_DIFFICULTY_HARD => Ok(difficulty.to_string()),
|
||||
_ => Err("bark_battle difficulty_preset 不支持".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_editor_config(value: &str) -> Result<BarkBattleEditorConfigSnapshot, String> {
|
||||
serde_json::from_str::<BarkBattleEditorConfigSnapshot>(value)
|
||||
.map_err(|error| format!("bark_battle config_json JSON 无效: {error}"))
|
||||
}
|
||||
|
||||
fn validate_json<T: DeserializeOwned>(value: &str, field_name: &str) -> Result<(), String> {
|
||||
serde_json::from_str::<T>(value)
|
||||
.map(|_| ())
|
||||
.map_err(|error| format!("bark_battle {field_name} JSON 无效: {error}"))
|
||||
}
|
||||
|
||||
fn bark_battle_json_result<T: Serialize>(value: &T) -> BarkBattleProcedureResult {
|
||||
BarkBattleProcedureResult {
|
||||
ok: true,
|
||||
row_json: Some(to_json_string(value)),
|
||||
error_message: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn bark_battle_error_result(error: String) -> BarkBattleProcedureResult {
|
||||
BarkBattleProcedureResult {
|
||||
ok: false,
|
||||
row_json: None,
|
||||
error_message: Some(error),
|
||||
}
|
||||
}
|
||||
|
||||
fn to_json_string<T: Serialize>(value: &T) -> String {
|
||||
serde_json::to_string(value).expect("serialize bark battle snapshot")
|
||||
}
|
||||
|
||||
fn run_snapshot(row: &BarkBattleRuntimeRunRow) -> BarkBattleRunSnapshot {
|
||||
BarkBattleRunSnapshot {
|
||||
run_id: row.run_id.clone(),
|
||||
owner_user_id: row.owner_user_id.clone(),
|
||||
work_id: row.work_id.clone(),
|
||||
config_version: row.config_version,
|
||||
ruleset_version: row.ruleset_version.clone(),
|
||||
difficulty_preset: row.difficulty_preset.clone(),
|
||||
leaderboard_enabled: row.leaderboard_enabled,
|
||||
status: row.status.clone(),
|
||||
client_started_at_micros: row.client_started_at_micros,
|
||||
server_started_at_micros: row.server_started_at.to_micros_since_unix_epoch(),
|
||||
client_finished_at_micros: row.client_finished_at_micros,
|
||||
server_finished_at_micros: row
|
||||
.server_finished_at
|
||||
.map(|t| t.to_micros_since_unix_epoch()),
|
||||
metrics_json: row.metrics_json.clone(),
|
||||
server_result: row.server_result.clone(),
|
||||
validation_status: row.validation_status.clone(),
|
||||
anti_cheat_flags_json: row.anti_cheat_flags_json.clone(),
|
||||
leaderboard_score: row.leaderboard_score,
|
||||
score_id: row.score_id.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn upsert_initial_work_stats(ctx: &ReducerContext, run: &BarkBattleRuntimeRunRow) {
|
||||
let now = run.created_at;
|
||||
match ctx
|
||||
.db
|
||||
.bark_battle_work_stats_projection()
|
||||
.work_id()
|
||||
.find(&run.work_id)
|
||||
{
|
||||
Some(mut stats) => {
|
||||
stats.play_count += 1;
|
||||
stats.updated_at = now;
|
||||
ctx.db
|
||||
.bark_battle_work_stats_projection()
|
||||
.work_id()
|
||||
.update(stats);
|
||||
}
|
||||
None => {
|
||||
ctx.db
|
||||
.bark_battle_work_stats_projection()
|
||||
.insert(BarkBattleWorkStatsProjectionRow {
|
||||
work_id: run.work_id.clone(),
|
||||
owner_user_id: run.owner_user_id.clone(),
|
||||
play_count: 1,
|
||||
finished_count: 0,
|
||||
accepted_score_count: 0,
|
||||
leaderboard_entry_count: 0,
|
||||
best_leaderboard_score: None,
|
||||
best_score_id: None,
|
||||
best_run_id: None,
|
||||
average_final_energy: 0.0,
|
||||
average_trigger_count: 0.0,
|
||||
last_finished_at_micros: None,
|
||||
stats_json: "{}".to_string(),
|
||||
updated_at: now,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn upsert_finished_projections(
|
||||
ctx: &ReducerContext,
|
||||
run: &BarkBattleRuntimeRunRow,
|
||||
score_id: &str,
|
||||
leaderboard_score: Option<u64>,
|
||||
final_energy: f32,
|
||||
trigger_count: u64,
|
||||
max_volume: f32,
|
||||
duration_closeness_ms: u64,
|
||||
server_result: &str,
|
||||
validation_status: &str,
|
||||
finished_at_micros: i64,
|
||||
updated_at: Timestamp,
|
||||
) {
|
||||
let mut stats = ctx
|
||||
.db
|
||||
.bark_battle_work_stats_projection()
|
||||
.work_id()
|
||||
.find(&run.work_id)
|
||||
.unwrap_or_else(|| BarkBattleWorkStatsProjectionRow {
|
||||
work_id: run.work_id.clone(),
|
||||
owner_user_id: run.owner_user_id.clone(),
|
||||
play_count: 0,
|
||||
finished_count: 0,
|
||||
accepted_score_count: 0,
|
||||
leaderboard_entry_count: 0,
|
||||
best_leaderboard_score: None,
|
||||
best_score_id: None,
|
||||
best_run_id: None,
|
||||
average_final_energy: 0.0,
|
||||
average_trigger_count: 0.0,
|
||||
last_finished_at_micros: None,
|
||||
stats_json: "{}".to_string(),
|
||||
updated_at,
|
||||
});
|
||||
let previous_finished = stats.finished_count as f32;
|
||||
stats.finished_count += 1;
|
||||
if validation_status != BARK_BATTLE_VALIDATION_REJECTED {
|
||||
stats.accepted_score_count += 1;
|
||||
}
|
||||
if leaderboard_score.is_some() {
|
||||
stats.leaderboard_entry_count += 1;
|
||||
}
|
||||
stats.average_final_energy = ((stats.average_final_energy * previous_finished) + final_energy)
|
||||
/ stats.finished_count as f32;
|
||||
stats.average_trigger_count = ((stats.average_trigger_count * previous_finished)
|
||||
+ trigger_count as f32)
|
||||
/ stats.finished_count as f32;
|
||||
if leaderboard_score > stats.best_leaderboard_score {
|
||||
stats.best_leaderboard_score = leaderboard_score;
|
||||
stats.best_score_id = Some(score_id.to_string());
|
||||
stats.best_run_id = Some(run.run_id.clone());
|
||||
}
|
||||
stats.last_finished_at_micros = Some(finished_at_micros);
|
||||
stats.updated_at = updated_at;
|
||||
if ctx
|
||||
.db
|
||||
.bark_battle_work_stats_projection()
|
||||
.work_id()
|
||||
.find(&run.work_id)
|
||||
.is_some()
|
||||
{
|
||||
ctx.db
|
||||
.bark_battle_work_stats_projection()
|
||||
.work_id()
|
||||
.update(stats);
|
||||
} else {
|
||||
ctx.db.bark_battle_work_stats_projection().insert(stats);
|
||||
}
|
||||
|
||||
let personal_best_id = format!("{}:{}", run.owner_user_id, run.work_id);
|
||||
let should_update_best = validation_status != BARK_BATTLE_VALIDATION_REJECTED
|
||||
&& ctx
|
||||
.db
|
||||
.bark_battle_personal_best_projection()
|
||||
.personal_best_id()
|
||||
.find(&personal_best_id)
|
||||
.map(|best| {
|
||||
leaderboard_score > best.leaderboard_score || final_energy > best.final_energy
|
||||
})
|
||||
.unwrap_or(true);
|
||||
if should_update_best {
|
||||
let row = BarkBattlePersonalBestProjectionRow {
|
||||
personal_best_id: personal_best_id.clone(),
|
||||
owner_user_id: run.owner_user_id.clone(),
|
||||
work_id: run.work_id.clone(),
|
||||
run_id: run.run_id.clone(),
|
||||
score_id: score_id.to_string(),
|
||||
leaderboard_entry_id: leaderboard_score.map(|_| format!("leaderboard-{}", run.run_id)),
|
||||
leaderboard_score,
|
||||
final_energy,
|
||||
trigger_count,
|
||||
max_volume,
|
||||
duration_closeness_ms,
|
||||
server_result: server_result.to_string(),
|
||||
validation_status: validation_status.to_string(),
|
||||
finished_at_micros,
|
||||
summary_json: "{}".to_string(),
|
||||
updated_at,
|
||||
};
|
||||
if ctx
|
||||
.db
|
||||
.bark_battle_personal_best_projection()
|
||||
.personal_best_id()
|
||||
.find(&personal_best_id)
|
||||
.is_some()
|
||||
{
|
||||
ctx.db
|
||||
.bark_battle_personal_best_projection()
|
||||
.personal_best_id()
|
||||
.update(row);
|
||||
} else {
|
||||
ctx.db.bark_battle_personal_best_projection().insert(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_domain_difficulty(value: &str) -> Result<module_bark_battle::DifficultyPreset, String> {
|
||||
match value {
|
||||
BARK_BATTLE_DIFFICULTY_EASY => Ok(module_bark_battle::DifficultyPreset::Easy),
|
||||
BARK_BATTLE_DIFFICULTY_NORMAL => Ok(module_bark_battle::DifficultyPreset::Normal),
|
||||
BARK_BATTLE_DIFFICULTY_HARD => Ok(module_bark_battle::DifficultyPreset::Hard),
|
||||
_ => Err("bark_battle difficulty_preset 不支持".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn millis_to_unit(value: u32) -> f32 {
|
||||
value as f32 / 1_000.0
|
||||
}
|
||||
|
||||
fn millis_to_energy(value: u32) -> f32 {
|
||||
value as f32 / 1_000.0
|
||||
}
|
||||
|
||||
fn validation_status_to_string(decision: module_bark_battle::FinishValidationDecision) -> String {
|
||||
match decision {
|
||||
module_bark_battle::FinishValidationDecision::Accepted => BARK_BATTLE_VALIDATION_ACCEPTED,
|
||||
module_bark_battle::FinishValidationDecision::AcceptedWithFlags => {
|
||||
BARK_BATTLE_VALIDATION_ACCEPTED_WITH_FLAGS
|
||||
}
|
||||
module_bark_battle::FinishValidationDecision::Rejected => BARK_BATTLE_VALIDATION_REJECTED,
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn battle_result_to_string(result: module_bark_battle::BattleResult) -> String {
|
||||
match result {
|
||||
module_bark_battle::BattleResult::PlayerWin => "player_win",
|
||||
module_bark_battle::BattleResult::OpponentWin => "opponent_win",
|
||||
module_bark_battle::BattleResult::Draw => "draw",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn compose_leaderboard_score(score: module_bark_battle::BarkBattleLeaderboardScore) -> u64 {
|
||||
u64::from(score.final_energy_millis) * 10_000_000
|
||||
+ score.trigger_count.min(9_999)
|
||||
+ u64::from(score.max_volume_millis).min(999) * 10_000
|
||||
+ (10_000_u64.saturating_sub(score.duration_closeness_ms.min(10_000)))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn bark_battle_types_are_constructible() {
|
||||
let input = BarkBattleDraftConfigUpsertInput {
|
||||
draft_id: "draft-1".to_string(),
|
||||
owner_user_id: "user-1".to_string(),
|
||||
work_id: "work-1".to_string(),
|
||||
config_version: 1,
|
||||
ruleset_version: BARK_BATTLE_DEFAULT_RULESET_VERSION.to_string(),
|
||||
difficulty_preset: BARK_BATTLE_DIFFICULTY_NORMAL.to_string(),
|
||||
leaderboard_enabled: true,
|
||||
config_json: "{}".to_string(),
|
||||
updated_at_micros: 1_700_000,
|
||||
};
|
||||
|
||||
let result = BarkBattleProcedureResult {
|
||||
ok: true,
|
||||
row_json: Some(input.config_json.clone()),
|
||||
error_message: None,
|
||||
};
|
||||
|
||||
assert_eq!(input.draft_id, "draft-1");
|
||||
assert_eq!(input.ruleset_version, BARK_BATTLE_DEFAULT_RULESET_VERSION);
|
||||
assert!(result.ok);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validates_light_editor_config_before_publish() {
|
||||
assert_eq!(
|
||||
normalize_difficulty(Some(BARK_BATTLE_DIFFICULTY_HARD)).expect("difficulty"),
|
||||
BARK_BATTLE_DIFFICULTY_HARD
|
||||
);
|
||||
assert!(normalize_difficulty(Some("insane")).is_err());
|
||||
assert!(normalize_title(Some(" 标题 ")).is_ok());
|
||||
assert!(normalize_title(Some(" ")).is_err());
|
||||
}
|
||||
}
|
||||
172
server-rs/crates/spacetime-module/src/bark_battle/tables.rs
Normal file
172
server-rs/crates/spacetime-module/src/bark_battle/tables.rs
Normal file
@@ -0,0 +1,172 @@
|
||||
use crate::*;
|
||||
|
||||
#[spacetimedb::table(
|
||||
accessor = bark_battle_draft_config,
|
||||
index(accessor = by_bark_battle_draft_owner_user_id, btree(columns = [owner_user_id])),
|
||||
index(accessor = by_bark_battle_draft_work_id, btree(columns = [work_id]))
|
||||
)]
|
||||
#[derive(Clone)]
|
||||
pub struct BarkBattleDraftConfigRow {
|
||||
#[primary_key]
|
||||
pub(crate) draft_id: String,
|
||||
pub(crate) owner_user_id: String,
|
||||
pub(crate) work_id: String,
|
||||
pub(crate) config_version: u64,
|
||||
pub(crate) ruleset_version: String,
|
||||
pub(crate) difficulty_preset: String,
|
||||
pub(crate) leaderboard_enabled: bool,
|
||||
pub(crate) config_json: String,
|
||||
pub(crate) editor_state_json: String,
|
||||
pub(crate) created_at: Timestamp,
|
||||
pub(crate) updated_at: Timestamp,
|
||||
}
|
||||
|
||||
#[spacetimedb::table(
|
||||
accessor = bark_battle_published_config,
|
||||
index(accessor = by_bark_battle_published_owner_user_id, btree(columns = [owner_user_id]))
|
||||
)]
|
||||
#[derive(Clone)]
|
||||
pub struct BarkBattlePublishedConfigRow {
|
||||
#[primary_key]
|
||||
pub(crate) work_id: String,
|
||||
pub(crate) owner_user_id: String,
|
||||
pub(crate) source_draft_id: Option<String>,
|
||||
pub(crate) config_version: u64,
|
||||
pub(crate) ruleset_version: String,
|
||||
pub(crate) difficulty_preset: String,
|
||||
pub(crate) leaderboard_enabled: bool,
|
||||
pub(crate) config_json: String,
|
||||
pub(crate) published_snapshot_json: String,
|
||||
pub(crate) created_at: Timestamp,
|
||||
pub(crate) updated_at: Timestamp,
|
||||
pub(crate) published_at: Timestamp,
|
||||
}
|
||||
|
||||
#[spacetimedb::table(
|
||||
accessor = bark_battle_runtime_run,
|
||||
index(accessor = by_bark_battle_run_owner_user_id, btree(columns = [owner_user_id])),
|
||||
index(accessor = by_bark_battle_run_work_id, btree(columns = [work_id]))
|
||||
)]
|
||||
#[derive(Clone)]
|
||||
pub struct BarkBattleRuntimeRunRow {
|
||||
#[primary_key]
|
||||
pub(crate) run_id: String,
|
||||
pub(crate) run_token_hash: String,
|
||||
pub(crate) owner_user_id: String,
|
||||
pub(crate) work_id: String,
|
||||
pub(crate) config_version: u64,
|
||||
pub(crate) ruleset_version: String,
|
||||
pub(crate) difficulty_preset: String,
|
||||
pub(crate) leaderboard_enabled: bool,
|
||||
pub(crate) status: String,
|
||||
pub(crate) client_started_at_micros: i64,
|
||||
pub(crate) server_started_at: Timestamp,
|
||||
pub(crate) client_finished_at_micros: Option<i64>,
|
||||
pub(crate) server_finished_at: Option<Timestamp>,
|
||||
pub(crate) metrics_json: String,
|
||||
pub(crate) server_result: Option<String>,
|
||||
pub(crate) validation_status: String,
|
||||
pub(crate) anti_cheat_flags_json: String,
|
||||
pub(crate) leaderboard_score: Option<u64>,
|
||||
pub(crate) score_id: Option<String>,
|
||||
pub(crate) created_at: Timestamp,
|
||||
pub(crate) updated_at: Timestamp,
|
||||
}
|
||||
|
||||
#[spacetimedb::table(
|
||||
accessor = bark_battle_score_record,
|
||||
index(accessor = by_bark_battle_score_owner_user_id, btree(columns = [owner_user_id])),
|
||||
index(accessor = by_bark_battle_score_work_id, btree(columns = [work_id])),
|
||||
index(accessor = by_bark_battle_score_run_id, btree(columns = [run_id]))
|
||||
)]
|
||||
#[derive(Clone)]
|
||||
pub struct BarkBattleScoreRecordRow {
|
||||
#[primary_key]
|
||||
pub(crate) score_id: String,
|
||||
pub(crate) owner_user_id: String,
|
||||
pub(crate) work_id: String,
|
||||
pub(crate) run_id: String,
|
||||
pub(crate) config_version: u64,
|
||||
pub(crate) ruleset_version: String,
|
||||
pub(crate) difficulty_preset: String,
|
||||
pub(crate) leaderboard_enabled: bool,
|
||||
pub(crate) metrics_json: String,
|
||||
pub(crate) derived_metrics_json: String,
|
||||
pub(crate) server_result: String,
|
||||
pub(crate) validation_status: String,
|
||||
pub(crate) anti_cheat_flags_json: String,
|
||||
pub(crate) leaderboard_score: Option<u64>,
|
||||
pub(crate) recorded_at: Timestamp,
|
||||
}
|
||||
|
||||
#[spacetimedb::table(
|
||||
accessor = bark_battle_leaderboard_entry,
|
||||
index(accessor = by_bark_battle_leaderboard_work_score, btree(columns = [work_id, leaderboard_score])),
|
||||
index(accessor = by_bark_battle_leaderboard_owner_work, btree(columns = [owner_user_id, work_id]))
|
||||
)]
|
||||
#[derive(Clone)]
|
||||
pub struct BarkBattleLeaderboardEntryRow {
|
||||
#[primary_key]
|
||||
pub(crate) leaderboard_entry_id: String,
|
||||
pub(crate) work_id: String,
|
||||
pub(crate) owner_user_id: String,
|
||||
pub(crate) run_id: String,
|
||||
pub(crate) score_id: String,
|
||||
pub(crate) leaderboard_score: u64,
|
||||
pub(crate) final_energy: f32,
|
||||
pub(crate) trigger_count: u64,
|
||||
pub(crate) max_volume: f32,
|
||||
pub(crate) duration_closeness_ms: u64,
|
||||
pub(crate) finished_at_micros: i64,
|
||||
pub(crate) created_at: Timestamp,
|
||||
pub(crate) updated_at: Timestamp,
|
||||
}
|
||||
|
||||
#[spacetimedb::table(
|
||||
accessor = bark_battle_work_stats_projection,
|
||||
index(accessor = by_bark_battle_work_stats_owner_user_id, btree(columns = [owner_user_id]))
|
||||
)]
|
||||
#[derive(Clone)]
|
||||
pub struct BarkBattleWorkStatsProjectionRow {
|
||||
#[primary_key]
|
||||
pub(crate) work_id: String,
|
||||
pub(crate) owner_user_id: String,
|
||||
pub(crate) play_count: u64,
|
||||
pub(crate) finished_count: u64,
|
||||
pub(crate) accepted_score_count: u64,
|
||||
pub(crate) leaderboard_entry_count: u64,
|
||||
pub(crate) best_leaderboard_score: Option<u64>,
|
||||
pub(crate) best_score_id: Option<String>,
|
||||
pub(crate) best_run_id: Option<String>,
|
||||
pub(crate) average_final_energy: f32,
|
||||
pub(crate) average_trigger_count: f32,
|
||||
pub(crate) last_finished_at_micros: Option<i64>,
|
||||
pub(crate) stats_json: String,
|
||||
pub(crate) updated_at: Timestamp,
|
||||
}
|
||||
|
||||
#[spacetimedb::table(
|
||||
accessor = bark_battle_personal_best_projection,
|
||||
index(accessor = by_bark_battle_personal_best_work_id, btree(columns = [work_id])),
|
||||
index(accessor = by_bark_battle_personal_best_owner_work, btree(columns = [owner_user_id, work_id]))
|
||||
)]
|
||||
#[derive(Clone)]
|
||||
pub struct BarkBattlePersonalBestProjectionRow {
|
||||
#[primary_key]
|
||||
pub(crate) personal_best_id: String,
|
||||
pub(crate) owner_user_id: String,
|
||||
pub(crate) work_id: String,
|
||||
pub(crate) run_id: String,
|
||||
pub(crate) score_id: String,
|
||||
pub(crate) leaderboard_entry_id: Option<String>,
|
||||
pub(crate) leaderboard_score: Option<u64>,
|
||||
pub(crate) final_energy: f32,
|
||||
pub(crate) trigger_count: u64,
|
||||
pub(crate) max_volume: f32,
|
||||
pub(crate) duration_closeness_ms: u64,
|
||||
pub(crate) server_result: String,
|
||||
pub(crate) validation_status: String,
|
||||
pub(crate) finished_at_micros: i64,
|
||||
pub(crate) summary_json: String,
|
||||
pub(crate) updated_at: Timestamp,
|
||||
}
|
||||
177
server-rs/crates/spacetime-module/src/bark_battle/types.rs
Normal file
177
server-rs/crates/spacetime-module/src/bark_battle/types.rs
Normal file
@@ -0,0 +1,177 @@
|
||||
use crate::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const BARK_BATTLE_DEFAULT_RULESET_VERSION: &str =
|
||||
module_bark_battle::BARK_BATTLE_RULESET_VERSION_V1;
|
||||
pub const BARK_BATTLE_DIFFICULTY_EASY: &str = "easy";
|
||||
pub const BARK_BATTLE_DIFFICULTY_NORMAL: &str = "normal";
|
||||
pub const BARK_BATTLE_DIFFICULTY_HARD: &str = "hard";
|
||||
|
||||
pub const BARK_BATTLE_RUN_PENDING: &str = "Pending";
|
||||
pub const BARK_BATTLE_RUN_RUNNING: &str = "Running";
|
||||
pub const BARK_BATTLE_RUN_FINISHED: &str = "Finished";
|
||||
pub const BARK_BATTLE_RUN_ABORTED: &str = "Aborted";
|
||||
|
||||
pub const BARK_BATTLE_VALIDATION_PENDING: &str = "pending";
|
||||
pub const BARK_BATTLE_VALIDATION_ACCEPTED: &str = "accepted";
|
||||
pub const BARK_BATTLE_VALIDATION_ACCEPTED_WITH_FLAGS: &str = "accepted_with_flags";
|
||||
pub const BARK_BATTLE_VALIDATION_REJECTED: &str = "rejected";
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct BarkBattleDraftCreateInput {
|
||||
pub draft_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub title: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub theme_preset: String,
|
||||
pub player_dog_skin_preset: String,
|
||||
pub opponent_dog_skin_preset: String,
|
||||
pub difficulty_preset: Option<String>,
|
||||
pub leaderboard_enabled: Option<bool>,
|
||||
pub editor_state_json: Option<String>,
|
||||
pub created_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct BarkBattleDraftConfigUpsertInput {
|
||||
pub draft_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub config_json: String,
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct BarkBattleWorkPublishInput {
|
||||
pub draft_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub published_snapshot_json: Option<String>,
|
||||
pub published_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct BarkBattleRuntimeConfigGetInput {
|
||||
pub work_id: String,
|
||||
pub owner_user_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct BarkBattleRunStartInput {
|
||||
pub run_id: String,
|
||||
pub run_token: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub client_started_at_micros: i64,
|
||||
pub server_started_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct BarkBattleRunFinishInput {
|
||||
pub run_id: String,
|
||||
pub run_token: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub client_finished_at_micros: i64,
|
||||
pub server_finished_at_micros: i64,
|
||||
pub duration_ms: u64,
|
||||
pub trigger_count: u64,
|
||||
pub max_volume_millis: u32,
|
||||
pub average_volume_millis: u32,
|
||||
pub final_energy_millis: u32,
|
||||
pub opponent_final_energy_millis: u32,
|
||||
pub max_combo: u32,
|
||||
pub metrics_json: String,
|
||||
pub derived_metrics_json: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct BarkBattleRunGetInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct BarkBattleProcedureResult {
|
||||
pub ok: bool,
|
||||
pub row_json: Option<String>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleEditorConfigSnapshot {
|
||||
pub title: String,
|
||||
pub description: String,
|
||||
pub theme_preset: String,
|
||||
pub player_dog_skin_preset: String,
|
||||
pub opponent_dog_skin_preset: String,
|
||||
pub difficulty_preset: String,
|
||||
pub leaderboard_enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleDraftConfigSnapshot {
|
||||
pub draft_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub config_json: String,
|
||||
pub editor_state_json: String,
|
||||
pub created_at_micros: i64,
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleRuntimeConfigSnapshot {
|
||||
pub work_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub source_draft_id: Option<String>,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub config_json: String,
|
||||
pub published_snapshot_json: String,
|
||||
pub published_at_micros: i64,
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BarkBattleRunSnapshot {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_id: String,
|
||||
pub config_version: u64,
|
||||
pub ruleset_version: String,
|
||||
pub difficulty_preset: String,
|
||||
pub leaderboard_enabled: bool,
|
||||
pub status: String,
|
||||
pub client_started_at_micros: i64,
|
||||
pub server_started_at_micros: i64,
|
||||
pub client_finished_at_micros: Option<i64>,
|
||||
pub server_finished_at_micros: Option<i64>,
|
||||
pub metrics_json: String,
|
||||
pub server_result: Option<String>,
|
||||
pub validation_status: String,
|
||||
pub anti_cheat_flags_json: String,
|
||||
pub leaderboard_score: Option<u64>,
|
||||
pub score_id: Option<String>,
|
||||
}
|
||||
@@ -23,6 +23,7 @@ pub use spacetimedb::{
|
||||
mod ai;
|
||||
mod asset_metadata;
|
||||
mod auth;
|
||||
mod bark_battle;
|
||||
mod big_fish;
|
||||
mod custom_world;
|
||||
mod domain_types;
|
||||
@@ -38,6 +39,7 @@ mod visual_novel;
|
||||
pub use ai::*;
|
||||
pub use asset_metadata::*;
|
||||
pub use auth::*;
|
||||
pub use bark_battle::*;
|
||||
pub use big_fish::*;
|
||||
pub use custom_world::*;
|
||||
pub use domain_types::*;
|
||||
|
||||
@@ -6,6 +6,11 @@ use spacetimedb::sats::de::serde::DeserializeWrapper;
|
||||
use spacetimedb::sats::ser::serde::SerializeWrapper;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::bark_battle::tables::{
|
||||
bark_battle_draft_config, bark_battle_leaderboard_entry, bark_battle_personal_best_projection,
|
||||
bark_battle_published_config, bark_battle_runtime_run, bark_battle_score_record,
|
||||
bark_battle_work_stats_projection,
|
||||
};
|
||||
use crate::big_fish::big_fish_runtime_run;
|
||||
use crate::match3d::tables::{
|
||||
match3d_agent_message, match3d_agent_session, match3d_runtime_run, match3d_work_profile,
|
||||
@@ -216,6 +221,13 @@ macro_rules! migration_tables {
|
||||
puzzle_event,
|
||||
puzzle_runtime_run,
|
||||
puzzle_leaderboard_entry,
|
||||
bark_battle_draft_config,
|
||||
bark_battle_published_config,
|
||||
bark_battle_runtime_run,
|
||||
bark_battle_score_record,
|
||||
bark_battle_leaderboard_entry,
|
||||
bark_battle_work_stats_projection,
|
||||
bark_battle_personal_best_projection,
|
||||
match3d_agent_session,
|
||||
match3d_agent_message,
|
||||
match3d_work_profile,
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
pub mod analytics_date_dimension;
|
||||
pub mod creation_entry_config;
|
||||
mod browse_history;
|
||||
pub mod creation_entry_config;
|
||||
mod profile;
|
||||
mod settings;
|
||||
mod snapshots;
|
||||
|
||||
pub use analytics_date_dimension::*;
|
||||
pub use creation_entry_config::*;
|
||||
pub use browse_history::*;
|
||||
pub use creation_entry_config::*;
|
||||
pub use profile::*;
|
||||
pub use settings::*;
|
||||
pub use snapshots::*;
|
||||
|
||||
Reference in New Issue
Block a user