From aae00a1036d3d727fd1ddc6626dacc837e1dd2ac Mon Sep 17 00:00:00 2001 From: Mathih13 Date: Wed, 7 Oct 2026 12:35:56 +0200 Subject: [PATCH] refactor(bridge): let the Package name its client-command reply Core sent every Companion Order outcome under a hard-coded Package command name. The game_client_command! marker now takes a third argument, a const that names the reply command, and Core sends outcomes under that name. The seven command fixture reducers become party_command_fixture_*, the Gateway bindings are regenerated, and the group intent log lines drop their Package prefix. Co-Authored-By: Claude Opus 5.5 (1M context) --- crates/lyracore-test-support/src/lib.rs | 4 +- docs/package-api.md | 2 +- gateway/src/codec/addon.rs | 4 +- gateway/src/stdb/bindings/mod.rs | 90 +++++++++---------- ...ixture_apply_after_gate_change_reducer.rs} | 32 +++---- ...=> party_command_fixture_apply_reducer.rs} | 36 ++++---- ...=> party_command_fixture_drive_reducer.rs} | 36 ++++---- ...re_expire_after_receipt_window_reducer.rs} | 32 +++---- ...> party_command_fixture_expire_reducer.rs} | 36 ++++---- ...> party_command_fixture_finish_reducer.rs} | 36 ++++---- ...ommand_fixture_release_receipt_reducer.rs} | 32 +++---- gateway/src/stdb/subscriptions.rs | 4 +- gateway/src/world/framing_tests.rs | 8 +- module/build.rs | 76 +++++++++------- module/src/actor.rs | 2 +- module/src/bridge.rs | 60 +++++++------ module/src/lib.rs | 3 +- 17 files changed, 246 insertions(+), 247 deletions(-) rename gateway/src/stdb/bindings/{playerbots_fixture_command_apply_after_gate_change_reducer.rs => party_command_fixture_apply_after_gate_change_reducer.rs} (60%) rename gateway/src/stdb/bindings/{playerbots_fixture_command_apply_reducer.rs => party_command_fixture_apply_reducer.rs} (60%) rename gateway/src/stdb/bindings/{playerbots_fixture_command_drive_reducer.rs => party_command_fixture_drive_reducer.rs} (60%) rename gateway/src/stdb/bindings/{playerbots_fixture_command_expire_after_receipt_window_reducer.rs => party_command_fixture_expire_after_receipt_window_reducer.rs} (53%) rename gateway/src/stdb/bindings/{playerbots_fixture_command_expire_reducer.rs => party_command_fixture_expire_reducer.rs} (55%) rename gateway/src/stdb/bindings/{playerbots_fixture_command_finish_reducer.rs => party_command_fixture_finish_reducer.rs} (59%) rename gateway/src/stdb/bindings/{playerbots_fixture_command_release_receipt_reducer.rs => party_command_fixture_release_receipt_reducer.rs} (55%) diff --git a/crates/lyracore-test-support/src/lib.rs b/crates/lyracore-test-support/src/lib.rs index 6f702867a..96673f67f 100644 --- a/crates/lyracore-test-support/src/lib.rs +++ b/crates/lyracore-test-support/src/lib.rs @@ -676,12 +676,12 @@ mod tests { #[test] fn text_rows_preserve_the_addon_reply_separator() { let rows = parse_text_rows( - "id | cmd | payload\n---+-----+--------\n1 | \"playerbots.order.result\" | \"1|Applied\"\n", + "id | cmd | payload\n---+-----+--------\n1 | \"example.order.result\" | \"1|Applied\"\n", ); assert_eq!(rows.len(), 1); assert_eq!(rows[0].len(), 3); assert_eq!(rows[0]["id"], "1"); - assert_eq!(rows[0]["cmd"], "playerbots.order.result"); + assert_eq!(rows[0]["cmd"], "example.order.result"); assert_eq!(rows[0]["payload"], "1|Applied"); } diff --git a/docs/package-api.md b/docs/package-api.md index d1ed19c26..103a2f5dc 100644 --- a/docs/package-api.md +++ b/docs/package-api.md @@ -38,7 +38,7 @@ which must be written literally. |---|---| | `crate::game_hook!(EVENT, fn NAME(ctx, payload) { .. })` | a notify handler for one hook event | | `crate::game_tick_pass!(fn NAME(ctx) { .. })` | a periodic pass, run at the end of every `tick_creatures` tick (0.5s), after every core pass | -| `crate::game_client_command!(PARSE, APPLY)` | the single Package parser and admitted apply operation for authenticated addon commands | +| `crate::game_client_command!(PARSE, APPLY, REPLY)` | the single Package parser, admitted apply operation and reply command name for authenticated addon commands | | `crate::character_owned!(delete \| restamp \| transfer \| not_transported, ..)` | a Package table's character-keyed sweeps and its cross-shard transport arm | | `crate::encounter_package!(BINDING, fn NAME(ctx, instance_id, signal) { .. })` | encounter authority for one Encounter Binding | diff --git a/gateway/src/codec/addon.rs b/gateway/src/codec/addon.rs index 35100f446..9c718889c 100644 --- a/gateway/src/codec/addon.rs +++ b/gateway/src/codec/addon.rs @@ -267,8 +267,8 @@ mod tests { #[test] fn escaped_envelope_decodes_payload_pipes_once() { assert_eq!( - parse_bridge_envelope("STC\tv1||playerbots.order||21||1/1||follow||2126"), - Some(("playerbots.order".into(), "follow|2126".into())) + parse_bridge_envelope("STC\tv1||example.order||21||1/1||follow||2126"), + Some(("example.order".into(), "follow|2126".into())) ); assert_eq!( parse_bridge_envelope("STC\tv1||ping||22||1/1||a||||b"), diff --git a/gateway/src/stdb/bindings/mod.rs b/gateway/src/stdb/bindings/mod.rs index 80ec966bc..b22e04af9 100644 --- a/gateway/src/stdb/bindings/mod.rs +++ b/gateway/src/stdb/bindings/mod.rs @@ -915,6 +915,13 @@ pub mod package_config_type; pub mod package_import_type; pub mod parsed_client_command_type; pub mod party_command_dispatch_lane_type; +pub mod party_command_fixture_apply_after_gate_change_reducer; +pub mod party_command_fixture_apply_reducer; +pub mod party_command_fixture_drive_reducer; +pub mod party_command_fixture_expire_after_receipt_window_reducer; +pub mod party_command_fixture_expire_reducer; +pub mod party_command_fixture_finish_reducer; +pub mod party_command_fixture_release_receipt_reducer; pub mod party_command_intent_type; pub mod party_command_issuer_type; pub mod party_command_receipt_type; @@ -932,13 +939,6 @@ pub mod player_action_type; pub mod player_reputation_type; pub mod player_skill_type; pub mod player_spell_type; -pub mod playerbots_fixture_command_apply_after_gate_change_reducer; -pub mod playerbots_fixture_command_apply_reducer; -pub mod playerbots_fixture_command_drive_reducer; -pub mod playerbots_fixture_command_expire_after_receipt_window_reducer; -pub mod playerbots_fixture_command_expire_reducer; -pub mod playerbots_fixture_command_finish_reducer; -pub mod playerbots_fixture_command_release_receipt_reducer; pub mod posture_admission_type; pub mod prepare_vmap_nav_coverage_reducer; pub mod provision_account_reducer; @@ -2088,6 +2088,13 @@ pub use package_config_type::PackageConfig; pub use package_import_type::PackageImport; pub use parsed_client_command_type::ParsedClientCommand; pub use party_command_dispatch_lane_type::PartyCommandDispatchLane; +pub use party_command_fixture_apply_after_gate_change_reducer::party_command_fixture_apply_after_gate_change; +pub use party_command_fixture_apply_reducer::party_command_fixture_apply; +pub use party_command_fixture_drive_reducer::party_command_fixture_drive; +pub use party_command_fixture_expire_after_receipt_window_reducer::party_command_fixture_expire_after_receipt_window; +pub use party_command_fixture_expire_reducer::party_command_fixture_expire; +pub use party_command_fixture_finish_reducer::party_command_fixture_finish; +pub use party_command_fixture_release_receipt_reducer::party_command_fixture_release_receipt; pub use party_command_intent_type::PartyCommandIntent; pub use party_command_issuer_type::PartyCommandIssuer; pub use party_command_receipt_type::PartyCommandReceipt; @@ -2105,13 +2112,6 @@ pub use player_action_type::PlayerAction; pub use player_reputation_type::PlayerReputation; pub use player_skill_type::PlayerSkill; pub use player_spell_type::PlayerSpell; -pub use playerbots_fixture_command_apply_after_gate_change_reducer::playerbots_fixture_command_apply_after_gate_change; -pub use playerbots_fixture_command_apply_reducer::playerbots_fixture_command_apply; -pub use playerbots_fixture_command_drive_reducer::playerbots_fixture_command_drive; -pub use playerbots_fixture_command_expire_after_receipt_window_reducer::playerbots_fixture_command_expire_after_receipt_window; -pub use playerbots_fixture_command_expire_reducer::playerbots_fixture_command_expire; -pub use playerbots_fixture_command_finish_reducer::playerbots_fixture_command_finish; -pub use playerbots_fixture_command_release_receipt_reducer::playerbots_fixture_command_release_receipt; pub use posture_admission_type::PostureAdmission; pub use prepare_vmap_nav_coverage_reducer::prepare_vmap_nav_coverage; pub use provision_account_reducer::provision_account; @@ -3937,30 +3937,30 @@ pub enum Reducer { claim_token: u64, }, OnDisconnect, - PlayerbotsFixtureCommandApply { + PartyCommandFixtureApply { intent_id: u64, claim_token: u64, }, - PlayerbotsFixtureCommandApplyAfterGateChange { + PartyCommandFixtureApplyAfterGateChange { intent_id: u64, claim_token: u64, mode: u8, }, - PlayerbotsFixtureCommandDrive { + PartyCommandFixtureDrive { intent_id: u64, claim_token: u64, }, - PlayerbotsFixtureCommandExpire { + PartyCommandFixtureExpire { intent_id: u64, }, - PlayerbotsFixtureCommandExpireAfterReceiptWindow { + PartyCommandFixtureExpireAfterReceiptWindow { intent_id: u64, }, - PlayerbotsFixtureCommandFinish { + PartyCommandFixtureFinish { intent_id: u64, claim_token: u64, }, - PlayerbotsFixtureCommandReleaseReceipt { + PartyCommandFixtureReleaseReceipt { bot_guid: u64, }, PrepareVmapNavCoverage { @@ -4806,18 +4806,18 @@ impl __sdk::Reducer for Reducer { Reducer::InstallGuidRange { .. } => "install_guid_range", Reducer::MarkBotTransferArrivalReady { .. } => "mark_bot_transfer_arrival_ready", Reducer::OnDisconnect => "on_disconnect", - Reducer::PlayerbotsFixtureCommandApply { .. } => "playerbots_fixture_command_apply", - Reducer::PlayerbotsFixtureCommandApplyAfterGateChange { .. } => { - "playerbots_fixture_command_apply_after_gate_change" + Reducer::PartyCommandFixtureApply { .. } => "party_command_fixture_apply", + Reducer::PartyCommandFixtureApplyAfterGateChange { .. } => { + "party_command_fixture_apply_after_gate_change" } - Reducer::PlayerbotsFixtureCommandDrive { .. } => "playerbots_fixture_command_drive", - Reducer::PlayerbotsFixtureCommandExpire { .. } => "playerbots_fixture_command_expire", - Reducer::PlayerbotsFixtureCommandExpireAfterReceiptWindow { .. } => { - "playerbots_fixture_command_expire_after_receipt_window" + Reducer::PartyCommandFixtureDrive { .. } => "party_command_fixture_drive", + Reducer::PartyCommandFixtureExpire { .. } => "party_command_fixture_expire", + Reducer::PartyCommandFixtureExpireAfterReceiptWindow { .. } => { + "party_command_fixture_expire_after_receipt_window" } - Reducer::PlayerbotsFixtureCommandFinish { .. } => "playerbots_fixture_command_finish", - Reducer::PlayerbotsFixtureCommandReleaseReceipt { .. } => { - "playerbots_fixture_command_release_receipt" + Reducer::PartyCommandFixtureFinish { .. } => "party_command_fixture_finish", + Reducer::PartyCommandFixtureReleaseReceipt { .. } => { + "party_command_fixture_release_receipt" } Reducer::PrepareVmapNavCoverage { .. } => "prepare_vmap_nav_coverage", Reducer::ProvisionAccount { .. } => "provision_account", @@ -7732,49 +7732,49 @@ Reducer::GwIgnoreTrade{ }), Reducer::OnDisconnect => __sats::bsatn::to_vec(&on_disconnect_reducer::OnDisconnectArgs { }), -Reducer::PlayerbotsFixtureCommandApply{ +Reducer::PartyCommandFixtureApply{ intent_id, claim_token, -} => __sats::bsatn::to_vec(&playerbots_fixture_command_apply_reducer::PlayerbotsFixtureCommandApplyArgs { +} => __sats::bsatn::to_vec(&party_command_fixture_apply_reducer::PartyCommandFixtureApplyArgs { intent_id: intent_id.clone(), claim_token: claim_token.clone(), }), - Reducer::PlayerbotsFixtureCommandApplyAfterGateChange{ + Reducer::PartyCommandFixtureApplyAfterGateChange{ intent_id, claim_token, mode, -} => __sats::bsatn::to_vec(&playerbots_fixture_command_apply_after_gate_change_reducer::PlayerbotsFixtureCommandApplyAfterGateChangeArgs { +} => __sats::bsatn::to_vec(&party_command_fixture_apply_after_gate_change_reducer::PartyCommandFixtureApplyAfterGateChangeArgs { intent_id: intent_id.clone(), claim_token: claim_token.clone(), mode: mode.clone(), }), - Reducer::PlayerbotsFixtureCommandDrive{ + Reducer::PartyCommandFixtureDrive{ intent_id, claim_token, -} => __sats::bsatn::to_vec(&playerbots_fixture_command_drive_reducer::PlayerbotsFixtureCommandDriveArgs { +} => __sats::bsatn::to_vec(&party_command_fixture_drive_reducer::PartyCommandFixtureDriveArgs { intent_id: intent_id.clone(), claim_token: claim_token.clone(), }), - Reducer::PlayerbotsFixtureCommandExpire{ + Reducer::PartyCommandFixtureExpire{ intent_id, -} => __sats::bsatn::to_vec(&playerbots_fixture_command_expire_reducer::PlayerbotsFixtureCommandExpireArgs { +} => __sats::bsatn::to_vec(&party_command_fixture_expire_reducer::PartyCommandFixtureExpireArgs { intent_id: intent_id.clone(), }), - Reducer::PlayerbotsFixtureCommandExpireAfterReceiptWindow{ + Reducer::PartyCommandFixtureExpireAfterReceiptWindow{ intent_id, -} => __sats::bsatn::to_vec(&playerbots_fixture_command_expire_after_receipt_window_reducer::PlayerbotsFixtureCommandExpireAfterReceiptWindowArgs { +} => __sats::bsatn::to_vec(&party_command_fixture_expire_after_receipt_window_reducer::PartyCommandFixtureExpireAfterReceiptWindowArgs { intent_id: intent_id.clone(), }), - Reducer::PlayerbotsFixtureCommandFinish{ + Reducer::PartyCommandFixtureFinish{ intent_id, claim_token, -} => __sats::bsatn::to_vec(&playerbots_fixture_command_finish_reducer::PlayerbotsFixtureCommandFinishArgs { +} => __sats::bsatn::to_vec(&party_command_fixture_finish_reducer::PartyCommandFixtureFinishArgs { intent_id: intent_id.clone(), claim_token: claim_token.clone(), }), - Reducer::PlayerbotsFixtureCommandReleaseReceipt{ + Reducer::PartyCommandFixtureReleaseReceipt{ bot_guid, -} => __sats::bsatn::to_vec(&playerbots_fixture_command_release_receipt_reducer::PlayerbotsFixtureCommandReleaseReceiptArgs { +} => __sats::bsatn::to_vec(&party_command_fixture_release_receipt_reducer::PartyCommandFixtureReleaseReceiptArgs { bot_guid: bot_guid.clone(), }), Reducer::PrepareVmapNavCoverage{ diff --git a/gateway/src/stdb/bindings/playerbots_fixture_command_apply_after_gate_change_reducer.rs b/gateway/src/stdb/bindings/party_command_fixture_apply_after_gate_change_reducer.rs similarity index 60% rename from gateway/src/stdb/bindings/playerbots_fixture_command_apply_after_gate_change_reducer.rs rename to gateway/src/stdb/bindings/party_command_fixture_apply_after_gate_change_reducer.rs index a442cc2dd..1eb9627e2 100644 --- a/gateway/src/stdb/bindings/playerbots_fixture_command_apply_after_gate_change_reducer.rs +++ b/gateway/src/stdb/bindings/party_command_fixture_apply_after_gate_change_reducer.rs @@ -6,15 +6,15 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] -pub(super) struct PlayerbotsFixtureCommandApplyAfterGateChangeArgs { +pub(super) struct PartyCommandFixtureApplyAfterGateChangeArgs { pub intent_id: u64, pub claim_token: u64, pub mode: u8, } -impl From for super::Reducer { - fn from(args: PlayerbotsFixtureCommandApplyAfterGateChangeArgs) -> Self { - Self::PlayerbotsFixtureCommandApplyAfterGateChange { +impl From for super::Reducer { + fn from(args: PartyCommandFixtureApplyAfterGateChangeArgs) -> Self { + Self::PartyCommandFixtureApplyAfterGateChange { intent_id: args.intent_id, claim_token: args.claim_token, mode: args.mode, @@ -22,28 +22,28 @@ impl From for super::Reducer { } } -impl __sdk::InModule for PlayerbotsFixtureCommandApplyAfterGateChangeArgs { +impl __sdk::InModule for PartyCommandFixtureApplyAfterGateChangeArgs { type Module = super::RemoteModule; } #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `playerbots_fixture_command_apply_after_gate_change`. +/// Extension trait for access to the reducer `party_command_fixture_apply_after_gate_change`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait playerbots_fixture_command_apply_after_gate_change { - /// Request that the remote module invoke the reducer `playerbots_fixture_command_apply_after_gate_change` to run as soon as possible. +pub trait party_command_fixture_apply_after_gate_change { + /// Request that the remote module invoke the reducer `party_command_fixture_apply_after_gate_change` to run as soon as possible. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and this method provides no way to listen for its completion status. - /// /// Use [`playerbots_fixture_command_apply_after_gate_change:playerbots_fixture_command_apply_after_gate_change_then`] to run a callback after the reducer completes. - fn playerbots_fixture_command_apply_after_gate_change( + /// /// Use [`party_command_fixture_apply_after_gate_change:party_command_fixture_apply_after_gate_change_then`] to run a callback after the reducer completes. + fn party_command_fixture_apply_after_gate_change( &self, intent_id: u64, claim_token: u64, mode: u8, ) -> __sdk::Result<()> { - self.playerbots_fixture_command_apply_after_gate_change_then( + self.party_command_fixture_apply_after_gate_change_then( intent_id, claim_token, mode, @@ -51,13 +51,13 @@ pub trait playerbots_fixture_command_apply_after_gate_change { ) } - /// Request that the remote module invoke the reducer `playerbots_fixture_command_apply_after_gate_change` to run as soon as possible, + /// Request that the remote module invoke the reducer `party_command_fixture_apply_after_gate_change` to run as soon as possible, /// registering `callback` to run when we are notified that the reducer completed. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed with the `callback`. - fn playerbots_fixture_command_apply_after_gate_change_then( + fn party_command_fixture_apply_after_gate_change_then( &self, intent_id: u64, claim_token: u64, @@ -69,8 +69,8 @@ pub trait playerbots_fixture_command_apply_after_gate_change { ) -> __sdk::Result<()>; } -impl playerbots_fixture_command_apply_after_gate_change for super::RemoteReducers { - fn playerbots_fixture_command_apply_after_gate_change_then( +impl party_command_fixture_apply_after_gate_change for super::RemoteReducers { + fn party_command_fixture_apply_after_gate_change_then( &self, intent_id: u64, claim_token: u64, @@ -81,7 +81,7 @@ impl playerbots_fixture_command_apply_after_gate_change for super::RemoteReducer + 'static, ) -> __sdk::Result<()> { self.imp.invoke_reducer_with_callback( - PlayerbotsFixtureCommandApplyAfterGateChangeArgs { + PartyCommandFixtureApplyAfterGateChangeArgs { intent_id, claim_token, mode, diff --git a/gateway/src/stdb/bindings/playerbots_fixture_command_apply_reducer.rs b/gateway/src/stdb/bindings/party_command_fixture_apply_reducer.rs similarity index 60% rename from gateway/src/stdb/bindings/playerbots_fixture_command_apply_reducer.rs rename to gateway/src/stdb/bindings/party_command_fixture_apply_reducer.rs index 7c1be4fef..b25e3cdf5 100644 --- a/gateway/src/stdb/bindings/playerbots_fixture_command_apply_reducer.rs +++ b/gateway/src/stdb/bindings/party_command_fixture_apply_reducer.rs @@ -6,50 +6,46 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] -pub(super) struct PlayerbotsFixtureCommandApplyArgs { +pub(super) struct PartyCommandFixtureApplyArgs { pub intent_id: u64, pub claim_token: u64, } -impl From for super::Reducer { - fn from(args: PlayerbotsFixtureCommandApplyArgs) -> Self { - Self::PlayerbotsFixtureCommandApply { +impl From for super::Reducer { + fn from(args: PartyCommandFixtureApplyArgs) -> Self { + Self::PartyCommandFixtureApply { intent_id: args.intent_id, claim_token: args.claim_token, } } } -impl __sdk::InModule for PlayerbotsFixtureCommandApplyArgs { +impl __sdk::InModule for PartyCommandFixtureApplyArgs { type Module = super::RemoteModule; } #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `playerbots_fixture_command_apply`. +/// Extension trait for access to the reducer `party_command_fixture_apply`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait playerbots_fixture_command_apply { - /// Request that the remote module invoke the reducer `playerbots_fixture_command_apply` to run as soon as possible. +pub trait party_command_fixture_apply { + /// Request that the remote module invoke the reducer `party_command_fixture_apply` to run as soon as possible. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and this method provides no way to listen for its completion status. - /// /// Use [`playerbots_fixture_command_apply:playerbots_fixture_command_apply_then`] to run a callback after the reducer completes. - fn playerbots_fixture_command_apply( - &self, - intent_id: u64, - claim_token: u64, - ) -> __sdk::Result<()> { - self.playerbots_fixture_command_apply_then(intent_id, claim_token, |_, _| {}) + /// /// Use [`party_command_fixture_apply:party_command_fixture_apply_then`] to run a callback after the reducer completes. + fn party_command_fixture_apply(&self, intent_id: u64, claim_token: u64) -> __sdk::Result<()> { + self.party_command_fixture_apply_then(intent_id, claim_token, |_, _| {}) } - /// Request that the remote module invoke the reducer `playerbots_fixture_command_apply` to run as soon as possible, + /// Request that the remote module invoke the reducer `party_command_fixture_apply` to run as soon as possible, /// registering `callback` to run when we are notified that the reducer completed. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed with the `callback`. - fn playerbots_fixture_command_apply_then( + fn party_command_fixture_apply_then( &self, intent_id: u64, claim_token: u64, @@ -60,8 +56,8 @@ pub trait playerbots_fixture_command_apply { ) -> __sdk::Result<()>; } -impl playerbots_fixture_command_apply for super::RemoteReducers { - fn playerbots_fixture_command_apply_then( +impl party_command_fixture_apply for super::RemoteReducers { + fn party_command_fixture_apply_then( &self, intent_id: u64, claim_token: u64, @@ -71,7 +67,7 @@ impl playerbots_fixture_command_apply for super::RemoteReducers { + 'static, ) -> __sdk::Result<()> { self.imp.invoke_reducer_with_callback( - PlayerbotsFixtureCommandApplyArgs { + PartyCommandFixtureApplyArgs { intent_id, claim_token, }, diff --git a/gateway/src/stdb/bindings/playerbots_fixture_command_drive_reducer.rs b/gateway/src/stdb/bindings/party_command_fixture_drive_reducer.rs similarity index 60% rename from gateway/src/stdb/bindings/playerbots_fixture_command_drive_reducer.rs rename to gateway/src/stdb/bindings/party_command_fixture_drive_reducer.rs index cefc575e4..1de9b99f8 100644 --- a/gateway/src/stdb/bindings/playerbots_fixture_command_drive_reducer.rs +++ b/gateway/src/stdb/bindings/party_command_fixture_drive_reducer.rs @@ -6,50 +6,46 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] -pub(super) struct PlayerbotsFixtureCommandDriveArgs { +pub(super) struct PartyCommandFixtureDriveArgs { pub intent_id: u64, pub claim_token: u64, } -impl From for super::Reducer { - fn from(args: PlayerbotsFixtureCommandDriveArgs) -> Self { - Self::PlayerbotsFixtureCommandDrive { +impl From for super::Reducer { + fn from(args: PartyCommandFixtureDriveArgs) -> Self { + Self::PartyCommandFixtureDrive { intent_id: args.intent_id, claim_token: args.claim_token, } } } -impl __sdk::InModule for PlayerbotsFixtureCommandDriveArgs { +impl __sdk::InModule for PartyCommandFixtureDriveArgs { type Module = super::RemoteModule; } #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `playerbots_fixture_command_drive`. +/// Extension trait for access to the reducer `party_command_fixture_drive`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait playerbots_fixture_command_drive { - /// Request that the remote module invoke the reducer `playerbots_fixture_command_drive` to run as soon as possible. +pub trait party_command_fixture_drive { + /// Request that the remote module invoke the reducer `party_command_fixture_drive` to run as soon as possible. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and this method provides no way to listen for its completion status. - /// /// Use [`playerbots_fixture_command_drive:playerbots_fixture_command_drive_then`] to run a callback after the reducer completes. - fn playerbots_fixture_command_drive( - &self, - intent_id: u64, - claim_token: u64, - ) -> __sdk::Result<()> { - self.playerbots_fixture_command_drive_then(intent_id, claim_token, |_, _| {}) + /// /// Use [`party_command_fixture_drive:party_command_fixture_drive_then`] to run a callback after the reducer completes. + fn party_command_fixture_drive(&self, intent_id: u64, claim_token: u64) -> __sdk::Result<()> { + self.party_command_fixture_drive_then(intent_id, claim_token, |_, _| {}) } - /// Request that the remote module invoke the reducer `playerbots_fixture_command_drive` to run as soon as possible, + /// Request that the remote module invoke the reducer `party_command_fixture_drive` to run as soon as possible, /// registering `callback` to run when we are notified that the reducer completed. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed with the `callback`. - fn playerbots_fixture_command_drive_then( + fn party_command_fixture_drive_then( &self, intent_id: u64, claim_token: u64, @@ -60,8 +56,8 @@ pub trait playerbots_fixture_command_drive { ) -> __sdk::Result<()>; } -impl playerbots_fixture_command_drive for super::RemoteReducers { - fn playerbots_fixture_command_drive_then( +impl party_command_fixture_drive for super::RemoteReducers { + fn party_command_fixture_drive_then( &self, intent_id: u64, claim_token: u64, @@ -71,7 +67,7 @@ impl playerbots_fixture_command_drive for super::RemoteReducers { + 'static, ) -> __sdk::Result<()> { self.imp.invoke_reducer_with_callback( - PlayerbotsFixtureCommandDriveArgs { + PartyCommandFixtureDriveArgs { intent_id, claim_token, }, diff --git a/gateway/src/stdb/bindings/playerbots_fixture_command_expire_after_receipt_window_reducer.rs b/gateway/src/stdb/bindings/party_command_fixture_expire_after_receipt_window_reducer.rs similarity index 53% rename from gateway/src/stdb/bindings/playerbots_fixture_command_expire_after_receipt_window_reducer.rs rename to gateway/src/stdb/bindings/party_command_fixture_expire_after_receipt_window_reducer.rs index 03928491a..e0f07f96e 100644 --- a/gateway/src/stdb/bindings/playerbots_fixture_command_expire_after_receipt_window_reducer.rs +++ b/gateway/src/stdb/bindings/party_command_fixture_expire_after_receipt_window_reducer.rs @@ -6,47 +6,47 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] -pub(super) struct PlayerbotsFixtureCommandExpireAfterReceiptWindowArgs { +pub(super) struct PartyCommandFixtureExpireAfterReceiptWindowArgs { pub intent_id: u64, } -impl From for super::Reducer { - fn from(args: PlayerbotsFixtureCommandExpireAfterReceiptWindowArgs) -> Self { - Self::PlayerbotsFixtureCommandExpireAfterReceiptWindow { +impl From for super::Reducer { + fn from(args: PartyCommandFixtureExpireAfterReceiptWindowArgs) -> Self { + Self::PartyCommandFixtureExpireAfterReceiptWindow { intent_id: args.intent_id, } } } -impl __sdk::InModule for PlayerbotsFixtureCommandExpireAfterReceiptWindowArgs { +impl __sdk::InModule for PartyCommandFixtureExpireAfterReceiptWindowArgs { type Module = super::RemoteModule; } #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `playerbots_fixture_command_expire_after_receipt_window`. +/// Extension trait for access to the reducer `party_command_fixture_expire_after_receipt_window`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait playerbots_fixture_command_expire_after_receipt_window { - /// Request that the remote module invoke the reducer `playerbots_fixture_command_expire_after_receipt_window` to run as soon as possible. +pub trait party_command_fixture_expire_after_receipt_window { + /// Request that the remote module invoke the reducer `party_command_fixture_expire_after_receipt_window` to run as soon as possible. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and this method provides no way to listen for its completion status. - /// /// Use [`playerbots_fixture_command_expire_after_receipt_window:playerbots_fixture_command_expire_after_receipt_window_then`] to run a callback after the reducer completes. - fn playerbots_fixture_command_expire_after_receipt_window( + /// /// Use [`party_command_fixture_expire_after_receipt_window:party_command_fixture_expire_after_receipt_window_then`] to run a callback after the reducer completes. + fn party_command_fixture_expire_after_receipt_window( &self, intent_id: u64, ) -> __sdk::Result<()> { - self.playerbots_fixture_command_expire_after_receipt_window_then(intent_id, |_, _| {}) + self.party_command_fixture_expire_after_receipt_window_then(intent_id, |_, _| {}) } - /// Request that the remote module invoke the reducer `playerbots_fixture_command_expire_after_receipt_window` to run as soon as possible, + /// Request that the remote module invoke the reducer `party_command_fixture_expire_after_receipt_window` to run as soon as possible, /// registering `callback` to run when we are notified that the reducer completed. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed with the `callback`. - fn playerbots_fixture_command_expire_after_receipt_window_then( + fn party_command_fixture_expire_after_receipt_window_then( &self, intent_id: u64, @@ -56,8 +56,8 @@ pub trait playerbots_fixture_command_expire_after_receipt_window { ) -> __sdk::Result<()>; } -impl playerbots_fixture_command_expire_after_receipt_window for super::RemoteReducers { - fn playerbots_fixture_command_expire_after_receipt_window_then( +impl party_command_fixture_expire_after_receipt_window for super::RemoteReducers { + fn party_command_fixture_expire_after_receipt_window_then( &self, intent_id: u64, @@ -66,7 +66,7 @@ impl playerbots_fixture_command_expire_after_receipt_window for super::RemoteRed + 'static, ) -> __sdk::Result<()> { self.imp.invoke_reducer_with_callback( - PlayerbotsFixtureCommandExpireAfterReceiptWindowArgs { intent_id }, + PartyCommandFixtureExpireAfterReceiptWindowArgs { intent_id }, callback, ) } diff --git a/gateway/src/stdb/bindings/playerbots_fixture_command_expire_reducer.rs b/gateway/src/stdb/bindings/party_command_fixture_expire_reducer.rs similarity index 55% rename from gateway/src/stdb/bindings/playerbots_fixture_command_expire_reducer.rs rename to gateway/src/stdb/bindings/party_command_fixture_expire_reducer.rs index 40975d8d3..ff1cf7e27 100644 --- a/gateway/src/stdb/bindings/playerbots_fixture_command_expire_reducer.rs +++ b/gateway/src/stdb/bindings/party_command_fixture_expire_reducer.rs @@ -6,44 +6,44 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] -pub(super) struct PlayerbotsFixtureCommandExpireArgs { +pub(super) struct PartyCommandFixtureExpireArgs { pub intent_id: u64, } -impl From for super::Reducer { - fn from(args: PlayerbotsFixtureCommandExpireArgs) -> Self { - Self::PlayerbotsFixtureCommandExpire { +impl From for super::Reducer { + fn from(args: PartyCommandFixtureExpireArgs) -> Self { + Self::PartyCommandFixtureExpire { intent_id: args.intent_id, } } } -impl __sdk::InModule for PlayerbotsFixtureCommandExpireArgs { +impl __sdk::InModule for PartyCommandFixtureExpireArgs { type Module = super::RemoteModule; } #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `playerbots_fixture_command_expire`. +/// Extension trait for access to the reducer `party_command_fixture_expire`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait playerbots_fixture_command_expire { - /// Request that the remote module invoke the reducer `playerbots_fixture_command_expire` to run as soon as possible. +pub trait party_command_fixture_expire { + /// Request that the remote module invoke the reducer `party_command_fixture_expire` to run as soon as possible. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and this method provides no way to listen for its completion status. - /// /// Use [`playerbots_fixture_command_expire:playerbots_fixture_command_expire_then`] to run a callback after the reducer completes. - fn playerbots_fixture_command_expire(&self, intent_id: u64) -> __sdk::Result<()> { - self.playerbots_fixture_command_expire_then(intent_id, |_, _| {}) + /// /// Use [`party_command_fixture_expire:party_command_fixture_expire_then`] to run a callback after the reducer completes. + fn party_command_fixture_expire(&self, intent_id: u64) -> __sdk::Result<()> { + self.party_command_fixture_expire_then(intent_id, |_, _| {}) } - /// Request that the remote module invoke the reducer `playerbots_fixture_command_expire` to run as soon as possible, + /// Request that the remote module invoke the reducer `party_command_fixture_expire` to run as soon as possible, /// registering `callback` to run when we are notified that the reducer completed. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed with the `callback`. - fn playerbots_fixture_command_expire_then( + fn party_command_fixture_expire_then( &self, intent_id: u64, @@ -53,8 +53,8 @@ pub trait playerbots_fixture_command_expire { ) -> __sdk::Result<()>; } -impl playerbots_fixture_command_expire for super::RemoteReducers { - fn playerbots_fixture_command_expire_then( +impl party_command_fixture_expire for super::RemoteReducers { + fn party_command_fixture_expire_then( &self, intent_id: u64, @@ -62,9 +62,7 @@ impl playerbots_fixture_command_expire for super::RemoteReducers { + Send + 'static, ) -> __sdk::Result<()> { - self.imp.invoke_reducer_with_callback( - PlayerbotsFixtureCommandExpireArgs { intent_id }, - callback, - ) + self.imp + .invoke_reducer_with_callback(PartyCommandFixtureExpireArgs { intent_id }, callback) } } diff --git a/gateway/src/stdb/bindings/playerbots_fixture_command_finish_reducer.rs b/gateway/src/stdb/bindings/party_command_fixture_finish_reducer.rs similarity index 59% rename from gateway/src/stdb/bindings/playerbots_fixture_command_finish_reducer.rs rename to gateway/src/stdb/bindings/party_command_fixture_finish_reducer.rs index 1a1bb395c..0fb5ff36f 100644 --- a/gateway/src/stdb/bindings/playerbots_fixture_command_finish_reducer.rs +++ b/gateway/src/stdb/bindings/party_command_fixture_finish_reducer.rs @@ -6,50 +6,46 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] -pub(super) struct PlayerbotsFixtureCommandFinishArgs { +pub(super) struct PartyCommandFixtureFinishArgs { pub intent_id: u64, pub claim_token: u64, } -impl From for super::Reducer { - fn from(args: PlayerbotsFixtureCommandFinishArgs) -> Self { - Self::PlayerbotsFixtureCommandFinish { +impl From for super::Reducer { + fn from(args: PartyCommandFixtureFinishArgs) -> Self { + Self::PartyCommandFixtureFinish { intent_id: args.intent_id, claim_token: args.claim_token, } } } -impl __sdk::InModule for PlayerbotsFixtureCommandFinishArgs { +impl __sdk::InModule for PartyCommandFixtureFinishArgs { type Module = super::RemoteModule; } #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `playerbots_fixture_command_finish`. +/// Extension trait for access to the reducer `party_command_fixture_finish`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait playerbots_fixture_command_finish { - /// Request that the remote module invoke the reducer `playerbots_fixture_command_finish` to run as soon as possible. +pub trait party_command_fixture_finish { + /// Request that the remote module invoke the reducer `party_command_fixture_finish` to run as soon as possible. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and this method provides no way to listen for its completion status. - /// /// Use [`playerbots_fixture_command_finish:playerbots_fixture_command_finish_then`] to run a callback after the reducer completes. - fn playerbots_fixture_command_finish( - &self, - intent_id: u64, - claim_token: u64, - ) -> __sdk::Result<()> { - self.playerbots_fixture_command_finish_then(intent_id, claim_token, |_, _| {}) + /// /// Use [`party_command_fixture_finish:party_command_fixture_finish_then`] to run a callback after the reducer completes. + fn party_command_fixture_finish(&self, intent_id: u64, claim_token: u64) -> __sdk::Result<()> { + self.party_command_fixture_finish_then(intent_id, claim_token, |_, _| {}) } - /// Request that the remote module invoke the reducer `playerbots_fixture_command_finish` to run as soon as possible, + /// Request that the remote module invoke the reducer `party_command_fixture_finish` to run as soon as possible, /// registering `callback` to run when we are notified that the reducer completed. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed with the `callback`. - fn playerbots_fixture_command_finish_then( + fn party_command_fixture_finish_then( &self, intent_id: u64, claim_token: u64, @@ -60,8 +56,8 @@ pub trait playerbots_fixture_command_finish { ) -> __sdk::Result<()>; } -impl playerbots_fixture_command_finish for super::RemoteReducers { - fn playerbots_fixture_command_finish_then( +impl party_command_fixture_finish for super::RemoteReducers { + fn party_command_fixture_finish_then( &self, intent_id: u64, claim_token: u64, @@ -71,7 +67,7 @@ impl playerbots_fixture_command_finish for super::RemoteReducers { + 'static, ) -> __sdk::Result<()> { self.imp.invoke_reducer_with_callback( - PlayerbotsFixtureCommandFinishArgs { + PartyCommandFixtureFinishArgs { intent_id, claim_token, }, diff --git a/gateway/src/stdb/bindings/playerbots_fixture_command_release_receipt_reducer.rs b/gateway/src/stdb/bindings/party_command_fixture_release_receipt_reducer.rs similarity index 55% rename from gateway/src/stdb/bindings/playerbots_fixture_command_release_receipt_reducer.rs rename to gateway/src/stdb/bindings/party_command_fixture_release_receipt_reducer.rs index 48b51d08f..3ca907b6c 100644 --- a/gateway/src/stdb/bindings/playerbots_fixture_command_release_receipt_reducer.rs +++ b/gateway/src/stdb/bindings/party_command_fixture_release_receipt_reducer.rs @@ -6,44 +6,44 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] -pub(super) struct PlayerbotsFixtureCommandReleaseReceiptArgs { +pub(super) struct PartyCommandFixtureReleaseReceiptArgs { pub bot_guid: u64, } -impl From for super::Reducer { - fn from(args: PlayerbotsFixtureCommandReleaseReceiptArgs) -> Self { - Self::PlayerbotsFixtureCommandReleaseReceipt { +impl From for super::Reducer { + fn from(args: PartyCommandFixtureReleaseReceiptArgs) -> Self { + Self::PartyCommandFixtureReleaseReceipt { bot_guid: args.bot_guid, } } } -impl __sdk::InModule for PlayerbotsFixtureCommandReleaseReceiptArgs { +impl __sdk::InModule for PartyCommandFixtureReleaseReceiptArgs { type Module = super::RemoteModule; } #[allow(non_camel_case_types)] -/// Extension trait for access to the reducer `playerbots_fixture_command_release_receipt`. +/// Extension trait for access to the reducer `party_command_fixture_release_receipt`. /// /// Implemented for [`super::RemoteReducers`]. -pub trait playerbots_fixture_command_release_receipt { - /// Request that the remote module invoke the reducer `playerbots_fixture_command_release_receipt` to run as soon as possible. +pub trait party_command_fixture_release_receipt { + /// Request that the remote module invoke the reducer `party_command_fixture_release_receipt` to run as soon as possible. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and this method provides no way to listen for its completion status. - /// /// Use [`playerbots_fixture_command_release_receipt:playerbots_fixture_command_release_receipt_then`] to run a callback after the reducer completes. - fn playerbots_fixture_command_release_receipt(&self, bot_guid: u64) -> __sdk::Result<()> { - self.playerbots_fixture_command_release_receipt_then(bot_guid, |_, _| {}) + /// /// Use [`party_command_fixture_release_receipt:party_command_fixture_release_receipt_then`] to run a callback after the reducer completes. + fn party_command_fixture_release_receipt(&self, bot_guid: u64) -> __sdk::Result<()> { + self.party_command_fixture_release_receipt_then(bot_guid, |_, _| {}) } - /// Request that the remote module invoke the reducer `playerbots_fixture_command_release_receipt` to run as soon as possible, + /// Request that the remote module invoke the reducer `party_command_fixture_release_receipt` to run as soon as possible, /// registering `callback` to run when we are notified that the reducer completed. /// /// This method returns immediately, and errors only if we are unable to send the request. /// The reducer will run asynchronously in the future, /// and its status can be observed with the `callback`. - fn playerbots_fixture_command_release_receipt_then( + fn party_command_fixture_release_receipt_then( &self, bot_guid: u64, @@ -53,8 +53,8 @@ pub trait playerbots_fixture_command_release_receipt { ) -> __sdk::Result<()>; } -impl playerbots_fixture_command_release_receipt for super::RemoteReducers { - fn playerbots_fixture_command_release_receipt_then( +impl party_command_fixture_release_receipt for super::RemoteReducers { + fn party_command_fixture_release_receipt_then( &self, bot_guid: u64, @@ -63,7 +63,7 @@ impl playerbots_fixture_command_release_receipt for super::RemoteReducers { + 'static, ) -> __sdk::Result<()> { self.imp.invoke_reducer_with_callback( - PlayerbotsFixtureCommandReleaseReceiptArgs { bot_guid }, + PartyCommandFixtureReleaseReceiptArgs { bot_guid }, callback, ) } diff --git a/gateway/src/stdb/subscriptions.rs b/gateway/src/stdb/subscriptions.rs index 30972e43d..315a73969 100644 --- a/gateway/src/stdb/subscriptions.rs +++ b/gateway/src/stdb/subscriptions.rs @@ -4156,14 +4156,14 @@ impl Coordinator { ) { Ok(crate::world::party::PartyOutcome::Ran) => {} outcome => log::debug!( - "playerbots: group intent {intent_id} op {op} ({inviter_guid} -> \ + "group intent {intent_id} op {op} ({inviter_guid} -> \ {target_guid}) did not execute: {outcome:?}" ), } }); if let Err(error) = spawned { log::error!( - "playerbots: could not start consumer for group intent {intent_id} op {op} \ + "could not start consumer for group intent {intent_id} op {op} \ ({inviter_guid} -> {target_guid}): {error}" ); } diff --git a/gateway/src/world/framing_tests.rs b/gateway/src/world/framing_tests.rs index 3420eb63b..c32c0bda8 100644 --- a/gateway/src/world/framing_tests.rs +++ b/gateway/src/world/framing_tests.rs @@ -426,8 +426,8 @@ fn an_authenticated_stc_order_uses_the_logged_in_actor_and_keeps_the_session_liv let (mut client, mut c_enc, mut c_dec, server) = enter_world(store.clone(), 1); for text in [ - "STC\tv1|playerbots.order|same|1/1|follow|77\0", - "STC\tv1||playerbots.order||changed||1/1||follow||77\0", + "STC\tv1|example.order|same|1/1|follow|77\0", + "STC\tv1||example.order||changed||1/1||follow||77\0", ] { let mut body = Vec::new(); body.extend_from_slice(&1u32.to_le_bytes()); @@ -453,8 +453,8 @@ fn an_authenticated_stc_order_uses_the_logged_in_actor_and_keeps_the_session_liv assert_eq!( *store.client_commands.lock().unwrap(), vec![ - (42, 1, "playerbots.order".into(), "follow|77".into()), - (42, 1, "playerbots.order".into(), "follow|77".into()), + (42, 1, "example.order".into(), "follow|77".into()), + (42, 1, "example.order".into(), "follow|77".into()), ] ); drop(client); diff --git a/module/build.rs b/module/build.rs index 78145a908..decca0458 100644 --- a/module/build.rs +++ b/module/build.rs @@ -572,8 +572,8 @@ fn main() { } out.push_str("];\n"); match registries.client_commands.first() { - Some((parse, apply)) => out.push_str(&format!( - "pub const GAME_CLIENT_COMMAND: Option = Some(crate::bridge::ClientCommandHandler {{ parse: {parse}, apply: {apply} }});\n" + Some((parse, apply, reply)) => out.push_str(&format!( + "pub const GAME_CLIENT_COMMAND: Option = Some(crate::bridge::ClientCommandHandler {{ parse: {parse}, apply: {apply}, reply: {reply} }});\n" )), None => out.push_str( "pub const GAME_CLIENT_COMMAND: Option = None;\n", @@ -642,7 +642,7 @@ struct Registries { tick_passes: Vec, hooks: Vec<(String, String)>, // (event, fully-qualified fn path) encounter_packages: Vec<(String, String)>, // (binding variant, fully-qualified fn path) - client_commands: Vec<(String, String)>, // (parser path, admitted apply path) + client_commands: Vec<(String, String, String)>, // (parser, admitted apply, reply name) paths } /// The table accessor a transport arm's fully-qualified fn path names: the same @@ -1042,26 +1042,19 @@ fn try_match_hook(head: &str) -> Option<(String, String)> { Some((event, name)) } -fn try_match_client_command(head: &str) -> Option<(String, String)> { - let rest = head.strip_prefix('(')?.trim_start(); - let parse_end = rest.find(|c: char| !(c.is_alphanumeric() || c == '_'))?; - if parse_end == 0 { - return None; - } - let parse = rest[..parse_end].to_string(); - let rest = rest[parse_end..] - .trim_start() - .strip_prefix(',')? - .trim_start(); - let apply_end = rest.find(|c: char| !(c.is_alphanumeric() || c == '_'))?; - if apply_end == 0 { - return None; - } - let apply = rest[..apply_end].to_string(); - rest[apply_end..] - .trim_start() - .starts_with(')') - .then_some((parse, apply)) +/// `game_client_command!` head: `(PARSE, APPLY, REPLY)` — package files only. +fn try_match_client_command(head: &str) -> Option<(String, String, String)> { + let mut rest = head.strip_prefix('(')?; + let mut ident_before = |separator: char| { + let trimmed = rest.trim_start(); + let end = trimmed.find(|c: char| !(c.is_alphanumeric() || c == '_'))?; + if end == 0 { + return None; + } + rest = trimmed[end..].trim_start().strip_prefix(separator)?; + Some(trimmed[..end].to_string()) + }; + Some((ident_before(',')?, ident_before(',')?, ident_before(')')?)) } /// `encounter_package!` head: `(BINDING, fn NAME(...` — package files only. @@ -1202,7 +1195,7 @@ fn scan_file(file: &Path, scan_root: &Path, in_package: bool, prefix: &str, reg: scan_marker(&content, file, "game_client_command!", |head, line| { match try_match_client_command(head) { - Some((parse, apply)) => { + Some((parse, apply, reply)) => { if !in_package { panic!( "build.rs: `game_client_command!` in {}:{line} is core code; command meaning belongs to a Package", @@ -1211,11 +1204,15 @@ fn scan_file(file: &Path, scan_root: &Path, in_package: bool, prefix: &str, reg: } check_facade_reexport(file, scan_root, in_package, &parse); check_facade_reexport(file, scan_root, in_package, &apply); - reg.client_commands - .push((format!("{prefix}::{parse}"), format!("{prefix}::{apply}"))); + check_facade_reexport(file, scan_root, in_package, &reply); + reg.client_commands.push(( + format!("{prefix}::{parse}"), + format!("{prefix}::{apply}"), + format!("{prefix}::{reply}"), + )); } None => panic!( - "build.rs: malformed `game_client_command!` marker in {}:{line} — expected `game_client_command!(PARSE, APPLY)`", + "build.rs: malformed `game_client_command!` marker in {}:{line} — expected `game_client_command!(PARSE, APPLY, REPLY)`", file.display() ), } @@ -1854,16 +1851,29 @@ mod package_api_lint_tests { } #[test] - fn client_command_marker_names_one_parser_and_apply_operation() { + fn client_command_marker_names_one_parser_apply_operation_and_reply() { + assert_eq!( + try_match_client_command("(parse_order, apply_order, ORDER_RESULT);"), + Some(( + "parse_order".to_string(), + "apply_order".to_string(), + "ORDER_RESULT".to_string() + )) + ); assert_eq!( try_match_client_command("(parse_order, apply_order);"), - Some(("parse_order".to_string(), "apply_order".to_string())) + None + ); + assert_eq!( + try_match_client_command("(, apply_order, ORDER_RESULT);"), + None + ); + assert_eq!( + try_match_client_command("(parse_order, apply_order, );"), + None ); - assert_eq!(try_match_client_command("(parse_order);"), None); - assert_eq!(try_match_client_command("(, apply_order);"), None); - assert_eq!(try_match_client_command("(parse_order, );"), None); assert_eq!( - try_match_client_command("(parse_order, apply_order, extra);"), + try_match_client_command("(parse_order, apply_order, ORDER_RESULT, extra);"), None ); } diff --git a/module/src/actor.rs b/module/src/actor.rs index 0d5c678fa..f1145e579 100644 --- a/module/src/actor.rs +++ b/module/src/actor.rs @@ -152,7 +152,7 @@ package_only! { } #[cfg(all(has_packages, feature = "debug_reducers"))] -pub(crate) use crate::bridge::playerbots_fixture_command_drive as fixture_command_drive; +pub(crate) use crate::bridge::party_command_fixture_drive as fixture_command_drive; debug_only! { pub(crate) use crate::quest::grant_quest_unchecked as stage_quest; } // ---- loot / inventory / vendor ---- diff --git a/module/src/bridge.rs b/module/src/bridge.rs index d88e300ee..570da52a5 100644 --- a/module/src/bridge.rs +++ b/module/src/bridge.rs @@ -9,9 +9,9 @@ //! connection — the 279 delivery law: addon UI state must survive fat transactions) as an //! addon-language whisper the client surfaces to addons as `CHAT_MSG_ADDON`. //! -//! Core owns `ping`; one installed Package may register a parser and admitted apply operation with -//! `game_client_command!`. Parsing queues only a pending intent. Gateway certifies Realm-core party -//! authority before the target World Shard applies gameplay. +//! Core owns `ping`; one installed Package may register a parser, an admitted apply operation and a +//! reply command name with `game_client_command!`. Parsing queues only a pending intent. Gateway +//! certifies Realm-core party authority before the target World Shard applies gameplay. use lyracore_shared::group::COMMAND_RESULT_WINDOW_MICROS; use spacetimedb::{reducer, table, Identity, ReducerContext, Table, Timestamp}; @@ -94,6 +94,8 @@ pub struct AdmittedClientCommand { pub struct ClientCommandHandler { pub parse: fn(&str, &str) -> Option>, pub apply: fn(&ReducerContext, &AdmittedClientCommand) -> CommandOutcome, + /// The addon command name that carries each outcome back to the issuer. + pub reply: &'static str, } #[derive(spacetimedb::SpacetimeType, Clone, Debug, PartialEq, Eq)] @@ -261,8 +263,11 @@ fn dispatch(ctx: &ReducerContext, character_guid: u64, cmd: &str, payload: &str) // The 184 acceptance round-trip: `STC ping` → `STC pong` (payload echoed). "ping" => send(ctx, character_guid, "pong", payload), other => { - match crate::GAME_CLIENT_COMMAND.and_then(|handler| (handler.parse)(other, payload)) { - Some(Ok(command)) => { + let parsed = crate::GAME_CLIENT_COMMAND.and_then(|handler| { + (handler.parse)(other, payload).map(|parsed| (handler, parsed)) + }); + match parsed { + Some((_, Ok(command))) => { let now = ctx.timestamp.to_micros_since_unix_epoch(); let Some(reply_identity) = crate::helpers::character_by_guid(ctx, character_guid) @@ -309,12 +314,9 @@ fn dispatch(ctx: &ReducerContext, character_guid: u64, cmd: &str, payload: &str) }); enqueue_party_command_intent(ctx, &inserted); } - Some(Err(outcome)) => send( - ctx, - character_guid, - "playerbots.order.result", - outcome.tag(), - ), + Some((handler, Err(outcome))) => { + send(ctx, character_guid, handler.reply, outcome.tag()) + } None => { spacetimedb::log::info!( "bridge: unknown client command {other:?} from {character_guid} (dropped)" @@ -500,12 +502,15 @@ pub fn finish_party_command_intent( let reply_identity = intent.reply_identity; retire_party_command_intent(ctx, &intent)?; table.id().update(intent); - send_to_identity( - ctx, - reply_identity, - "playerbots.order.result", - &format!("{response_id}|{}", outcome.tag()), - ); + // An intent outlives an uninstalled Package; no addon remains to read its reply. + if let Some(handler) = crate::GAME_CLIENT_COMMAND { + send_to_identity( + ctx, + reply_identity, + handler.reply, + &format!("{response_id}|{}", outcome.tag()), + ); + } Ok(()) } @@ -653,7 +658,7 @@ fn fixture_command_intent( /// before source finalization so durable tests can model a Gateway loss at that boundary. #[cfg(feature = "debug_reducers")] #[reducer] -pub fn playerbots_fixture_command_apply( +pub fn party_command_fixture_apply( ctx: &ReducerContext, intent_id: u64, claim_token: u64, @@ -666,7 +671,7 @@ pub fn playerbots_fixture_command_apply( /// transaction. Mode 1 removes the live body; mode 2 suppresses Sessionless Action Consent. #[cfg(feature = "debug_reducers")] #[reducer] -pub fn playerbots_fixture_command_apply_after_gate_change( +pub fn party_command_fixture_apply_after_gate_change( ctx: &ReducerContext, intent_id: u64, claim_token: u64, @@ -750,7 +755,7 @@ fn fixture_command_apply_after_authority( /// Finish a private fixture command from the exact target receipt without applying it again. #[cfg(feature = "debug_reducers")] #[reducer] -pub fn playerbots_fixture_command_finish( +pub fn party_command_fixture_finish( ctx: &ReducerContext, intent_id: u64, claim_token: u64, @@ -770,13 +775,13 @@ pub fn playerbots_fixture_command_finish( /// Apply and finish one private unsharded fixture command through the production phase operations. #[cfg(feature = "debug_reducers")] #[reducer] -pub fn playerbots_fixture_command_drive( +pub fn party_command_fixture_drive( ctx: &ReducerContext, intent_id: u64, claim_token: u64, ) -> Result<(), String> { crate::helpers::require_operator(ctx)?; - playerbots_fixture_command_apply(ctx, intent_id, claim_token)?; + party_command_fixture_apply(ctx, intent_id, claim_token)?; if ctx .db .game_party_command_receipt() @@ -785,7 +790,7 @@ pub fn playerbots_fixture_command_drive( .next() .is_some() { - playerbots_fixture_command_finish(ctx, intent_id, claim_token)?; + party_command_fixture_finish(ctx, intent_id, claim_token)?; } Ok(()) } @@ -793,7 +798,7 @@ pub fn playerbots_fixture_command_drive( /// Release the oldest receipt owned by one private command fixture to exercise capacity recovery. #[cfg(feature = "debug_reducers")] #[reducer] -pub fn playerbots_fixture_command_release_receipt( +pub fn party_command_fixture_release_receipt( ctx: &ReducerContext, bot_guid: u64, ) -> Result<(), String> { @@ -812,10 +817,7 @@ pub fn playerbots_fixture_command_release_receipt( /// Expire one still-pending private fixture command without changing its target receipt. #[cfg(feature = "debug_reducers")] #[reducer] -pub fn playerbots_fixture_command_expire( - ctx: &ReducerContext, - intent_id: u64, -) -> Result<(), String> { +pub fn party_command_fixture_expire(ctx: &ReducerContext, intent_id: u64) -> Result<(), String> { crate::helpers::require_operator(ctx)?; let table = ctx.db.game_party_command_intent(); let mut intent = fixture_command_intent(ctx, intent_id)?; @@ -830,7 +832,7 @@ pub fn playerbots_fixture_command_expire( /// Move one pending fixture intent beyond the target receipt-retention guarantee. #[cfg(feature = "debug_reducers")] #[reducer] -pub fn playerbots_fixture_command_expire_after_receipt_window( +pub fn party_command_fixture_expire_after_receipt_window( ctx: &ReducerContext, intent_id: u64, ) -> Result<(), String> { diff --git a/module/src/lib.rs b/module/src/lib.rs index 5e0cc961e..1dbd66d32 100644 --- a/module/src/lib.rs +++ b/module/src/lib.rs @@ -239,10 +239,11 @@ macro_rules! game_hook { } /// Installs the one Package-owned parser and admitted apply operation for addon client commands. +/// `REPLY` names a `&'static str` const: the addon command that carries each outcome to the issuer. /// Core authenticates the issuer and Gateway certifies realm-wide party authority before apply. #[macro_export] macro_rules! game_client_command { - ($parse:ident, $apply:ident) => {}; + ($parse:ident, $apply:ident, $reply:ident) => {}; } /// Installs one package as the sole authority for a map-scoped encounter binding. `build.rs`