|
|
|
|
@@ -135,6 +135,11 @@ pub async fn serve(addr: &str, state: AppState) -> anyhow::Result<()> {
|
|
|
|
|
// so nothing runs twice, fills the placeholders and decides who is online; this process
|
|
|
|
|
// moves the line and knows nothing of what any command does (no allowlist, D384).
|
|
|
|
|
.route("/commands/run", post(commands_run))
|
|
|
|
|
// Protocol 14 (§20.12): one RaidableBases base for a run, and a spot's checks. The plugin
|
|
|
|
|
// keeps the key and the run's base in its world registry, so `world.revert` takes it back
|
|
|
|
|
// like a zone; nothing is kept here.
|
|
|
|
|
.route("/raid/spawn", post(raid_spawn))
|
|
|
|
|
.route("/raid/check", post(raid_check))
|
|
|
|
|
// Protocol 10 (§29): who took part, what they may redeem, and a line in chat. The tally
|
|
|
|
|
// is counted and held by the plugin, the kit catalogue is Kits' own, and whether a chat
|
|
|
|
|
// line was already said is the plugin's memory. These move lines, like everything above.
|
|
|
|
|
@@ -597,6 +602,19 @@ async fn commands_run(State(st): State<AppState>, Json(body): Json<Value>) -> Re
|
|
|
|
|
forward_object(&st, body, "command.run", "a console command run").await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Spawn one RaidableBases base for a run's step (protocol 14). `raid.queued` (its id, when the
|
|
|
|
|
/// raids helper made it the run's, and `repeat` for a key already seen) or `raid.error` with a
|
|
|
|
|
/// reason. The plugin's world registry holds the run's base; nothing is remembered here.
|
|
|
|
|
async fn raid_spawn(State(st): State<AppState>, Json(body): Json<Value>) -> Response {
|
|
|
|
|
forward_object(&st, body, "raid.spawn", "a raid base spawn").await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Check a spot for a raid base without spawning one (protocol 14): `raid.checked`, with the
|
|
|
|
|
/// refusal's reason and the warnings, or `raid.error` when the spot cannot be checked at all.
|
|
|
|
|
async fn raid_check(State(st): State<AppState>, Json(body): Json<Value>) -> Response {
|
|
|
|
|
forward_object(&st, body, "raid.check", "a raid base spot check").await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Start counting who takes part in a run. `tally.ok` or `tally.error` with a reason.
|
|
|
|
|
async fn tally_open(State(st): State<AppState>, Json(body): Json<Value>) -> Response {
|
|
|
|
|
forward_object(&st, body, "tally.open", "a tally").await
|
|
|
|
|
@@ -1397,6 +1415,33 @@ mod tests {
|
|
|
|
|
assert_eq!(teardown["teardownOf"], "12:6");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Protocol 14, RaidableBases: a spawn is stamped `raid.spawn` and a check `raid.check`
|
|
|
|
|
/// whatever their bodies name, so each route does its one thing; the plugin's own names for
|
|
|
|
|
/// difficulties, profiles and bases (D386), the spot and the settings pass through untouched.
|
|
|
|
|
#[test]
|
|
|
|
|
fn protocol_14_raid_spawn_and_check_are_stamped() {
|
|
|
|
|
let body = json!({ "cmd": "world.revert", "reqId": "theirs", "key": "12:7", "runId": "12",
|
|
|
|
|
"difficulty": "Wobbly", "profile": "Wobbly Bases", "base": "wobbly1",
|
|
|
|
|
"x": 650.0, "z": 2037.0, "heightAdjust": 5.0,
|
|
|
|
|
"pvp": false, "npcs": true, "npcCount": 0, "despawnMinutes": 90, "lock": true });
|
|
|
|
|
let spawn = stamp(body.clone(), "raid.spawn", "r-68").expect("an object is stamped");
|
|
|
|
|
|
|
|
|
|
assert_eq!(spawn["cmd"], "raid.spawn");
|
|
|
|
|
assert_eq!(spawn["reqId"], "r-68");
|
|
|
|
|
assert_eq!(spawn["key"], "12:7");
|
|
|
|
|
assert_eq!(spawn["difficulty"], "Wobbly");
|
|
|
|
|
assert_eq!(spawn["base"], "wobbly1");
|
|
|
|
|
assert_eq!(spawn["heightAdjust"], 5.0);
|
|
|
|
|
assert_eq!(spawn["npcCount"], 0);
|
|
|
|
|
assert_eq!(spawn["pvp"], false);
|
|
|
|
|
assert!(stamp(json!("Wobbly"), "raid.spawn", "r-69").is_none());
|
|
|
|
|
|
|
|
|
|
let check = stamp(body, "raid.check", "r-70").expect("an object is stamped");
|
|
|
|
|
assert_eq!(check["cmd"], "raid.check");
|
|
|
|
|
assert_eq!(check["x"], 650.0);
|
|
|
|
|
assert_eq!(check["profile"], "Wobbly Bases");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Protocol 12: a title set is forwarded whole. The markup inside each `text` is the module's
|
|
|
|
|
/// and the plugin's business, so it must arrive byte for byte as the website composed it.
|
|
|
|
|
#[test]
|
|
|
|
|
|