From dcc2cb34f56a134a48c9add3709f3a9ec2c11c4b Mon Sep 17 00:00:00 2001 From: Matthew Date: Sat, 25 Jul 2026 09:36:05 -0700 Subject: [PATCH 1/4] Refresh Rust starter kit to current engine protocol The Rust kit (flagged not-up-to-date in the README) had drifted from the current engine wire protocol. Because it uses typed serde structs, the drift caused hard failures rather than the silent no-ops seen in the untyped Go kit. Protocol fixes: - Add the `info` ServerPacketType variant. The engine broadcasts `info` packets while waiting for players; without this variant serde fails to parse them and the agent panics on connect (start() propagates the error via `?`). - Rename the bomb-owner field `owner_unit_id` -> `unit_id` (entity.rs, game_state.rs). The stale name never populated, so get_bomb_for_unit always returned None and the agent could never detonate. - Fix create_detonate_bomb_action to send type "detonate" (was "bomb", which would place a bomb instead of detonating). - Add `stunned` to Unit and `agent_id` to Entity, both present in the current schema (freeze mechanic), and copy them in update_state. Tests (the kit had none): - Add src/tests.rs with serde-conformance tests (info parses, stunned/unit_id/ agent_id deserialize, detonate serializes correctly) and a schema-validation test that checks the fixtures against the engine's canonical ServerPacket schema via a jsonschema dev-dependency. The schema path is taken from BOMBERLAND_SCHEMA_PATH (CI points it at the engine schema) and defaults to a bundled copy for local runs and standalone clones. Tooling: - Bundle the engine's canonical validation.schema.json. - Modernize the Dockerfile base images (rust:1.57-slim-buster -> rust:1-slim- bookworm, debian:buster-slim -> bookworm-slim) so the toolchain can resolve the updated dependency graph; the release build still compiles only the bin target, so the jsonschema dev-dependency is not built into the image. --- agents/rust/Cargo.lock | 1637 +++++++++++++++++++++++++--- agents/rust/Cargo.toml | 5 + agents/rust/Dockerfile | 4 +- agents/rust/src/entity.rs | 11 +- agents/rust/src/game_connection.rs | 2 + agents/rust/src/game_state.rs | 2 +- agents/rust/src/main.rs | 3 + agents/rust/src/packets.rs | 4 + agents/rust/src/tests.rs | 160 +++ agents/rust/src/unit.rs | 5 +- agents/rust/validation.schema.json | 948 ++++++++++++++++ 11 files changed, 2640 insertions(+), 141 deletions(-) create mode 100644 agents/rust/src/tests.rs create mode 100644 agents/rust/validation.schema.json diff --git a/agents/rust/Cargo.lock b/agents/rust/Cargo.lock index e093626e..fbe4238b 100644 --- a/agents/rust/Cargo.lock +++ b/agents/rust/Cargo.lock @@ -2,18 +2,124 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.4", + "once_cell", + "serde", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + [[package]] name = "anyhow" version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + [[package]] name = "base64" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" + [[package]] name = "block-buffer" version = "0.9.0" @@ -28,6 +134,7 @@ name = "bomberland_starter_kit" version = "0.1.0" dependencies = [ "anyhow", + "jsonschema", "rand", "serde", "serde_json", @@ -35,6 +142,18 @@ dependencies = [ "url", ] +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytecount" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" + [[package]] name = "byteorder" version = "1.4.3" @@ -53,6 +172,52 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "4.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + [[package]] name = "cpufeatures" version = "0.2.1" @@ -62,6 +227,12 @@ dependencies = [ "libc", ] +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" + [[package]] name = "digest" version = "0.9.0" @@ -71,6 +242,28 @@ dependencies = [ "generic-array", ] +[[package]] +name = "displaydoc" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "fancy-regex" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2" +dependencies = [ + "bit-set", + "regex-automata", + "regex-syntax", +] + [[package]] name = "fnv" version = "1.0.7" @@ -79,14 +272,72 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ - "matches", "percent-encoding", ] +[[package]] +name = "fraction" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076045bb43dac435333ed5f04caf35c7463631d0dae2deb2638d94dd0a5b872" +dependencies = [ + "lazy_static", + "num", +] + +[[package]] +name = "futures-channel" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" + +[[package]] +name = "futures-io" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" + +[[package]] +name = "futures-sink" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307" + +[[package]] +name = "futures-task" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" + +[[package]] +name = "futures-util" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + [[package]] name = "generic-array" version = "0.14.4" @@ -102,12 +353,32 @@ name = "getrandom" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "wasi", + "r-efi", + "wasip2", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "http" version = "0.2.5" @@ -120,191 +391,821 @@ dependencies = [ ] [[package]] -name = "httparse" -version = "1.5.1" +name = "http" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +dependencies = [ + "bytes", + "itoa 1.0.1", +] [[package]] -name = "idna" -version = "0.2.3" +name = "http-body" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", + "bytes", + "http 1.4.2", ] [[package]] -name = "itoa" -version = "0.4.8" +name = "http-body-util" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" +dependencies = [ + "bytes", + "futures-core", + "http 1.4.2", + "http-body", + "pin-project-lite", +] [[package]] -name = "itoa" -version = "1.0.1" +name = "httparse" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] -name = "libc" -version = "0.2.112" +name = "hyper" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.4.2", + "http-body", + "httparse", + "itoa 1.0.1", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] [[package]] -name = "log" -version = "0.4.14" +name = "hyper-util" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ - "cfg-if", + "bytes", + "futures-channel", + "futures-util", + "http 1.4.2", + "http-body", + "hyper", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] -name = "matches" -version = "0.1.9" +name = "icu_collections" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] [[package]] -name = "opaque-debug" -version = "0.3.0" +name = "icu_locale_core" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] [[package]] -name = "percent-encoding" -version = "2.1.0" +name = "icu_normalizer" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] [[package]] -name = "ppv-lite86" -version = "0.2.15" +name = "icu_normalizer_data" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] -name = "proc-macro2" -version = "1.0.34" +name = "icu_properties" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ - "unicode-xid", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", ] [[package]] -name = "quote" -version = "1.0.10" +name = "icu_properties_data" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" -dependencies = [ - "proc-macro2", -] +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] -name = "rand" -version = "0.8.4" +name = "icu_provider" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "idna" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ - "ppv-lite86", - "rand_core", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "rand_core" -version = "0.6.3" +name = "idna_adapter" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ - "getrandom", + "icu_normalizer", + "icu_properties", ] [[package]] -name = "rand_hc" -version = "0.3.1" +name = "ipnet" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] -name = "ryu" -version = "1.0.9" +name = "is_terminal_polyfill" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] -name = "serde" -version = "1.0.132" +name = "iso8601" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +checksum = "74a0559b45528cf0732d911524974977a5749f477d7dd99652830ffdaf53c4d1" dependencies = [ - "serde_derive", + "nom", ] [[package]] -name = "serde_derive" -version = "1.0.132" +name = "itoa" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] -name = "serde_json" -version = "1.0.73" +name = "itoa" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" -dependencies = [ - "itoa 1.0.1", - "ryu", - "serde", -] +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] -name = "sha-1" -version = "0.9.8" +name = "js-sys" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ - "block-buffer", "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", + "futures-util", + "wasm-bindgen", ] [[package]] -name = "syn" -version = "1.0.83" +name = "jsonschema" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1dfb999630e338648c83e91c59a4e9fb7620f520c3194b6b89e276f2f1959" +checksum = "fa0f4bea31643be4c6a678e9aa4ae44f0db9e5609d5ca9dc9083d06eb3e9a27a" dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] + "ahash", + "anyhow", + "base64 0.22.1", + "bytecount", + "clap", + "fancy-regex", + "fraction", + "getrandom 0.2.3", + "iso8601", + "itoa 1.0.1", + "memchr", + "num-cmp", + "once_cell", + "parking_lot", + "percent-encoding", + "regex", + "reqwest", + "serde", + "serde_json", + "time", + "url", + "uuid", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mio" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.61.2", +] + +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-cmp" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63335b2e2c34fae2fb0aa2cecfd9f0832a1e24b3b32ecec612c3426d46dc8aaa" + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "potential_utf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "reqwest" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.4.2", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "serde_json" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" +dependencies = [ + "itoa 1.0.1", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa 1.0.1", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23a1dfb999630e338648c83e91c59a4e9fb7620f520c3194b6b89e276f2f1959" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] [[package]] name = "thiserror" @@ -323,23 +1224,116 @@ checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.83", ] [[package]] -name = "tinyvec" -version = "1.5.1" +name = "time" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "3e1d5e639ff6bab73cb6885cc7e7b1de96c3f32c68ec55f3952614bec1092244" dependencies = [ - "tinyvec_macros", + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", ] [[package]] -name = "tinyvec_macros" -version = "0.1.0" +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" +dependencies = [ + "libc", + "mio", + "pin-project-lite", + "socket2 0.6.5", + "windows-sys 0.61.2", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" @@ -347,10 +1341,10 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ad3713a14ae247f22a728a0456a545df14acf3867f905adff84be99e23b3ad1" dependencies = [ - "base64", + "base64 0.13.0", "byteorder", "bytes", - "http", + "http 0.2.5", "httparse", "log", "rand", @@ -367,19 +1361,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] -name = "unicode-bidi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" +name = "unicode-ident" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-xid" @@ -389,14 +1374,14 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "url" -version = "2.2.2" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", + "serde", ] [[package]] @@ -405,14 +1390,398 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.4+wasi-0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.119", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] diff --git a/agents/rust/Cargo.toml b/agents/rust/Cargo.toml index 7d85c9ff..b44b9be1 100644 --- a/agents/rust/Cargo.toml +++ b/agents/rust/Cargo.toml @@ -10,3 +10,8 @@ anyhow = "1.0.51" tungstenite = "0.16.0" url = "2.2.2" rand = "0.8.4" + +[dev-dependencies] +# Test-only: validates the kit's protocol fixtures against the engine's canonical JSON schema. +# Not compiled into the release binary (the Dockerfile builds the bin target only). +jsonschema = "0.18" diff --git a/agents/rust/Dockerfile b/agents/rust/Dockerfile index f83970b9..25b584dd 100644 --- a/agents/rust/Dockerfile +++ b/agents/rust/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.57-slim-buster as build +FROM rust:1-slim-bookworm AS build RUN USER=root cargo new --bin bomberland_starter_kit WORKDIR /bomberland_starter_kit @@ -12,6 +12,6 @@ COPY ./src ./src RUN rm ./target/release/deps/bomberland_starter_kit* RUN cargo build --release -FROM debian:buster-slim +FROM debian:bookworm-slim COPY --from=build /bomberland_starter_kit/target/release/bomberland_starter_kit . CMD ["./bomberland_starter_kit"] diff --git a/agents/rust/src/entity.rs b/agents/rust/src/entity.rs index 7ce56904..af1b470c 100644 --- a/agents/rust/src/entity.rs +++ b/agents/rust/src/entity.rs @@ -1,3 +1,4 @@ +use crate::agent::AgentID; use crate::unit::UnitID; use serde::{Deserialize, Serialize}; @@ -33,9 +34,12 @@ pub struct Entity { pub y: u8, /// the type of entity pub r#type: EntityType, - /// ID of the unit that owns this entity + /// ID of the unit that owns this entity (e.g. the unit that placed a bomb) #[serde(skip_serializing_if = "Option::is_none")] - pub owner_unit_id: Option, + pub unit_id: Option, + /// ID of the agent that owns this entity + #[serde(skip_serializing_if = "Option::is_none")] + pub agent_id: Option, /// Tick on which this entity will perish from the map. /// E.g. a bomb placed with expires=74 will explode on tick 74. #[serde(skip_serializing_if = "Option::is_none")] @@ -54,7 +58,8 @@ impl Entity { self.x = new_state.x; self.y = new_state.y; self.r#type = new_state.r#type.clone(); - self.owner_unit_id = new_state.owner_unit_id.clone(); + self.unit_id = new_state.unit_id.clone(); + self.agent_id = new_state.agent_id.clone(); self.expires = new_state.expires; self.hp = new_state.hp; self.blast_diameter = new_state.blast_diameter; diff --git a/agents/rust/src/game_connection.rs b/agents/rust/src/game_connection.rs index 4d91b2b8..f92a5bdb 100644 --- a/agents/rust/src/game_connection.rs +++ b/agents/rust/src/game_connection.rs @@ -154,6 +154,8 @@ impl GameConnection { } return true; } + // Informational packet sent while waiting for players; nothing to do. + ServerPacketType::Info => {} } false } diff --git a/agents/rust/src/game_state.rs b/agents/rust/src/game_state.rs index 0b44dd4d..cb1e7eec 100644 --- a/agents/rust/src/game_state.rs +++ b/agents/rust/src/game_state.rs @@ -65,7 +65,7 @@ impl GameState { pub fn get_bomb_for_unit(&self, unit_id: &UnitID) -> Option<&Entity> { for entity in self.entities.iter() { - if entity.r#type == EntityType::Bomb && entity.owner_unit_id == Some(unit_id.clone()) { + if entity.r#type == EntityType::Bomb && entity.unit_id == Some(unit_id.clone()) { return Some(&entity); } } diff --git a/agents/rust/src/main.rs b/agents/rust/src/main.rs index 4bc51785..714d209a 100644 --- a/agents/rust/src/main.rs +++ b/agents/rust/src/main.rs @@ -77,6 +77,9 @@ pub mod game_state; pub mod packets; pub mod unit; +#[cfg(test)] +mod tests; + fn main() -> () { let conn_string = env::var("GAME_CONNECTION_STRING").unwrap_or("ws://127.0.0.1:3000/?role=agent&agentId=agentA&name=RustAgent".to_owned()); let mut conn = game_connection::GameConnection::new( diff --git a/agents/rust/src/packets.rs b/agents/rust/src/packets.rs index a98924ee..f5235057 100644 --- a/agents/rust/src/packets.rs +++ b/agents/rust/src/packets.rs @@ -19,6 +19,10 @@ pub enum ServerPacketType { Tick, #[serde(rename = "endgame_state")] EndGameState, + /// Sent while the engine waits for players to connect. Carries a human-readable + /// message; agents can safely ignore it (but must not fail to parse it). + #[serde(rename = "info")] + Info, } #[derive(Serialize, Deserialize, Debug)] diff --git a/agents/rust/src/tests.rs b/agents/rust/src/tests.rs new file mode 100644 index 00000000..e6d001e5 --- /dev/null +++ b/agents/rust/src/tests.rs @@ -0,0 +1,160 @@ +//! Protocol-conformance tests for the Rust starter kit. +//! +//! These deserialize representative engine packets into the kit's typed structs to guard +//! against wire-protocol drift — the shapes here mirror the engine's canonical JSON schema +//! (engine/bomberland-engine/src/runtime-validation/validation.schema.json). If the engine +//! renames or adds a field, the corresponding assertion here should fail. + +use crate::agent::AgentID; +use crate::entity::EntityType; +use crate::packets::{ServerPacket, ServerPacketPayload, ServerPacketType}; +use crate::unit::UnitID; +use std::{env, fs}; + +/// An `info` packet, broadcast by the engine while waiting for players to connect. +const INFO_PACKET: &str = r#"{"type": "info", "payload": {"message": "Waiting for agents to connect"}}"#; + +/// A `tick` packet exercising the event shapes: entity spawn, unit-state update, unit action. +const TICK_PACKET: &str = r#" +{ + "type": "tick", + "payload": { + "tick": 23, + "events": [ + {"type": "entity_spawned", "data": {"created": 23, "x": 7, "y": 3, "type": "a", "expires": 63, "hp": 1}}, + {"type": "unit_state", "data": {"coordinates": [1, 1], "hp": 2, "inventory": {"bombs": 2}, "blast_diameter": 3, "unit_id": "c", "agent_id": "a", "invulnerable": 0, "stunned": 0}}, + {"type": "unit", "agent_id": "a", "data": {"type": "move", "move": "right", "unit_id": "c"}} + ] + } +} +"#; + +/// A game_state payload matching the current engine contract: units carry `stunned` and +/// `invulnerable`, a bomb entity is owned via `unit_id`/`agent_id`. +const GAME_STATE_PACKET: &str = r#" +{ + "type": "game_state", + "payload": { + "game_id": "test", + "tick": 5, + "agents": { + "a": {"agent_id": "a", "unit_ids": ["c"]}, + "b": {"agent_id": "b", "unit_ids": ["d"]} + }, + "unit_state": { + "c": {"coordinates": [1, 1], "hp": 3, "inventory": {"bombs": 2}, "blast_diameter": 3, "unit_id": "c", "agent_id": "a", "invulnerable": 0, "stunned": 0}, + "d": {"coordinates": [3, 3], "hp": 3, "inventory": {"bombs": 3}, "blast_diameter": 3, "unit_id": "d", "agent_id": "b", "invulnerable": 0, "stunned": 7} + }, + "entities": [ + {"created": 4, "x": 1, "y": 1, "type": "b", "unit_id": "c", "agent_id": "a", "expires": 40, "blast_diameter": 3}, + {"created": 4, "x": 7, "y": 7, "type": "fp", "expires": 50, "hp": 1} + ], + "world": {"width": 15, "height": 15}, + "config": {"tick_rate_hz": 10, "game_duration_ticks": 300, "fire_spawn_interval_ticks": 5}, + "connection": {"id": 1, "role": "agent", "agent_id": "a"} + } +} +"#; + +fn parse_game_state(json: &str) -> crate::game_state::GameState { + let packet: ServerPacket = serde_json::from_str(json).expect("game_state packet should parse"); + assert!(matches!(packet.r#type, ServerPacketType::GameState)); + match packet.payload { + ServerPacketPayload::GameState(state) => state, + other => panic!("expected GameState payload, got {:?}", other), + } +} + +#[test] +fn info_packet_parses_without_error() { + // Regression: the engine broadcasts `info` packets while waiting for players. If the + // ServerPacketType enum lacks this variant, the agent panics on connect. + let packet: ServerPacket = serde_json::from_str(INFO_PACKET).expect("info packet should parse"); + assert!(matches!(packet.r#type, ServerPacketType::Info)); +} + +#[test] +fn tick_packet_parses_without_error() { + let packet: ServerPacket = serde_json::from_str(TICK_PACKET).expect("tick packet should parse"); + assert!(matches!(packet.r#type, ServerPacketType::Tick)); +} + +/// Compiles a validator pinned to the engine's `ServerPacket` union. The schema path comes from +/// BOMBERLAND_SCHEMA_PATH (CI points it at the engine's canonical schema) and defaults to the +/// bundled copy for local runs and standalone clones. +fn compile_server_packet_schema() -> jsonschema::JSONSchema { + let path = env::var("BOMBERLAND_SCHEMA_PATH").unwrap_or_else(|_| "validation.schema.json".to_string()); + let text = fs::read_to_string(&path).unwrap_or_else(|e| panic!("could not read schema at {}: {}", path, e)); + let doc: serde_json::Value = serde_json::from_str(&text).expect("schema should be valid JSON"); + // The document root only holds `definitions` (no constraints), so pin validation to the + // ServerPacket union while keeping the sibling definitions resolvable for internal $refs. + let root = serde_json::json!({ + "$ref": "#/definitions/ServerPacket", + "definitions": doc["definitions"].clone(), + }); + jsonschema::JSONSchema::compile(&root).expect("engine schema should compile") +} + +#[test] +fn fixtures_conform_to_engine_server_packet_schema() { + let schema = compile_server_packet_schema(); + for (name, fixture) in [ + ("game_state", GAME_STATE_PACKET), + ("info", INFO_PACKET), + ("tick", TICK_PACKET), + ] { + let instance: serde_json::Value = + serde_json::from_str(fixture).unwrap_or_else(|e| panic!("fixture `{}` invalid JSON: {}", name, e)); + // Collect errors into owned strings so nothing borrows `instance` past this statement. + let validation: Result<(), Vec> = schema + .validate(&instance) + .map_err(|errors| errors.map(|e| format!(" - {} (at {})", e, e.instance_path)).collect()); + if let Err(details) = validation { + panic!( + "fixture `{}` does not conform to the engine ServerPacket schema:\n{}", + name, + details.join("\n") + ); + } + } +} + +#[test] +fn unit_state_includes_stunned() { + let state = parse_game_state(GAME_STATE_PACKET); + let unit_d = state + .unit_state + .get(&UnitID::D) + .expect("unit d should exist"); + assert_eq!(unit_d.stunned, 7, "stunned must be deserialized from the wire"); + assert_eq!(unit_d.invulnerable, 0); +} + +#[test] +fn bomb_is_owned_via_unit_id() { + // Regression: the engine renamed the bomb owner field from `owner_unit_id` to `unit_id`. + // get_bomb_for_unit must find unit c's bomb; if the field is stale it returns None. + let state = parse_game_state(GAME_STATE_PACKET); + let bomb = state + .get_bomb_for_unit(&UnitID::C) + .expect("unit c's bomb should be found via unit_id"); + assert_eq!(bomb.r#type, EntityType::Bomb); + assert_eq!([bomb.x, bomb.y], [1, 1]); + assert_eq!(bomb.agent_id, Some(AgentID::A)); +} + +#[test] +fn detonate_action_serializes_as_detonate() { + // Regression: create_detonate_bomb_action previously sent type "bomb" instead of "detonate". + let state = parse_game_state(GAME_STATE_PACKET); + let unit_c = state.unit_state.get(&UnitID::C).unwrap(); + let bomb = state.get_bomb_for_unit(&UnitID::C).unwrap(); + let action = unit_c.create_detonate_bomb_action(bomb); + let json = serde_json::to_string(&action).expect("action should serialize"); + assert!( + json.contains("\"type\":\"detonate\""), + "detonate action must use type \"detonate\", got: {}", + json + ); + assert!(json.contains("\"coordinates\":[1,1]")); +} diff --git a/agents/rust/src/unit.rs b/agents/rust/src/unit.rs index 7820fb7b..5d44a4d6 100644 --- a/agents/rust/src/unit.rs +++ b/agents/rust/src/unit.rs @@ -78,6 +78,8 @@ pub struct Unit { pub agent_id: AgentID, /// Latest tick number after which this unit is no longer invulnerable (inclusive). pub invulnerable: u16, + /// Latest tick number until which this unit is stunned/frozen (inclusive). + pub stunned: u16, } impl Unit { @@ -121,7 +123,7 @@ impl Unit { } ActionPacket { - r#type: ActionPacketType::Bomb, + r#type: ActionPacketType::Detonate, unit_id: Some(self.unit_id.clone()), coordinates: Some([entity.x, entity.y]), r#move: None, @@ -145,6 +147,7 @@ impl Unit { self.blast_diameter = new_state.blast_diameter; self.agent_id = new_state.agent_id; self.invulnerable = new_state.invulnerable; + self.stunned = new_state.stunned; } else { panic!( "Attempted to update unit '{:?}' with data from unit '{:?}'", diff --git a/agents/rust/validation.schema.json b/agents/rust/validation.schema.json new file mode 100644 index 00000000..7cc0aa25 --- /dev/null +++ b/agents/rust/validation.schema.json @@ -0,0 +1,948 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "IHashMapObject": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "ValidAdminPacket": { + "$ref": "#/definitions/AdminPacket" + }, + "AdminPacket": { + "anyOf": [ + { + "$ref": "#/definitions/EvaluateNextStatePacket" + }, + { + "$ref": "#/definitions/RequestTickPacket" + }, + { + "$ref": "#/definitions/RequestGameReset" + } + ] + }, + "EvaluateNextStatePacket": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "evaluate_next_state" + }, + "sequence_id": { + "type": "number" + }, + "state": { + "type": "object", + "properties": { + "game_id": { + "type": "string" + }, + "tick": { + "type": "number" + }, + "agents": { + "$ref": "#/definitions/IAgentHashMap" + }, + "unit_state": { + "$ref": "#/definitions/IUnitStateHashMap" + }, + "entities": { + "type": "array", + "items": { + "$ref": "#/definitions/IEntity" + } + }, + "world": { + "type": "object", + "properties": { + "width": { + "type": "number" + }, + "height": { + "type": "number" + } + }, + "required": [ + "width", + "height" + ], + "additionalProperties": false + }, + "config": { + "type": "object", + "properties": { + "game_duration_ticks": { + "type": "number" + }, + "tick_rate_hz": { + "type": "number" + }, + "fire_spawn_interval_ticks": { + "type": "number" + } + }, + "required": [ + "game_duration_ticks", + "tick_rate_hz", + "fire_spawn_interval_ticks" + ], + "additionalProperties": false + } + }, + "required": [ + "game_id", + "tick", + "agents", + "unit_state", + "entities", + "world", + "config" + ], + "additionalProperties": false + }, + "actions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + }, + "action": { + "$ref": "#/definitions/AgentPacket" + } + }, + "required": [ + "agent_id", + "action" + ], + "additionalProperties": false + } + } + }, + "required": [ + "type", + "sequence_id", + "state", + "actions" + ], + "additionalProperties": false + }, + "IAgentHashMap": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/IAgentState" + } + }, + "IAgentState": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + }, + "unit_ids": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "agent_id", + "unit_ids" + ], + "additionalProperties": false + }, + "IUnitStateHashMap": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/IUnitState" + } + }, + "IUnitState": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + }, + "unit_id": { + "type": "string" + }, + "coordinates": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + }, + "inventory": { + "type": "object", + "properties": { + "bombs": { + "type": "number" + } + }, + "required": [ + "bombs" + ], + "additionalProperties": false + }, + "blast_diameter": { + "type": "number" + }, + "hp": { + "type": "number" + }, + "invulnerable": { + "type": "number" + }, + "stunned": { + "type": "number" + } + }, + "required": [ + "agent_id", + "unit_id", + "coordinates", + "inventory", + "blast_diameter", + "hp", + "invulnerable", + "stunned" + ], + "additionalProperties": false + }, + "IEntity": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/EntityType" + }, + "hp": { + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + }, + "unit_id": { + "type": "string" + }, + "agent_id": { + "type": "string" + }, + "created": { + "type": "number" + }, + "expires": { + "type": "number" + }, + "blast_diameter": { + "type": "number" + } + }, + "required": [ + "type", + "x", + "y", + "created" + ], + "additionalProperties": false + }, + "EntityType": { + "type": "string", + "enum": [ + "a", + "b", + "x", + "bp", + "fp", + "m", + "o", + "t", + "w" + ] + }, + "AgentPacket": { + "anyOf": [ + { + "$ref": "#/definitions/AgentDetonatePacket" + }, + { + "$ref": "#/definitions/AgentMovePacket" + }, + { + "$ref": "#/definitions/AgentBombPacket" + } + ] + }, + "AgentDetonatePacket": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "detonate" + }, + "coordinates": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + }, + "unit_id": { + "type": "string" + } + }, + "required": [ + "type", + "coordinates", + "unit_id" + ], + "additionalProperties": false + }, + "AgentMovePacket": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "move" + }, + "move": { + "$ref": "#/definitions/UnitMove" + }, + "unit_id": { + "type": "string" + } + }, + "required": [ + "type", + "move", + "unit_id" + ], + "additionalProperties": false + }, + "UnitMove": { + "type": "string", + "enum": [ + "up", + "down", + "left", + "right" + ] + }, + "AgentBombPacket": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "bomb" + }, + "unit_id": { + "type": "string" + } + }, + "required": [ + "type", + "unit_id" + ], + "additionalProperties": false + }, + "RequestTickPacket": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "request_tick" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + "RequestGameReset": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "request_game_reset" + }, + "world_seed": { + "type": "number" + }, + "prng_seed": { + "type": "number" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + "ValidAgentPacket": { + "$ref": "#/definitions/AgentPacket" + }, + "ValidServerPacket": { + "$ref": "#/definitions/ServerPacket" + }, + "ServerPacket": { + "anyOf": [ + { + "$ref": "#/definitions/GameStatePacket" + }, + { + "$ref": "#/definitions/GameTickPacket" + }, + { + "$ref": "#/definitions/EndGameStatePacket" + }, + { + "$ref": "#/definitions/InfoPacket" + }, + { + "$ref": "#/definitions/NextGameStatePacket" + } + ] + }, + "GameStatePacket": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "game_state" + }, + "payload": { + "$ref": "#/definitions/IGameState" + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + }, + "IGameState": { + "type": "object", + "properties": { + "game_id": { + "type": "string" + }, + "tick": { + "type": "number" + }, + "agents": { + "$ref": "#/definitions/IAgentHashMap" + }, + "unit_state": { + "$ref": "#/definitions/IUnitStateHashMap" + }, + "entities": { + "type": "array", + "items": { + "$ref": "#/definitions/IEntity" + } + }, + "world": { + "type": "object", + "properties": { + "width": { + "type": "number" + }, + "height": { + "type": "number" + } + }, + "required": [ + "width", + "height" + ], + "additionalProperties": false + }, + "config": { + "type": "object", + "properties": { + "game_duration_ticks": { + "type": "number" + }, + "tick_rate_hz": { + "type": "number" + }, + "fire_spawn_interval_ticks": { + "type": "number" + } + }, + "required": [ + "game_duration_ticks", + "tick_rate_hz", + "fire_spawn_interval_ticks" + ], + "additionalProperties": false + }, + "connection": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "role": { + "$ref": "#/definitions/GameRole" + }, + "agent_id": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "id", + "role", + "agent_id" + ], + "additionalProperties": false + } + }, + "required": [ + "game_id", + "tick", + "agents", + "unit_state", + "entities", + "world", + "config", + "connection" + ], + "additionalProperties": false + }, + "GameRole": { + "type": "string", + "enum": [ + "admin", + "agent", + "spectator" + ] + }, + "GameTickPacket": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "tick" + }, + "payload": { + "$ref": "#/definitions/IGameTick" + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + }, + "IGameTick": { + "type": "object", + "properties": { + "events": { + "type": "array", + "items": { + "$ref": "#/definitions/GameEvent" + } + }, + "tick": { + "type": "number" + } + }, + "required": [ + "events", + "tick" + ], + "additionalProperties": false + }, + "GameEvent": { + "anyOf": [ + { + "$ref": "#/definitions/IAgentActionEvent" + }, + { + "$ref": "#/definitions/IEntitySpawnedEvent" + }, + { + "$ref": "#/definitions/IEntityExpiredEvent" + }, + { + "$ref": "#/definitions/IAgentStateEvent" + }, + { + "$ref": "#/definitions/IEntityStateEvent" + } + ] + }, + "IAgentActionEvent": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "unit" + }, + "agent_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/AgentPacket" + } + }, + "required": [ + "type", + "agent_id", + "data" + ], + "additionalProperties": false + }, + "IEntitySpawnedEvent": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "entity_spawned" + }, + "data": { + "$ref": "#/definitions/IEntity" + } + }, + "required": [ + "type", + "data" + ], + "additionalProperties": false + }, + "IEntityExpiredEvent": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "entity_expired" + }, + "data": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + } + }, + "required": [ + "type", + "data" + ], + "additionalProperties": false + }, + "IAgentStateEvent": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "unit_state" + }, + "data": { + "$ref": "#/definitions/IUnitState" + } + }, + "required": [ + "type", + "data" + ], + "additionalProperties": false + }, + "IEntityStateEvent": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "entity_state" + }, + "coordinates": { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 2, + "maxItems": 2 + }, + "updated_entity": { + "$ref": "#/definitions/IEntity" + } + }, + "required": [ + "type", + "coordinates", + "updated_entity" + ], + "additionalProperties": false + }, + "EndGameStatePacket": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "endgame_state" + }, + "payload": { + "$ref": "#/definitions/IEndGameState" + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + }, + "IEndGameState": { + "type": "object", + "properties": { + "initial_state": { + "type": "object", + "properties": { + "game_id": { + "type": "string" + }, + "tick": { + "type": "number" + }, + "agents": { + "$ref": "#/definitions/IAgentHashMap" + }, + "unit_state": { + "$ref": "#/definitions/IUnitStateHashMap" + }, + "entities": { + "type": "array", + "items": { + "$ref": "#/definitions/IEntity" + } + }, + "world": { + "type": "object", + "properties": { + "width": { + "type": "number" + }, + "height": { + "type": "number" + } + }, + "required": [ + "width", + "height" + ], + "additionalProperties": false + }, + "config": { + "type": "object", + "properties": { + "game_duration_ticks": { + "type": "number" + }, + "tick_rate_hz": { + "type": "number" + }, + "fire_spawn_interval_ticks": { + "type": "number" + } + }, + "required": [ + "game_duration_ticks", + "tick_rate_hz", + "fire_spawn_interval_ticks" + ], + "additionalProperties": false + } + }, + "required": [ + "game_id", + "tick", + "agents", + "unit_state", + "entities", + "world", + "config" + ], + "additionalProperties": false + }, + "history": { + "type": "array", + "items": { + "$ref": "#/definitions/IGameTick" + } + }, + "winning_agent_id": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "initial_state", + "history", + "winning_agent_id" + ], + "additionalProperties": false + }, + "InfoPacket": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "info" + }, + "payload": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "additionalProperties": false + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + }, + "NextGameStatePacket": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "next_game_state" + }, + "payload": { + "type": "object", + "properties": { + "sequence_id": { + "type": "number" + }, + "is_complete": { + "type": "boolean" + }, + "tick_result": { + "$ref": "#/definitions/IGameTick" + }, + "next_state": { + "type": "object", + "properties": { + "game_id": { + "type": "string" + }, + "tick": { + "type": "number" + }, + "agents": { + "$ref": "#/definitions/IAgentHashMap" + }, + "unit_state": { + "$ref": "#/definitions/IUnitStateHashMap" + }, + "entities": { + "type": "array", + "items": { + "$ref": "#/definitions/IEntity" + } + }, + "world": { + "type": "object", + "properties": { + "width": { + "type": "number" + }, + "height": { + "type": "number" + } + }, + "required": [ + "width", + "height" + ], + "additionalProperties": false + }, + "config": { + "type": "object", + "properties": { + "game_duration_ticks": { + "type": "number" + }, + "tick_rate_hz": { + "type": "number" + }, + "fire_spawn_interval_ticks": { + "type": "number" + } + }, + "required": [ + "game_duration_ticks", + "tick_rate_hz", + "fire_spawn_interval_ticks" + ], + "additionalProperties": false + } + }, + "required": [ + "game_id", + "tick", + "agents", + "unit_state", + "entities", + "world", + "config" + ], + "additionalProperties": false + } + }, + "required": [ + "sequence_id", + "is_complete", + "tick_result", + "next_state" + ], + "additionalProperties": false + } + }, + "required": [ + "type", + "payload" + ], + "additionalProperties": false + }, + "IPostTelemetryBody": { + "type": "object", + "properties": { + "_initId": { + "type": "string" + }, + "event": { + "type": "string" + }, + "data": {} + }, + "required": [ + "_initId", + "event", + "data" + ], + "additionalProperties": false + } + } +} \ No newline at end of file From 2922db0eebca41920e3b9f6cd2afcd8fc1410bf9 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sat, 25 Jul 2026 10:01:42 -0700 Subject: [PATCH 2/4] Add CI for Rust starter kit, validated against the engine schema Mirrors the Go kit's CI. The engine's JSON schema is the source of truth: the workflow validates the Rust fixtures against the engine's canonical schema and re-runs whenever that schema changes. - Triggers on changes to agents/rust/**, the engine schema, and the workflow. - Fails if the kit's bundled schema copy has drifted from the engine's. - Runs `cargo test --locked` with BOMBERLAND_SCHEMA_PATH pointed at the engine schema. GitHub-hosted runners only. --- .github/workflows/test-rust-agent.yaml | 72 ++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 .github/workflows/test-rust-agent.yaml diff --git a/.github/workflows/test-rust-agent.yaml b/.github/workflows/test-rust-agent.yaml new file mode 100644 index 00000000..a51a8a07 --- /dev/null +++ b/.github/workflows/test-rust-agent.yaml @@ -0,0 +1,72 @@ +name: Test Rust Starter Kit + +# Runs on GitHub-hosted runners (ubuntu-latest). +# +# The engine's JSON schema is the source of truth for the wire protocol. This +# workflow validates the Rust starter kit's fixtures against that schema, and is +# triggered whenever the schema changes — so a protocol update to the engine +# surfaces any drift in the Rust kit immediately. + +on: + push: + branches: + - master + pull_request: + branches: + - master + paths: + - "agents/rust/**" + - "engine/bomberland-engine/src/runtime-validation/validation.schema.json" + - ".github/workflows/test-rust-agent.yaml" + workflow_dispatch: + +concurrency: + group: test-rust-agent-${{ github.ref }} + cancel-in-progress: true + +env: + ENGINE_SCHEMA: engine/bomberland-engine/src/runtime-validation/validation.schema.json + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install stable Rust + run: | + rustup toolchain install stable --profile minimal --no-self-update + rustup default stable + rustc --version + + - name: Cache cargo + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + agents/rust/target + key: cargo-${{ runner.os }}-${{ hashFiles('agents/rust/Cargo.lock') }} + restore-keys: cargo-${{ runner.os }}- + + # The engine schema is the source of truth. Fail if the kit's bundled copy has + # drifted from it — that copy is what the Docker build and standalone clones use, + # since they don't have the engine tree available. + - name: Check bundled schema is in sync with engine + run: | + if ! cmp -s "$ENGINE_SCHEMA" agents/rust/validation.schema.json; then + echo "::error::agents/rust/validation.schema.json is out of sync with $ENGINE_SCHEMA" + echo "Re-sync with: cp $ENGINE_SCHEMA agents/rust/validation.schema.json" + diff -u agents/rust/validation.schema.json "$ENGINE_SCHEMA" || true + exit 1 + fi + + # Validate fixtures against the engine's live schema (not just the bundled copy), + # so fixture/protocol drift fails CI even before the copy is re-synced. + - name: Run Rust tests against engine schema + working-directory: agents/rust + env: + BOMBERLAND_SCHEMA_PATH: ${{ github.workspace }}/engine/bomberland-engine/src/runtime-validation/validation.schema.json + run: cargo test --locked From 8bc1008652300b2a6e40f90d038ad37d8b2b8b43 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sat, 25 Jul 2026 10:01:42 -0700 Subject: [PATCH 3/4] docs: mark Rust starter kit as up-to-date The Rust kit now matches the current engine wire protocol and is validated against the engine's canonical JSON schema in CI (test-rust-agent.yaml). --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8d9623b6..5b3d0a6f 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ docker-compose up --abort-on-container-exit --force-recreate | TypeScript-fwd | [Link](https://github.com/CoderOneHQ/bomberland/tree/master/agents/typescript) | Includes example for using forward model simulator | ❌ | Coder One | | Go | [Link](https://github.com/CoderOneHQ/bomberland/tree/master/agents/go) | Basic Go starter | ✅ | [dtitov](https://github.com/dtitov) | | C++ | [Link](https://github.com/CoderOneHQ/bomberland/tree/master/agents/cpp) | Basic C++ starter | ✅ | [jfbogusz](https://github.com/jfbogusz) | -| Rust | [Link](https://github.com/CoderOneHQ/bomberland/tree/master/agents/rust) | Basic Rust starter | ❌ | [K-JBoon](https://github.com/K-JBoon) | +| Rust | [Link](https://github.com/CoderOneHQ/bomberland/tree/master/agents/rust) | Basic Rust starter | ✅ | [K-JBoon](https://github.com/K-JBoon) | ## Discussion and Questions From c2e94d3c24fc5223756837334cc7c3cec973e303 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sat, 25 Jul 2026 10:02:47 -0700 Subject: [PATCH 4/4] ci: drop self-hosted-runner note from workflow comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Public repo — CI only ever runs on GitHub-hosted runners, so the note about never using self-hosted homeserver runners was misleading. Reworded both workflow header comments to just state the runner, keeping the engine workflow's PR-build/no-push note. --- .github/workflows/build-and-push-engine.yaml | 7 +++---- .github/workflows/test-go-agent.yaml | 4 +--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-and-push-engine.yaml b/.github/workflows/build-and-push-engine.yaml index e5031f9b..84b42ddb 100644 --- a/.github/workflows/build-and-push-engine.yaml +++ b/.github/workflows/build-and-push-engine.yaml @@ -1,9 +1,8 @@ name: Build and Push Bomberland Engine -# Public repo: this runs on GitHub-hosted runners (ubuntu-latest), never the -# self-hosted homeserver runners, so untrusted fork PRs can't execute on our -# infrastructure. Pull requests build only (no registry login, no push); the -# image is pushed to Docker Hub only on push to master. +# Runs on GitHub-hosted runners (ubuntu-latest). Pull requests build only +# (no registry login, no push); the image is pushed to Docker Hub only on +# push to master. on: # Every merge/commit to master builds and pushes the engine image. diff --git a/.github/workflows/test-go-agent.yaml b/.github/workflows/test-go-agent.yaml index 6d052e5f..edb96e95 100644 --- a/.github/workflows/test-go-agent.yaml +++ b/.github/workflows/test-go-agent.yaml @@ -1,8 +1,6 @@ name: Test Go Starter Kit -# Public repo: this runs on GitHub-hosted runners (ubuntu-latest), never the -# self-hosted homeserver runners, so untrusted fork PRs can't execute on our -# infrastructure. +# Runs on GitHub-hosted runners (ubuntu-latest). # # The engine's JSON schema is the source of truth for the wire protocol. This # workflow validates the Go starter kit's fixtures against that schema, and is