first commit
This commit is contained in:
commit
fbd750024a
570
Cargo.lock
generated
Normal file
570
Cargo.lock
generated
Normal file
@ -0,0 +1,570 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.104"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic-polyfill"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cobs"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "critical-section"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "custom-command"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"pumpkin-plugin-api",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"pumpkin-plugin-api",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hash32"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.17.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||||
|
dependencies = [
|
||||||
|
"foldhash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heapless"
|
||||||
|
version = "0.7.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-polyfill",
|
||||||
|
"hash32",
|
||||||
|
"rustc_version",
|
||||||
|
"serde",
|
||||||
|
"spin",
|
||||||
|
"stable_deref_trait",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hello-world"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"pumpkin-plugin-api",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "id-arena"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.14.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leb128fmt"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||||
|
|
||||||
|
[[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.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "postcard"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
|
||||||
|
dependencies = [
|
||||||
|
"cobs",
|
||||||
|
"embedded-io 0.4.0",
|
||||||
|
"embedded-io 0.6.1",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prettyplease"
|
||||||
|
version = "0.2.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "pumpkin-plugin-api"
|
||||||
|
version = "0.1.0-dev+26.2-26.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09559c59b3c594994856d81a4101b6b10be3843542b191bb1d0a4fff19058888"
|
||||||
|
dependencies = [
|
||||||
|
"postcard",
|
||||||
|
"serde_json",
|
||||||
|
"tracing",
|
||||||
|
"tracing-serde-structured",
|
||||||
|
"wit-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
|
||||||
|
|
||||||
|
[[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.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.151"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
"zmij",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spleef"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"pumpkin-plugin-api",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sumo"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"pumpkin-plugin-api",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tnt-run"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"pumpkin-plugin-api",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "tracing-serde-structured"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0832510e9838a4ff7e45e278602ab0533686f9507bc6189e024e488602f29820"
|
||||||
|
dependencies = [
|
||||||
|
"hash32",
|
||||||
|
"heapless",
|
||||||
|
"serde",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-encoder"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e974fe6821a8cf64575d51ea2194e2c8f77e7b66e9afe7419ce8a97f9ee0d251"
|
||||||
|
dependencies = [
|
||||||
|
"leb128fmt",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-metadata"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18a11585adb92fe9b55ad1d760e8d8fb5d87e0d2e303cb8eed57f078d54293a2"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"indexmap",
|
||||||
|
"wasm-encoder",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmparser"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9a61719f93a87b16d325921e251800c4833f8fab50fa21c7de73aed50086313"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"hashbrown",
|
||||||
|
"indexmap",
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e473fd0095479f9689ac7d2a52c427cc96bb2b973ace50238dfcc1ab1cd52d93"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen-rust-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-core"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87445680dfe6d6b5369e884bd63c03a3335268e855365b2fc3f7bcdce96a630e"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"heck",
|
||||||
|
"wit-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rust"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72f2fe494de0d898216caf0fd0ae76af75753fcb3ff4f465b46131537cf24cf8"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"heck",
|
||||||
|
"indexmap",
|
||||||
|
"prettyplease",
|
||||||
|
"syn 2.0.119",
|
||||||
|
"wasm-metadata",
|
||||||
|
"wit-bindgen-core",
|
||||||
|
"wit-component",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rust-macro"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59283a01aec94f60f92ada22ffe182a5cea8acfce43be3be688de8d52df55312"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
"wit-bindgen-core",
|
||||||
|
"wit-bindgen-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-component"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "481b5c47b2ecce0389b5e08a05557d6a190c9cd761773b8880a8017ee04dc7ef"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bitflags",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"wasm-encoder",
|
||||||
|
"wasm-metadata",
|
||||||
|
"wasmparser",
|
||||||
|
"wit-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-parser"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff4daaa3cd97ae49ecd0a99dc009d453f93e0f083dd3be38c0f24a83a93e37ac"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"hashbrown",
|
||||||
|
"id-arena",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"unicode-ident",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zmij"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
||||||
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[workspace]
|
||||||
|
resolver = "2"
|
||||||
|
members = [
|
||||||
|
"basics/*",
|
||||||
|
"minigames/*",
|
||||||
|
]
|
||||||
176
LICENSE-APACHE
Normal file
176
LICENSE-APACHE
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
21
LICENSE-MIT
Normal file
21
LICENSE-MIT
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Pumpkin Plugin Examples Contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
530
basics/01-hello-world/Cargo.lock
generated
Normal file
530
basics/01-hello-world/Cargo.lock
generated
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.104"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic-polyfill"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cobs"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "critical-section"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hash32"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.17.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||||
|
dependencies = [
|
||||||
|
"foldhash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heapless"
|
||||||
|
version = "0.7.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-polyfill",
|
||||||
|
"hash32",
|
||||||
|
"rustc_version",
|
||||||
|
"serde",
|
||||||
|
"spin",
|
||||||
|
"stable_deref_trait",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hello-world"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"pumpkin-plugin-api",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "id-arena"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.14.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leb128fmt"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||||
|
|
||||||
|
[[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.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "postcard"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
|
||||||
|
dependencies = [
|
||||||
|
"cobs",
|
||||||
|
"embedded-io 0.4.0",
|
||||||
|
"embedded-io 0.6.1",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prettyplease"
|
||||||
|
version = "0.2.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "pumpkin-plugin-api"
|
||||||
|
version = "0.1.0-dev+26.2-26.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09559c59b3c594994856d81a4101b6b10be3843542b191bb1d0a4fff19058888"
|
||||||
|
dependencies = [
|
||||||
|
"postcard",
|
||||||
|
"serde_json",
|
||||||
|
"tracing",
|
||||||
|
"tracing-serde-structured",
|
||||||
|
"wit-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
|
||||||
|
|
||||||
|
[[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.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.151"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
"zmij",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
|
[[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.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "tracing-serde-structured"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0832510e9838a4ff7e45e278602ab0533686f9507bc6189e024e488602f29820"
|
||||||
|
dependencies = [
|
||||||
|
"hash32",
|
||||||
|
"heapless",
|
||||||
|
"serde",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-encoder"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e974fe6821a8cf64575d51ea2194e2c8f77e7b66e9afe7419ce8a97f9ee0d251"
|
||||||
|
dependencies = [
|
||||||
|
"leb128fmt",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-metadata"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18a11585adb92fe9b55ad1d760e8d8fb5d87e0d2e303cb8eed57f078d54293a2"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"indexmap",
|
||||||
|
"wasm-encoder",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmparser"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9a61719f93a87b16d325921e251800c4833f8fab50fa21c7de73aed50086313"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"hashbrown",
|
||||||
|
"indexmap",
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e473fd0095479f9689ac7d2a52c427cc96bb2b973ace50238dfcc1ab1cd52d93"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen-rust-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-core"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87445680dfe6d6b5369e884bd63c03a3335268e855365b2fc3f7bcdce96a630e"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"heck",
|
||||||
|
"wit-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rust"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72f2fe494de0d898216caf0fd0ae76af75753fcb3ff4f465b46131537cf24cf8"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"heck",
|
||||||
|
"indexmap",
|
||||||
|
"prettyplease",
|
||||||
|
"syn 2.0.119",
|
||||||
|
"wasm-metadata",
|
||||||
|
"wit-bindgen-core",
|
||||||
|
"wit-component",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rust-macro"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59283a01aec94f60f92ada22ffe182a5cea8acfce43be3be688de8d52df55312"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
"wit-bindgen-core",
|
||||||
|
"wit-bindgen-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-component"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "481b5c47b2ecce0389b5e08a05557d6a190c9cd761773b8880a8017ee04dc7ef"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bitflags",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"wasm-encoder",
|
||||||
|
"wasm-metadata",
|
||||||
|
"wasmparser",
|
||||||
|
"wit-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-parser"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff4daaa3cd97ae49ecd0a99dc009d453f93e0f083dd3be38c0f24a83a93e37ac"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"hashbrown",
|
||||||
|
"id-arena",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"unicode-ident",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zmij"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
||||||
14
basics/01-hello-world/Cargo.toml
Normal file
14
basics/01-hello-world/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "hello-world"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
authors = ["Pumpkin Developer"]
|
||||||
|
description = "A minimal hello-world plugin example for the Pumpkin Minecraft server"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
pumpkin-plugin-api = "0.1.0-dev"
|
||||||
|
tracing = "0.1"
|
||||||
52
basics/01-hello-world/src/lib.rs
Normal file
52
basics/01-hello-world/src/lib.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
//! # 01 - Hello World Plugin Example for Pumpkin
|
||||||
|
//!
|
||||||
|
//! This is the simplest possible Pumpkin plugin. It demonstrates:
|
||||||
|
//! - Defining a plugin struct and implementing the [`Plugin`] trait.
|
||||||
|
//! - Setting up metadata (name, version, authors, permissions).
|
||||||
|
//! - Handling the [`on_load`] and [`on_unload`] lifecycle callbacks.
|
||||||
|
//! - Logging using the `tracing` crate, which connects to Pumpkin's server log system.
|
||||||
|
//! - Registering the plugin with the [`register_plugin!`] macro.
|
||||||
|
|
||||||
|
use pumpkin_plugin_api::{
|
||||||
|
Context, Plugin, PluginMetadata, permissions, register_plugin,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The main plugin state struct.
|
||||||
|
pub struct HelloWorldPlugin;
|
||||||
|
|
||||||
|
impl Plugin for HelloWorldPlugin {
|
||||||
|
/// Constructs a new instance of the plugin.
|
||||||
|
///
|
||||||
|
/// Called once by the runtime before [`on_load`](Plugin::on_load).
|
||||||
|
fn new() -> Self {
|
||||||
|
HelloWorldPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provides metadata describing this plugin to the Pumpkin server.
|
||||||
|
fn metadata(&self) -> PluginMetadata {
|
||||||
|
PluginMetadata {
|
||||||
|
name: "hello-world".into(),
|
||||||
|
version: env!("CARGO_PKG_VERSION").into(),
|
||||||
|
authors: vec!["Pumpkin Developer".into()],
|
||||||
|
description: "A minimal Hello World plugin for Pumpkin Minecraft server.".into(),
|
||||||
|
dependencies: vec![],
|
||||||
|
permissions: vec![permissions::FS_READ_DATA.into()],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked when the server loads and enables the plugin.
|
||||||
|
fn on_load(&self, context: Context) -> Result<(), String> {
|
||||||
|
tracing::info!("Hello, world from Pumpkin plugin!");
|
||||||
|
tracing::info!("Plugin private data directory: {}", context.get_data_folder());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoked when the server unloads or stops the plugin.
|
||||||
|
fn on_unload(&self, _context: Context) -> Result<(), String> {
|
||||||
|
tracing::info!("Goodbye from Hello World plugin!");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register HelloWorldPlugin as the entrypoint for the WebAssembly component.
|
||||||
|
register_plugin!(HelloWorldPlugin);
|
||||||
530
basics/02-custom-command/Cargo.lock
generated
Normal file
530
basics/02-custom-command/Cargo.lock
generated
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.104"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic-polyfill"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cobs"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "critical-section"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "custom-command"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"pumpkin-plugin-api",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hash32"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.17.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||||
|
dependencies = [
|
||||||
|
"foldhash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heapless"
|
||||||
|
version = "0.7.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-polyfill",
|
||||||
|
"hash32",
|
||||||
|
"rustc_version",
|
||||||
|
"serde",
|
||||||
|
"spin",
|
||||||
|
"stable_deref_trait",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "id-arena"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.14.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leb128fmt"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||||
|
|
||||||
|
[[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.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "postcard"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
|
||||||
|
dependencies = [
|
||||||
|
"cobs",
|
||||||
|
"embedded-io 0.4.0",
|
||||||
|
"embedded-io 0.6.1",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prettyplease"
|
||||||
|
version = "0.2.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "pumpkin-plugin-api"
|
||||||
|
version = "0.1.0-dev+26.2-26.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09559c59b3c594994856d81a4101b6b10be3843542b191bb1d0a4fff19058888"
|
||||||
|
dependencies = [
|
||||||
|
"postcard",
|
||||||
|
"serde_json",
|
||||||
|
"tracing",
|
||||||
|
"tracing-serde-structured",
|
||||||
|
"wit-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
|
||||||
|
|
||||||
|
[[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.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.151"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
"zmij",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
|
[[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.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "tracing-serde-structured"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0832510e9838a4ff7e45e278602ab0533686f9507bc6189e024e488602f29820"
|
||||||
|
dependencies = [
|
||||||
|
"hash32",
|
||||||
|
"heapless",
|
||||||
|
"serde",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-encoder"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e974fe6821a8cf64575d51ea2194e2c8f77e7b66e9afe7419ce8a97f9ee0d251"
|
||||||
|
dependencies = [
|
||||||
|
"leb128fmt",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-metadata"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18a11585adb92fe9b55ad1d760e8d8fb5d87e0d2e303cb8eed57f078d54293a2"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"indexmap",
|
||||||
|
"wasm-encoder",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmparser"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9a61719f93a87b16d325921e251800c4833f8fab50fa21c7de73aed50086313"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"hashbrown",
|
||||||
|
"indexmap",
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e473fd0095479f9689ac7d2a52c427cc96bb2b973ace50238dfcc1ab1cd52d93"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen-rust-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-core"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87445680dfe6d6b5369e884bd63c03a3335268e855365b2fc3f7bcdce96a630e"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"heck",
|
||||||
|
"wit-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rust"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72f2fe494de0d898216caf0fd0ae76af75753fcb3ff4f465b46131537cf24cf8"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"heck",
|
||||||
|
"indexmap",
|
||||||
|
"prettyplease",
|
||||||
|
"syn 2.0.119",
|
||||||
|
"wasm-metadata",
|
||||||
|
"wit-bindgen-core",
|
||||||
|
"wit-component",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rust-macro"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59283a01aec94f60f92ada22ffe182a5cea8acfce43be3be688de8d52df55312"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
"wit-bindgen-core",
|
||||||
|
"wit-bindgen-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-component"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "481b5c47b2ecce0389b5e08a05557d6a190c9cd761773b8880a8017ee04dc7ef"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bitflags",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"wasm-encoder",
|
||||||
|
"wasm-metadata",
|
||||||
|
"wasmparser",
|
||||||
|
"wit-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-parser"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff4daaa3cd97ae49ecd0a99dc009d453f93e0f083dd3be38c0f24a83a93e37ac"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"hashbrown",
|
||||||
|
"id-arena",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"unicode-ident",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zmij"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
||||||
14
basics/02-custom-command/Cargo.toml
Normal file
14
basics/02-custom-command/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "custom-command"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
authors = ["Pumpkin Developer"]
|
||||||
|
description = "A custom command plugin example for the Pumpkin Minecraft server"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
pumpkin-plugin-api = "0.1.0-dev"
|
||||||
|
tracing = "0.1"
|
||||||
138
basics/02-custom-command/src/lib.rs
Normal file
138
basics/02-custom-command/src/lib.rs
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
//! # 02 - Custom Command Plugin Example for Pumpkin
|
||||||
|
//!
|
||||||
|
//! Demonstrates:
|
||||||
|
//! - Building and registering custom Minecraft commands using the Pumpkin Plugin API.
|
||||||
|
//! - Setting up subcommands with [`CommandNode::literal`].
|
||||||
|
//! - Defining typed arguments with [`CommandNode::argument`] and [`ArgumentType`].
|
||||||
|
//! - Implementing [`CommandHandler`] to handle command execution.
|
||||||
|
//! - Extracting consumed arguments from [`ConsumedArgs`].
|
||||||
|
//! - Sending feedback messages back to the [`CommandSender`].
|
||||||
|
//! - Accessing server methods from [`Server`].
|
||||||
|
|
||||||
|
use pumpkin_plugin_api::{
|
||||||
|
command::{
|
||||||
|
Arg, ArgumentType, Command, CommandError, CommandNode, CommandSender, ConsumedArgs,
|
||||||
|
StringType,
|
||||||
|
},
|
||||||
|
commands::CommandHandler,
|
||||||
|
Context, Plugin, PluginMetadata, register_plugin, Server,
|
||||||
|
text::TextComponent,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Handler for the root `/greet` command.
|
||||||
|
struct GreetRootHandler;
|
||||||
|
|
||||||
|
impl CommandHandler for GreetRootHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
_server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let sender_name = sender.get_name();
|
||||||
|
let message = format!("Hello, {sender_name}! Welcome to Pumpkin!");
|
||||||
|
sender.send_message(TextComponent::text(&message));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handler for `/greet broadcast <message>`.
|
||||||
|
struct GreetBroadcastHandler;
|
||||||
|
|
||||||
|
impl CommandHandler for GreetBroadcastHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let message = match args.get_value("message") {
|
||||||
|
Arg::Simple(s) | Arg::Msg(s) => s,
|
||||||
|
_ => "Hello everyone!".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let sender_name = sender.get_name();
|
||||||
|
let broadcast_text = format!("[Broadcast by {sender_name}] {message}");
|
||||||
|
server.broadcast(&broadcast_text);
|
||||||
|
|
||||||
|
sender.send_message(TextComponent::text("Broadcast sent to all online players!"));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handler for `/greet stats`.
|
||||||
|
struct GreetStatsHandler;
|
||||||
|
|
||||||
|
impl CommandHandler for GreetStatsHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let tps = server.get_tps();
|
||||||
|
let mspt = server.get_mspt();
|
||||||
|
let player_count = server.get_player_count();
|
||||||
|
let max_players = server.get_max_players();
|
||||||
|
|
||||||
|
let stats_info = format!(
|
||||||
|
"Server Stats:\n - TPS: {:.2}\n - MSPT: {:.2}ms\n - Players: {}/{}",
|
||||||
|
tps, mspt, player_count, max_players
|
||||||
|
);
|
||||||
|
|
||||||
|
sender.send_message(TextComponent::text(&stats_info));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Main plugin struct for custom command example.
|
||||||
|
pub struct CustomCommandPlugin;
|
||||||
|
|
||||||
|
impl Plugin for CustomCommandPlugin {
|
||||||
|
fn new() -> Self {
|
||||||
|
CustomCommandPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&self) -> PluginMetadata {
|
||||||
|
PluginMetadata {
|
||||||
|
name: "custom-command".into(),
|
||||||
|
version: env!("CARGO_PKG_VERSION").into(),
|
||||||
|
authors: vec!["Pumpkin Developer".into()],
|
||||||
|
description: "A custom command example for the Pumpkin Minecraft server.".into(),
|
||||||
|
dependencies: vec![],
|
||||||
|
permissions: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_load(&self, context: Context) -> Result<(), String> {
|
||||||
|
let names = ["greet".to_string(), "greeting".to_string()];
|
||||||
|
|
||||||
|
// Build command tree:
|
||||||
|
// /greet
|
||||||
|
// /greet broadcast <message>
|
||||||
|
// /greet stats
|
||||||
|
let command = Command::new(&names, "A friendly greeting and server stats command")
|
||||||
|
.then(
|
||||||
|
CommandNode::literal("broadcast").then(
|
||||||
|
CommandNode::argument("message", &ArgumentType::String(StringType::Greedy))
|
||||||
|
.execute(GreetBroadcastHandler),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
CommandNode::literal("stats").execute(GreetStatsHandler),
|
||||||
|
)
|
||||||
|
.execute(GreetRootHandler);
|
||||||
|
|
||||||
|
context.register_command(command, "pumpkin.command.greet");
|
||||||
|
tracing::info!("Registered /greet command with aliases and subcommands!");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_unload(&self, _context: Context) -> Result<(), String> {
|
||||||
|
tracing::info!("Unloaded custom command plugin!");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register_plugin!(CustomCommandPlugin);
|
||||||
530
basics/03-event-listener/Cargo.lock
generated
Normal file
530
basics/03-event-listener/Cargo.lock
generated
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.104"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic-polyfill"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cobs"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "critical-section"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-io"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "event-listener"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"pumpkin-plugin-api",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hash32"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.17.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||||
|
dependencies = [
|
||||||
|
"foldhash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heapless"
|
||||||
|
version = "0.7.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-polyfill",
|
||||||
|
"hash32",
|
||||||
|
"rustc_version",
|
||||||
|
"serde",
|
||||||
|
"spin",
|
||||||
|
"stable_deref_trait",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "id-arena"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.14.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leb128fmt"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||||
|
|
||||||
|
[[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.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "postcard"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
|
||||||
|
dependencies = [
|
||||||
|
"cobs",
|
||||||
|
"embedded-io 0.4.0",
|
||||||
|
"embedded-io 0.6.1",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prettyplease"
|
||||||
|
version = "0.2.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "pumpkin-plugin-api"
|
||||||
|
version = "0.1.0-dev+26.2-26.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09559c59b3c594994856d81a4101b6b10be3843542b191bb1d0a4fff19058888"
|
||||||
|
dependencies = [
|
||||||
|
"postcard",
|
||||||
|
"serde_json",
|
||||||
|
"tracing",
|
||||||
|
"tracing-serde-structured",
|
||||||
|
"wit-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.47"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
|
||||||
|
|
||||||
|
[[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.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.151"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
"zmij",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
|
[[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.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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 = "tracing-serde-structured"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0832510e9838a4ff7e45e278602ab0533686f9507bc6189e024e488602f29820"
|
||||||
|
dependencies = [
|
||||||
|
"hash32",
|
||||||
|
"heapless",
|
||||||
|
"serde",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-encoder"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e974fe6821a8cf64575d51ea2194e2c8f77e7b66e9afe7419ce8a97f9ee0d251"
|
||||||
|
dependencies = [
|
||||||
|
"leb128fmt",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-metadata"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18a11585adb92fe9b55ad1d760e8d8fb5d87e0d2e303cb8eed57f078d54293a2"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"indexmap",
|
||||||
|
"wasm-encoder",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmparser"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9a61719f93a87b16d325921e251800c4833f8fab50fa21c7de73aed50086313"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"hashbrown",
|
||||||
|
"indexmap",
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e473fd0095479f9689ac7d2a52c427cc96bb2b973ace50238dfcc1ab1cd52d93"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen-rust-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-core"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87445680dfe6d6b5369e884bd63c03a3335268e855365b2fc3f7bcdce96a630e"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"heck",
|
||||||
|
"wit-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rust"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72f2fe494de0d898216caf0fd0ae76af75753fcb3ff4f465b46131537cf24cf8"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"heck",
|
||||||
|
"indexmap",
|
||||||
|
"prettyplease",
|
||||||
|
"syn 2.0.119",
|
||||||
|
"wasm-metadata",
|
||||||
|
"wit-bindgen-core",
|
||||||
|
"wit-component",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rust-macro"
|
||||||
|
version = "0.61.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59283a01aec94f60f92ada22ffe182a5cea8acfce43be3be688de8d52df55312"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
"wit-bindgen-core",
|
||||||
|
"wit-bindgen-rust",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-component"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "481b5c47b2ecce0389b5e08a05557d6a190c9cd761773b8880a8017ee04dc7ef"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bitflags",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"wasm-encoder",
|
||||||
|
"wasm-metadata",
|
||||||
|
"wasmparser",
|
||||||
|
"wit-parser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-parser"
|
||||||
|
version = "0.258.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff4daaa3cd97ae49ecd0a99dc009d453f93e0f083dd3be38c0f24a83a93e37ac"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"hashbrown",
|
||||||
|
"id-arena",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"unicode-ident",
|
||||||
|
"wasmparser",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zmij"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
||||||
14
basics/03-event-listener/Cargo.toml
Normal file
14
basics/03-event-listener/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "event-listener"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
authors = ["Pumpkin Developer"]
|
||||||
|
description = "An event listener plugin example for the Pumpkin Minecraft server"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
pumpkin-plugin-api = "0.1.0-dev"
|
||||||
|
tracing = "0.1"
|
||||||
140
basics/03-event-listener/src/lib.rs
Normal file
140
basics/03-event-listener/src/lib.rs
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
//! # 03 - Event Listener Plugin Example for Pumpkin
|
||||||
|
//!
|
||||||
|
//! Demonstrates:
|
||||||
|
//! - Subscribing to Pumpkin server events using [`EventHandler`].
|
||||||
|
//! - Registering listeners with [`Context::register_event_handler`].
|
||||||
|
//! - Setting [`EventPriority`] and configuring blocking vs non-blocking handlers.
|
||||||
|
//! - Handling player join and leave lifecycle events ([`PlayerJoinEvent`], [`PlayerLeaveEvent`]).
|
||||||
|
//! - Interacting with players (custom messages, titles, action bar).
|
||||||
|
//! - Handling block events ([`BlockBreakEvent`]) and cancelling events (`cancelled = true`) to protect blocks.
|
||||||
|
|
||||||
|
use pumpkin_plugin_api::{
|
||||||
|
events::{
|
||||||
|
EventHandler, EventPriority,
|
||||||
|
block::BlockBreakEvent,
|
||||||
|
player::{PlayerJoinEvent, PlayerLeaveEvent},
|
||||||
|
},
|
||||||
|
events_wit::{BlockBreakEventData, PlayerJoinEventData, PlayerLeaveEventData},
|
||||||
|
Context, Plugin, PluginMetadata, register_plugin, Server,
|
||||||
|
text::TextComponent,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Listens for players joining the server.
|
||||||
|
struct JoinListener;
|
||||||
|
|
||||||
|
impl EventHandler<PlayerJoinEvent> for JoinListener {
|
||||||
|
fn handle(&self, _server: Server, event: PlayerJoinEventData) -> PlayerJoinEventData {
|
||||||
|
let name = event.player.get_name();
|
||||||
|
tracing::info!("Player joined the game: {name}");
|
||||||
|
|
||||||
|
// Send a private chat message to the player
|
||||||
|
event.player.send_system_message(
|
||||||
|
TextComponent::text(&format!("Welcome to the server, {name}!")),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Show a welcoming title screen to the player
|
||||||
|
event
|
||||||
|
.player
|
||||||
|
.show_title(TextComponent::text("Welcome to Pumpkin!"));
|
||||||
|
event
|
||||||
|
.player
|
||||||
|
.show_subtitle(TextComponent::text("Have fun building and exploring!"));
|
||||||
|
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Listens for players leaving the server.
|
||||||
|
struct LeaveListener;
|
||||||
|
|
||||||
|
impl EventHandler<PlayerLeaveEvent> for LeaveListener {
|
||||||
|
fn handle(&self, _server: Server, event: PlayerLeaveEventData) -> PlayerLeaveEventData {
|
||||||
|
let name = event.player.get_name();
|
||||||
|
tracing::info!("Player left the game: {name}");
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Listens for block breaking events and demonstrates event cancellation.
|
||||||
|
struct BlockBreakListener;
|
||||||
|
|
||||||
|
impl EventHandler<BlockBreakEvent> for BlockBreakListener {
|
||||||
|
fn handle(&self, _server: Server, mut event: BlockBreakEventData) -> BlockBreakEventData {
|
||||||
|
let block_name = &event.block;
|
||||||
|
let pos = &event.block_pos;
|
||||||
|
|
||||||
|
tracing::info!(
|
||||||
|
"Block broken: {block_name} at X:{} Y:{} Z:{}",
|
||||||
|
pos.x, pos.y, pos.z
|
||||||
|
);
|
||||||
|
|
||||||
|
// Example: Protect bedrock and barrier blocks from being broken
|
||||||
|
if block_name.contains("bedrock") || block_name.contains("barrier") {
|
||||||
|
tracing::warn!("Cancelled breaking protected block '{block_name}' at ({}, {}, {})", pos.x, pos.y, pos.z);
|
||||||
|
event.cancelled = true;
|
||||||
|
|
||||||
|
if let Some(player) = &event.player {
|
||||||
|
player.send_system_message(
|
||||||
|
TextComponent::text("You cannot break this protected block!"),
|
||||||
|
true, // overlay = true displays in the action bar
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Main plugin struct for the event listener example.
|
||||||
|
pub struct EventListenerPlugin;
|
||||||
|
|
||||||
|
impl Plugin for EventListenerPlugin {
|
||||||
|
fn new() -> Self {
|
||||||
|
EventListenerPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&self) -> PluginMetadata {
|
||||||
|
PluginMetadata {
|
||||||
|
name: "event-listener".into(),
|
||||||
|
version: env!("CARGO_PKG_VERSION").into(),
|
||||||
|
authors: vec!["Pumpkin Developer".into()],
|
||||||
|
description: "An event listener example for the Pumpkin Minecraft server.".into(),
|
||||||
|
dependencies: vec![],
|
||||||
|
permissions: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_load(&self, context: Context) -> Result<(), String> {
|
||||||
|
// Register PlayerJoinEvent (non-blocking notification)
|
||||||
|
context.register_event_handler(
|
||||||
|
JoinListener,
|
||||||
|
EventPriority::Normal,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Register PlayerLeaveEvent (non-blocking notification)
|
||||||
|
context.register_event_handler(
|
||||||
|
LeaveListener,
|
||||||
|
EventPriority::Normal,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Register BlockBreakEvent (blocking = true allows event.cancelled to take effect)
|
||||||
|
context.register_event_handler(
|
||||||
|
BlockBreakListener,
|
||||||
|
EventPriority::High,
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
tracing::info!("Registered player join, player leave, and block break event handlers!");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_unload(&self, _context: Context) -> Result<(), String> {
|
||||||
|
tracing::info!("Unloaded event listener plugin!");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register_plugin!(EventListenerPlugin);
|
||||||
14
minigames/spleef/Cargo.toml
Normal file
14
minigames/spleef/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "spleef"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
authors = ["Pumpkin Developer"]
|
||||||
|
description = "A complete Spleef minigame for the Pumpkin Minecraft server"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
pumpkin-plugin-api = "0.1.0-dev"
|
||||||
|
tracing = "0.1"
|
||||||
412
minigames/spleef/src/lib.rs
Normal file
412
minigames/spleef/src/lib.rs
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
//! # Spleef Minigame for Pumpkin
|
||||||
|
//!
|
||||||
|
//! A complete, runnable Spleef minigame showcasing:
|
||||||
|
//! - State management (`Waiting`, `Active`, `Ended`).
|
||||||
|
//! - Commands: `/spleef join`, `/spleef leave`, `/spleef start`, `/spleef status`, `/spleef reset`.
|
||||||
|
//! - [`BlockBreakEvent`]:
|
||||||
|
//! - Allows breaking snow blocks inside the active arena.
|
||||||
|
//! - Protects blocks outside the arena boundary or before the game starts.
|
||||||
|
//! - [`PlayerMoveEvent`]:
|
||||||
|
//! - Detects players falling below the snow platform into the elimination zone.
|
||||||
|
//! - Automatic win condition check (last player standing).
|
||||||
|
//! - Arena regeneration (`/spleef reset`).
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
collections::HashSet,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
};
|
||||||
|
|
||||||
|
use pumpkin_plugin_api::{
|
||||||
|
command::{Command, CommandError, CommandNode, CommandSender, ConsumedArgs},
|
||||||
|
commands::CommandHandler,
|
||||||
|
common::{BlockPos, Position},
|
||||||
|
events::{
|
||||||
|
EventHandler, EventPriority,
|
||||||
|
block::BlockBreakEvent,
|
||||||
|
player::PlayerMoveEvent,
|
||||||
|
},
|
||||||
|
events_wit::{BlockBreakEventData, PlayerMoveEventData},
|
||||||
|
world::BlockFlags,
|
||||||
|
Context, Plugin, PluginMetadata, register_plugin, Server,
|
||||||
|
text::TextComponent,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Spleef arena boundaries and platform heights.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct SpleefConfig {
|
||||||
|
pub min_x: i32,
|
||||||
|
pub max_x: i32,
|
||||||
|
pub min_z: i32,
|
||||||
|
pub max_z: i32,
|
||||||
|
pub floor_y: i32,
|
||||||
|
pub elimination_y: f64,
|
||||||
|
pub spawn_pos: Position,
|
||||||
|
pub lobby_pos: Position,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SpleefConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
min_x: -12,
|
||||||
|
max_x: 12,
|
||||||
|
min_z: -12,
|
||||||
|
max_z: 12,
|
||||||
|
floor_y: 100,
|
||||||
|
elimination_y: 92.0,
|
||||||
|
spawn_pos: (0.5, 101.0, 0.5),
|
||||||
|
lobby_pos: (0.5, 115.0, 0.5),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpleefConfig {
|
||||||
|
pub fn is_inside_floor(&self, x: i32, y: i32, z: i32) -> bool {
|
||||||
|
y == self.floor_y && x >= self.min_x && x <= self.max_x && z >= self.min_z && z <= self.max_z
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum GameState {
|
||||||
|
Waiting,
|
||||||
|
Active,
|
||||||
|
Ended,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SpleefSession {
|
||||||
|
pub state: GameState,
|
||||||
|
pub config: SpleefConfig,
|
||||||
|
pub queued_players: HashSet<String>,
|
||||||
|
pub alive_players: HashSet<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpleefSession {
|
||||||
|
pub fn new(config: SpleefConfig) -> Self {
|
||||||
|
Self {
|
||||||
|
state: GameState::Waiting,
|
||||||
|
config,
|
||||||
|
queued_players: HashSet::new(),
|
||||||
|
alive_players: HashSet::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SESSION: Mutex<Option<Arc<Mutex<SpleefSession>>>> = Mutex::new(None);
|
||||||
|
|
||||||
|
fn get_session() -> Arc<Mutex<SpleefSession>> {
|
||||||
|
SESSION
|
||||||
|
.lock()
|
||||||
|
.unwrap_or_else(|e| e.into_inner())
|
||||||
|
.clone()
|
||||||
|
.expect("SpleefSession must be initialized in on_load")
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Commands: /spleef <subcommand>
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct SpleefRootHandler;
|
||||||
|
impl CommandHandler for SpleefRootHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
_server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let help_text = "Spleef Commands:\n\
|
||||||
|
/spleef join - Join the game queue\n\
|
||||||
|
/spleef leave - Leave the queue or game\n\
|
||||||
|
/spleef start - Force start the game\n\
|
||||||
|
/spleef status - View game status\n\
|
||||||
|
/spleef reset - Regenerate snow arena floor";
|
||||||
|
sender.send_message(TextComponent::text(help_text));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpleefJoinHandler;
|
||||||
|
impl CommandHandler for SpleefJoinHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let player_name = sender.get_name();
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
match session.state {
|
||||||
|
GameState::Active => {
|
||||||
|
sender.send_message(TextComponent::text("Game is already in progress! Please wait."));
|
||||||
|
}
|
||||||
|
GameState::Waiting | GameState::Ended => {
|
||||||
|
if session.queued_players.insert(player_name.clone()) {
|
||||||
|
let count = session.queued_players.len();
|
||||||
|
server.broadcast(&format!("{player_name} joined Spleef! ({count} players queued)"));
|
||||||
|
sender.send_message(TextComponent::text("You joined the queue! Use /spleef start when ready."));
|
||||||
|
} else {
|
||||||
|
sender.send_message(TextComponent::text("You are already in the queue!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpleefLeaveHandler;
|
||||||
|
impl CommandHandler for SpleefLeaveHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let player_name = sender.get_name();
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
if session.queued_players.remove(&player_name) || session.alive_players.remove(&player_name) {
|
||||||
|
server.broadcast(&format!("{player_name} left Spleef."));
|
||||||
|
sender.send_message(TextComponent::text("You left Spleef."));
|
||||||
|
} else {
|
||||||
|
sender.send_message(TextComponent::text("You are not currently in a Spleef game."));
|
||||||
|
}
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpleefStartHandler;
|
||||||
|
impl CommandHandler for SpleefStartHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
if session.state == GameState::Active {
|
||||||
|
sender.send_message(TextComponent::text("Game is already running!"));
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if session.queued_players.is_empty() {
|
||||||
|
session.queued_players.insert(sender.get_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
session.alive_players = session.queued_players.clone();
|
||||||
|
session.state = GameState::Active;
|
||||||
|
|
||||||
|
let count = session.alive_players.len();
|
||||||
|
server.broadcast(&format!("Spleef has STARTED with {count} players! Spleef your opponents!"));
|
||||||
|
|
||||||
|
let spawn = session.config.spawn_pos;
|
||||||
|
for player_name in &session.alive_players {
|
||||||
|
if let Some(player) = server.get_player_by_name(player_name) {
|
||||||
|
let world = player.get_world();
|
||||||
|
player.teleport(spawn, Some(0.0), Some(0.0), world);
|
||||||
|
player.show_title(TextComponent::text("SPLEEF!"));
|
||||||
|
player.show_subtitle(TextComponent::text("Break blocks beneath your rivals!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpleefStatusHandler;
|
||||||
|
impl CommandHandler for SpleefStatusHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
_server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let session_arc = get_session();
|
||||||
|
let session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
let status_msg = match session.state {
|
||||||
|
GameState::Waiting => format!("Spleef: WAITING ({} queued)", session.queued_players.len()),
|
||||||
|
GameState::Active => format!(
|
||||||
|
"Spleef: ACTIVE ({} alive: {:?})",
|
||||||
|
session.alive_players.len(),
|
||||||
|
session.alive_players
|
||||||
|
),
|
||||||
|
GameState::Ended => "Spleef: ENDED (Use /spleef reset or /spleef start)".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
sender.send_message(TextComponent::text(&status_msg));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpleefResetHandler;
|
||||||
|
impl CommandHandler for SpleefResetHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
session.state = GameState::Waiting;
|
||||||
|
session.alive_players.clear();
|
||||||
|
|
||||||
|
let worlds = server.get_all_worlds();
|
||||||
|
if let Some(world) = worlds.first() {
|
||||||
|
let flags = BlockFlags::NOTIFY_LISTENERS | BlockFlags::NOTIFY_NEIGHBORS;
|
||||||
|
for x in session.config.min_x..=session.config.max_x {
|
||||||
|
for z in session.config.min_z..=session.config.max_z {
|
||||||
|
let pos = BlockPos { x, y: session.config.floor_y, z };
|
||||||
|
world.set_block_by_name(pos, "minecraft:snow_block", flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server.broadcast("Spleef arena has been regenerated and reset!");
|
||||||
|
sender.send_message(TextComponent::text("Spleef reset complete!"));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Event Listeners: BlockBreakEvent & PlayerMoveEvent
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct SpleefBreakListener;
|
||||||
|
|
||||||
|
impl EventHandler<BlockBreakEvent> for SpleefBreakListener {
|
||||||
|
fn handle(&self, _server: Server, mut event: BlockBreakEventData) -> BlockBreakEventData {
|
||||||
|
let session_arc = get_session();
|
||||||
|
let session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
let pos = &event.block_pos;
|
||||||
|
|
||||||
|
// If the block broken is on the Spleef floor:
|
||||||
|
if session.config.is_inside_floor(pos.x, pos.y, pos.z) {
|
||||||
|
// Only allow breaking during Active state by alive players
|
||||||
|
if session.state == GameState::Active {
|
||||||
|
if let Some(player) = &event.player {
|
||||||
|
if session.alive_players.contains(&player.get_name()) {
|
||||||
|
event.should_drop = false; // Don't drop cluttering snowballs
|
||||||
|
event.cancelled = false;
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Disallow breaking floor before start or by spectators
|
||||||
|
event.cancelled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpleefMoveListener;
|
||||||
|
|
||||||
|
impl EventHandler<PlayerMoveEvent> for SpleefMoveListener {
|
||||||
|
fn handle(&self, server: Server, event: PlayerMoveEventData) -> PlayerMoveEventData {
|
||||||
|
let player_name = event.player.get_name();
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
if session.state != GameState::Active || !session.alive_players.contains(&player_name) {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
let to = &event.to_position;
|
||||||
|
|
||||||
|
// Elimination Check: player fell below elimination threshold
|
||||||
|
if to.1 < session.config.elimination_y {
|
||||||
|
session.alive_players.remove(&player_name);
|
||||||
|
server.broadcast(&format!("{player_name} was SPLEEFED and eliminated!"));
|
||||||
|
|
||||||
|
let lobby = session.config.lobby_pos;
|
||||||
|
let world = event.player.get_world();
|
||||||
|
event.player.teleport(lobby, Some(0.0), Some(0.0), world);
|
||||||
|
event.player.show_title(TextComponent::text("SPLEEFED!"));
|
||||||
|
|
||||||
|
if session.alive_players.len() == 1 {
|
||||||
|
let winner_name = session.alive_players.iter().next().cloned().unwrap();
|
||||||
|
server.broadcast(&format!("VICTORY! {winner_name} is the last player standing and WINS Spleef!"));
|
||||||
|
if let Some(winner) = server.get_player_by_name(&winner_name) {
|
||||||
|
winner.show_title(TextComponent::text("VICTORY!"));
|
||||||
|
winner.show_subtitle(TextComponent::text("You won Spleef!"));
|
||||||
|
}
|
||||||
|
session.state = GameState::Ended;
|
||||||
|
} else if session.alive_players.is_empty() {
|
||||||
|
server.broadcast("Game Over! No players remaining.");
|
||||||
|
session.state = GameState::Ended;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Plugin Lifecycle
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub struct SpleefPlugin;
|
||||||
|
|
||||||
|
impl Plugin for SpleefPlugin {
|
||||||
|
fn new() -> Self {
|
||||||
|
SpleefPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&self) -> PluginMetadata {
|
||||||
|
PluginMetadata {
|
||||||
|
name: "spleef".into(),
|
||||||
|
version: env!("CARGO_PKG_VERSION").into(),
|
||||||
|
authors: vec!["Pumpkin Developer".into()],
|
||||||
|
description: "A complete Spleef minigame for Pumpkin Minecraft server.".into(),
|
||||||
|
dependencies: vec![],
|
||||||
|
permissions: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_load(&self, context: Context) -> Result<(), String> {
|
||||||
|
let config = SpleefConfig::default();
|
||||||
|
let session = Arc::new(Mutex::new(SpleefSession::new(config)));
|
||||||
|
*SESSION.lock().unwrap_or_else(|e| e.into_inner()) = Some(session);
|
||||||
|
|
||||||
|
let names = ["spleef".to_string(), "sp".to_string()];
|
||||||
|
let command = Command::new(&names, "Spleef minigame management command")
|
||||||
|
.then(CommandNode::literal("join").execute(SpleefJoinHandler))
|
||||||
|
.then(CommandNode::literal("leave").execute(SpleefLeaveHandler))
|
||||||
|
.then(CommandNode::literal("start").execute(SpleefStartHandler))
|
||||||
|
.then(CommandNode::literal("status").execute(SpleefStatusHandler))
|
||||||
|
.then(CommandNode::literal("reset").execute(SpleefResetHandler))
|
||||||
|
.execute(SpleefRootHandler);
|
||||||
|
|
||||||
|
context.register_command(command, "pumpkin.command.spleef");
|
||||||
|
|
||||||
|
// Register BlockBreakEvent (blocking = true to allow/cancel break)
|
||||||
|
context.register_event_handler(
|
||||||
|
SpleefBreakListener,
|
||||||
|
EventPriority::High,
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Register PlayerMoveEvent for void detection
|
||||||
|
context.register_event_handler(
|
||||||
|
SpleefMoveListener,
|
||||||
|
EventPriority::Normal,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
tracing::info!("Spleef minigame plugin successfully loaded!");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_unload(&self, _context: Context) -> Result<(), String> {
|
||||||
|
tracing::info!("Spleef plugin unloaded.");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register_plugin!(SpleefPlugin);
|
||||||
14
minigames/sumo/Cargo.toml
Normal file
14
minigames/sumo/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "sumo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
authors = ["Pumpkin Developer"]
|
||||||
|
description = "A complete Sumo minigame for the Pumpkin Minecraft server"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
pumpkin-plugin-api = "0.1.0-dev"
|
||||||
|
tracing = "0.1"
|
||||||
408
minigames/sumo/src/lib.rs
Normal file
408
minigames/sumo/src/lib.rs
Normal file
@ -0,0 +1,408 @@
|
|||||||
|
//! # Sumo Minigame for Pumpkin
|
||||||
|
//!
|
||||||
|
//! A complete, runnable Sumo PvP minigame showcasing:
|
||||||
|
//! - State management (`Waiting`, `Active`, `Ended`).
|
||||||
|
//! - Commands: `/sumo join`, `/sumo leave`, `/sumo start`, `/sumo status`, `/sumo reset`.
|
||||||
|
//! - Arena protection: cancels all block breaking on the Sumo ring via [`BlockBreakEvent`].
|
||||||
|
//! - Ring-out elimination: monitors [`PlayerMoveEvent`] to detect when a player is knocked off.
|
||||||
|
//! - Automatic win condition check (last player remaining on the platform).
|
||||||
|
//! - Platform regeneration (`/sumo reset`).
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
collections::HashSet,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
};
|
||||||
|
|
||||||
|
use pumpkin_plugin_api::{
|
||||||
|
command::{Command, CommandError, CommandNode, CommandSender, ConsumedArgs},
|
||||||
|
commands::CommandHandler,
|
||||||
|
common::{BlockPos, Position},
|
||||||
|
events::{
|
||||||
|
EventHandler, EventPriority,
|
||||||
|
block::BlockBreakEvent,
|
||||||
|
player::PlayerMoveEvent,
|
||||||
|
},
|
||||||
|
events_wit::{BlockBreakEventData, PlayerMoveEventData},
|
||||||
|
world::BlockFlags,
|
||||||
|
Context, Plugin, PluginMetadata, register_plugin, Server,
|
||||||
|
text::TextComponent,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Sumo ring boundaries and platform coordinates.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct SumoConfig {
|
||||||
|
pub min_x: i32,
|
||||||
|
pub max_x: i32,
|
||||||
|
pub min_z: i32,
|
||||||
|
pub max_z: i32,
|
||||||
|
pub platform_y: i32,
|
||||||
|
pub elimination_y: f64,
|
||||||
|
pub spawn_pos_1: Position,
|
||||||
|
pub spawn_pos_2: Position,
|
||||||
|
pub lobby_pos: Position,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SumoConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
min_x: -6,
|
||||||
|
max_x: 6,
|
||||||
|
min_z: -6,
|
||||||
|
max_z: 6,
|
||||||
|
platform_y: 100,
|
||||||
|
elimination_y: 95.0,
|
||||||
|
spawn_pos_1: (-3.5, 101.0, 0.5),
|
||||||
|
spawn_pos_2: (3.5, 101.0, 0.5),
|
||||||
|
lobby_pos: (0.5, 115.0, 0.5),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SumoConfig {
|
||||||
|
pub fn is_inside_platform(&self, x: i32, y: i32, z: i32) -> bool {
|
||||||
|
y == self.platform_y && x >= self.min_x && x <= self.max_x && z >= self.min_z && z <= self.max_z
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum GameState {
|
||||||
|
Waiting,
|
||||||
|
Active,
|
||||||
|
Ended,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SumoSession {
|
||||||
|
pub state: GameState,
|
||||||
|
pub config: SumoConfig,
|
||||||
|
pub queued_players: HashSet<String>,
|
||||||
|
pub alive_players: HashSet<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SumoSession {
|
||||||
|
pub fn new(config: SumoConfig) -> Self {
|
||||||
|
Self {
|
||||||
|
state: GameState::Waiting,
|
||||||
|
config,
|
||||||
|
queued_players: HashSet::new(),
|
||||||
|
alive_players: HashSet::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SESSION: Mutex<Option<Arc<Mutex<SumoSession>>>> = Mutex::new(None);
|
||||||
|
|
||||||
|
fn get_session() -> Arc<Mutex<SumoSession>> {
|
||||||
|
SESSION
|
||||||
|
.lock()
|
||||||
|
.unwrap_or_else(|e| e.into_inner())
|
||||||
|
.clone()
|
||||||
|
.expect("SumoSession must be initialized in on_load")
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Commands: /sumo <subcommand>
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct SumoRootHandler;
|
||||||
|
impl CommandHandler for SumoRootHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
_server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let help_text = "Sumo Commands:\n\
|
||||||
|
/sumo join - Join the Sumo queue\n\
|
||||||
|
/sumo leave - Leave the queue or game\n\
|
||||||
|
/sumo start - Force start the duel\n\
|
||||||
|
/sumo status - View game status\n\
|
||||||
|
/sumo reset - Regenerate arena ring";
|
||||||
|
sender.send_message(TextComponent::text(help_text));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SumoJoinHandler;
|
||||||
|
impl CommandHandler for SumoJoinHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let player_name = sender.get_name();
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
match session.state {
|
||||||
|
GameState::Active => {
|
||||||
|
sender.send_message(TextComponent::text("A Sumo round is currently active! Please wait."));
|
||||||
|
}
|
||||||
|
GameState::Waiting | GameState::Ended => {
|
||||||
|
if session.queued_players.insert(player_name.clone()) {
|
||||||
|
let count = session.queued_players.len();
|
||||||
|
server.broadcast(&format!("{player_name} joined Sumo! ({count} fighters queued)"));
|
||||||
|
sender.send_message(TextComponent::text("You joined the queue! Use /sumo start when ready."));
|
||||||
|
} else {
|
||||||
|
sender.send_message(TextComponent::text("You are already in the queue!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SumoLeaveHandler;
|
||||||
|
impl CommandHandler for SumoLeaveHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let player_name = sender.get_name();
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
if session.queued_players.remove(&player_name) || session.alive_players.remove(&player_name) {
|
||||||
|
server.broadcast(&format!("{player_name} left Sumo."));
|
||||||
|
sender.send_message(TextComponent::text("You left Sumo."));
|
||||||
|
} else {
|
||||||
|
sender.send_message(TextComponent::text("You are not currently in a Sumo game."));
|
||||||
|
}
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SumoStartHandler;
|
||||||
|
impl CommandHandler for SumoStartHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
if session.state == GameState::Active {
|
||||||
|
sender.send_message(TextComponent::text("Sumo match is already running!"));
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if session.queued_players.is_empty() {
|
||||||
|
session.queued_players.insert(sender.get_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
session.alive_players = session.queued_players.clone();
|
||||||
|
session.state = GameState::Active;
|
||||||
|
|
||||||
|
let count = session.alive_players.len();
|
||||||
|
server.broadcast(&format!("Sumo duel has STARTED with {count} fighters! Knock your opponents off the ring!"));
|
||||||
|
|
||||||
|
// Alternate spawn positions for players facing each other
|
||||||
|
let spawns = [session.config.spawn_pos_1, session.config.spawn_pos_2];
|
||||||
|
for (idx, player_name) in session.alive_players.iter().enumerate() {
|
||||||
|
if let Some(player) = server.get_player_by_name(player_name) {
|
||||||
|
let world = player.get_world();
|
||||||
|
let spawn = spawns[idx % spawns.len()];
|
||||||
|
player.teleport(spawn, Some(0.0), Some(0.0), world);
|
||||||
|
player.show_title(TextComponent::text("SUMO!"));
|
||||||
|
player.show_subtitle(TextComponent::text("Knock the other players off the ring!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SumoStatusHandler;
|
||||||
|
impl CommandHandler for SumoStatusHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
_server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let session_arc = get_session();
|
||||||
|
let session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
let status_msg = match session.state {
|
||||||
|
GameState::Waiting => format!("Sumo: WAITING ({} fighters queued)", session.queued_players.len()),
|
||||||
|
GameState::Active => format!(
|
||||||
|
"Sumo: ACTIVE ({} fighters on ring: {:?})",
|
||||||
|
session.alive_players.len(),
|
||||||
|
session.alive_players
|
||||||
|
),
|
||||||
|
GameState::Ended => "Sumo: ENDED (Use /sumo reset or /sumo start)".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
sender.send_message(TextComponent::text(&status_msg));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SumoResetHandler;
|
||||||
|
impl CommandHandler for SumoResetHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
session.state = GameState::Waiting;
|
||||||
|
session.alive_players.clear();
|
||||||
|
|
||||||
|
let worlds = server.get_all_worlds();
|
||||||
|
if let Some(world) = worlds.first() {
|
||||||
|
let flags = BlockFlags::NOTIFY_LISTENERS | BlockFlags::NOTIFY_NEIGHBORS;
|
||||||
|
for x in session.config.min_x..=session.config.max_x {
|
||||||
|
for z in session.config.min_z..=session.config.max_z {
|
||||||
|
let pos = BlockPos { x, y: session.config.platform_y, z };
|
||||||
|
world.set_block_by_name(pos, "minecraft:smooth_stone", flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server.broadcast("Sumo ring has been regenerated and reset!");
|
||||||
|
sender.send_message(TextComponent::text("Sumo reset complete!"));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Event Listeners: BlockBreakEvent & PlayerMoveEvent
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct SumoBreakListener;
|
||||||
|
|
||||||
|
impl EventHandler<BlockBreakEvent> for SumoBreakListener {
|
||||||
|
fn handle(&self, _server: Server, mut event: BlockBreakEventData) -> BlockBreakEventData {
|
||||||
|
let session_arc = get_session();
|
||||||
|
let session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
let pos = &event.block_pos;
|
||||||
|
|
||||||
|
// The Sumo arena platform is strictly unbreakable
|
||||||
|
if session.config.is_inside_platform(pos.x, pos.y, pos.z) {
|
||||||
|
event.cancelled = true;
|
||||||
|
if let Some(player) = &event.player {
|
||||||
|
player.send_system_message(
|
||||||
|
TextComponent::text("You cannot break the Sumo ring!"),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SumoMoveListener;
|
||||||
|
|
||||||
|
impl EventHandler<PlayerMoveEvent> for SumoMoveListener {
|
||||||
|
fn handle(&self, server: Server, event: PlayerMoveEventData) -> PlayerMoveEventData {
|
||||||
|
let player_name = event.player.get_name();
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
if session.state != GameState::Active || !session.alive_players.contains(&player_name) {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
let to = &event.to_position;
|
||||||
|
|
||||||
|
// Ring-out check: knocked off the platform below elimination Y
|
||||||
|
if to.1 < session.config.elimination_y {
|
||||||
|
session.alive_players.remove(&player_name);
|
||||||
|
server.broadcast(&format!("{player_name} was KNOCKED OFF the ring and eliminated!"));
|
||||||
|
|
||||||
|
let lobby = session.config.lobby_pos;
|
||||||
|
let world = event.player.get_world();
|
||||||
|
event.player.teleport(lobby, Some(0.0), Some(0.0), world);
|
||||||
|
event.player.show_title(TextComponent::text("RING OUT!"));
|
||||||
|
|
||||||
|
if session.alive_players.len() == 1 {
|
||||||
|
let winner_name = session.alive_players.iter().next().cloned().unwrap();
|
||||||
|
server.broadcast(&format!("VICTORY! {winner_name} pushed everyone off and WINS Sumo!"));
|
||||||
|
if let Some(winner) = server.get_player_by_name(&winner_name) {
|
||||||
|
winner.show_title(TextComponent::text("VICTORY!"));
|
||||||
|
winner.show_subtitle(TextComponent::text("You won the Sumo match!"));
|
||||||
|
}
|
||||||
|
session.state = GameState::Ended;
|
||||||
|
} else if session.alive_players.is_empty() {
|
||||||
|
server.broadcast("Game Over! All fighters fell.");
|
||||||
|
session.state = GameState::Ended;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Plugin Lifecycle
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub struct SumoPlugin;
|
||||||
|
|
||||||
|
impl Plugin for SumoPlugin {
|
||||||
|
fn new() -> Self {
|
||||||
|
SumoPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&self) -> PluginMetadata {
|
||||||
|
PluginMetadata {
|
||||||
|
name: "sumo".into(),
|
||||||
|
version: env!("CARGO_PKG_VERSION").into(),
|
||||||
|
authors: vec!["Pumpkin Developer".into()],
|
||||||
|
description: "A complete Sumo PvP minigame for Pumpkin Minecraft server.".into(),
|
||||||
|
dependencies: vec![],
|
||||||
|
permissions: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_load(&self, context: Context) -> Result<(), String> {
|
||||||
|
let config = SumoConfig::default();
|
||||||
|
let session = Arc::new(Mutex::new(SumoSession::new(config)));
|
||||||
|
*SESSION.lock().unwrap_or_else(|e| e.into_inner()) = Some(session);
|
||||||
|
|
||||||
|
let names = ["sumo".to_string(), "sm".to_string()];
|
||||||
|
let command = Command::new(&names, "Sumo minigame management command")
|
||||||
|
.then(CommandNode::literal("join").execute(SumoJoinHandler))
|
||||||
|
.then(CommandNode::literal("leave").execute(SumoLeaveHandler))
|
||||||
|
.then(CommandNode::literal("start").execute(SumoStartHandler))
|
||||||
|
.then(CommandNode::literal("status").execute(SumoStatusHandler))
|
||||||
|
.then(CommandNode::literal("reset").execute(SumoResetHandler))
|
||||||
|
.execute(SumoRootHandler);
|
||||||
|
|
||||||
|
context.register_command(command, "pumpkin.command.sumo");
|
||||||
|
|
||||||
|
// Protect the ring platform from being broken
|
||||||
|
context.register_event_handler(
|
||||||
|
SumoBreakListener,
|
||||||
|
EventPriority::High,
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Monitor ring-out falls
|
||||||
|
context.register_event_handler(
|
||||||
|
SumoMoveListener,
|
||||||
|
EventPriority::Normal,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
tracing::info!("Sumo minigame plugin successfully loaded!");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_unload(&self, _context: Context) -> Result<(), String> {
|
||||||
|
tracing::info!("Sumo plugin unloaded.");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register_plugin!(SumoPlugin);
|
||||||
14
minigames/tnt-run/Cargo.toml
Normal file
14
minigames/tnt-run/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "tnt-run"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
authors = ["Pumpkin Developer"]
|
||||||
|
description = "A complete TNT Run minigame for the Pumpkin Minecraft server"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
pumpkin-plugin-api = "0.1.0-dev"
|
||||||
|
tracing = "0.1"
|
||||||
422
minigames/tnt-run/src/lib.rs
Normal file
422
minigames/tnt-run/src/lib.rs
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
//! # TNT Run Minigame for Pumpkin
|
||||||
|
//!
|
||||||
|
//! A complete, runnable TNT Run minigame showcasing:
|
||||||
|
//! - State management (`Waiting`, `Active`, `Ended`).
|
||||||
|
//! - Commands: `/tntrun join`, `/tntrun leave`, `/tntrun start`, `/tntrun status`, `/tntrun reset`.
|
||||||
|
//! - Movement tracking with [`PlayerMoveEvent`]:
|
||||||
|
//! - Decaying blocks under players' feet with a delay.
|
||||||
|
//! - Detecting when a player falls below the arena elimination Y level.
|
||||||
|
//! - Automatic win condition check (last player standing).
|
||||||
|
//! - Clean floor regeneration when resetting.
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
collections::HashSet,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
};
|
||||||
|
|
||||||
|
use pumpkin_plugin_api::{
|
||||||
|
command::{Command, CommandError, CommandNode, CommandSender, ConsumedArgs},
|
||||||
|
commands::CommandHandler,
|
||||||
|
common::{BlockPos, Position},
|
||||||
|
events::{EventHandler, EventPriority, player::PlayerMoveEvent},
|
||||||
|
events_wit::PlayerMoveEventData,
|
||||||
|
scheduler::SchedulerExt,
|
||||||
|
world::BlockFlags,
|
||||||
|
Context, Plugin, PluginMetadata, register_plugin, Server,
|
||||||
|
text::TextComponent,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Arena spatial configuration.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ArenaConfig {
|
||||||
|
pub min_x: i32,
|
||||||
|
pub max_x: i32,
|
||||||
|
pub min_z: i32,
|
||||||
|
pub max_z: i32,
|
||||||
|
/// Y coordinates of the running floors (top to bottom)
|
||||||
|
pub floor_y_levels: Vec<i32>,
|
||||||
|
/// Any player falling below this Y level is eliminated
|
||||||
|
pub elimination_y: f64,
|
||||||
|
/// Spawn position where players start the game
|
||||||
|
pub spawn_pos: Position,
|
||||||
|
/// Lobby position where spectators / eliminated players wait
|
||||||
|
pub lobby_pos: Position,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ArenaConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
min_x: -15,
|
||||||
|
max_x: 15,
|
||||||
|
min_z: -15,
|
||||||
|
max_z: 15,
|
||||||
|
floor_y_levels: vec![100, 85, 70],
|
||||||
|
elimination_y: 60.0,
|
||||||
|
spawn_pos: (0.5, 101.0, 0.5),
|
||||||
|
lobby_pos: (0.5, 115.0, 0.5),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ArenaConfig {
|
||||||
|
pub fn is_inside_xz(&self, x: f64, z: f64) -> bool {
|
||||||
|
let ix = x.floor() as i32;
|
||||||
|
let iz = z.floor() as i32;
|
||||||
|
ix >= self.min_x && ix <= self.max_x && iz >= self.min_z && iz <= self.max_z
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lifecycle state of the TNT Run game.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum GameState {
|
||||||
|
Waiting,
|
||||||
|
Active,
|
||||||
|
Ended,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shared game session state.
|
||||||
|
pub struct GameSession {
|
||||||
|
pub state: GameState,
|
||||||
|
pub config: ArenaConfig,
|
||||||
|
pub queued_players: HashSet<String>,
|
||||||
|
pub alive_players: HashSet<String>,
|
||||||
|
pub recently_decaying: HashSet<(i32, i32, i32)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GameSession {
|
||||||
|
pub fn new(config: ArenaConfig) -> Self {
|
||||||
|
Self {
|
||||||
|
state: GameState::Waiting,
|
||||||
|
config,
|
||||||
|
queued_players: HashSet::new(),
|
||||||
|
alive_players: HashSet::new(),
|
||||||
|
recently_decaying: HashSet::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SESSION: Mutex<Option<Arc<Mutex<GameSession>>>> = Mutex::new(None);
|
||||||
|
|
||||||
|
fn get_session() -> Arc<Mutex<GameSession>> {
|
||||||
|
SESSION
|
||||||
|
.lock()
|
||||||
|
.unwrap_or_else(|e| e.into_inner())
|
||||||
|
.clone()
|
||||||
|
.expect("GameSession must be initialized in on_load")
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Commands: /tntrun <subcommand>
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct TntRunRootHandler;
|
||||||
|
impl CommandHandler for TntRunRootHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
_server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let help_text = "TNT Run Commands:\n\
|
||||||
|
/tntrun join - Join the game queue\n\
|
||||||
|
/tntrun leave - Leave the queue or game\n\
|
||||||
|
/tntrun start - Force start the game\n\
|
||||||
|
/tntrun status - View game status\n\
|
||||||
|
/tntrun reset - Regenerate arena floors";
|
||||||
|
sender.send_message(TextComponent::text(help_text));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TntRunJoinHandler;
|
||||||
|
impl CommandHandler for TntRunJoinHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let player_name = sender.get_name();
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
match session.state {
|
||||||
|
GameState::Active => {
|
||||||
|
sender.send_message(TextComponent::text("Game is already in progress! Please wait."));
|
||||||
|
}
|
||||||
|
GameState::Waiting | GameState::Ended => {
|
||||||
|
if session.queued_players.insert(player_name.clone()) {
|
||||||
|
let count = session.queued_players.len();
|
||||||
|
server.broadcast(&format!("{player_name} joined TNT Run! ({count} players queued)"));
|
||||||
|
sender.send_message(TextComponent::text("You joined the queue! Use /tntrun start when ready."));
|
||||||
|
} else {
|
||||||
|
sender.send_message(TextComponent::text("You are already in the queue!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TntRunLeaveHandler;
|
||||||
|
impl CommandHandler for TntRunLeaveHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let player_name = sender.get_name();
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
if session.queued_players.remove(&player_name) || session.alive_players.remove(&player_name) {
|
||||||
|
server.broadcast(&format!("{player_name} left TNT Run."));
|
||||||
|
sender.send_message(TextComponent::text("You left TNT Run."));
|
||||||
|
} else {
|
||||||
|
sender.send_message(TextComponent::text("You are not currently in a TNT Run game."));
|
||||||
|
}
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TntRunStartHandler;
|
||||||
|
impl CommandHandler for TntRunStartHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
if session.state == GameState::Active {
|
||||||
|
sender.send_message(TextComponent::text("Game is already running!"));
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no one is queued, queue the sender if it's a player
|
||||||
|
if session.queued_players.is_empty() {
|
||||||
|
session.queued_players.insert(sender.get_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
session.alive_players = session.queued_players.clone();
|
||||||
|
session.state = GameState::Active;
|
||||||
|
session.recently_decaying.clear();
|
||||||
|
|
||||||
|
let count = session.alive_players.len();
|
||||||
|
server.broadcast(&format!("TNT Run has STARTED with {count} players! Keep running!"));
|
||||||
|
|
||||||
|
// Teleport all alive players to the spawn position
|
||||||
|
let spawn = session.config.spawn_pos;
|
||||||
|
for player_name in &session.alive_players {
|
||||||
|
if let Some(player) = server.get_player_by_name(player_name) {
|
||||||
|
let world = player.get_world();
|
||||||
|
player.teleport(spawn, Some(0.0), Some(0.0), world);
|
||||||
|
player.show_title(TextComponent::text("TNT RUN!"));
|
||||||
|
player.show_subtitle(TextComponent::text("Don't stop moving!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TntRunStatusHandler;
|
||||||
|
impl CommandHandler for TntRunStatusHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
_server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let session_arc = get_session();
|
||||||
|
let session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
let status_msg = match session.state {
|
||||||
|
GameState::Waiting => format!("TNT Run: WAITING ({} players queued)", session.queued_players.len()),
|
||||||
|
GameState::Active => format!(
|
||||||
|
"TNT Run: ACTIVE ({} alive: {:?})",
|
||||||
|
session.alive_players.len(),
|
||||||
|
session.alive_players
|
||||||
|
),
|
||||||
|
GameState::Ended => "TNT Run: ENDED (Use /tntrun reset or /tntrun start)".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
sender.send_message(TextComponent::text(&status_msg));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TntRunResetHandler;
|
||||||
|
impl CommandHandler for TntRunResetHandler {
|
||||||
|
fn handle(
|
||||||
|
&self,
|
||||||
|
sender: CommandSender,
|
||||||
|
server: Server,
|
||||||
|
_args: ConsumedArgs,
|
||||||
|
) -> Result<i32, CommandError> {
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
session.state = GameState::Waiting;
|
||||||
|
session.alive_players.clear();
|
||||||
|
session.recently_decaying.clear();
|
||||||
|
|
||||||
|
// Regenerate floors using the first available world
|
||||||
|
let worlds = server.get_all_worlds();
|
||||||
|
if let Some(world) = worlds.first() {
|
||||||
|
let flags = BlockFlags::NOTIFY_LISTENERS | BlockFlags::NOTIFY_NEIGHBORS;
|
||||||
|
for &y in &session.config.floor_y_levels {
|
||||||
|
for x in session.config.min_x..=session.config.max_x {
|
||||||
|
for z in session.config.min_z..=session.config.max_z {
|
||||||
|
let pos = BlockPos { x, y, z };
|
||||||
|
world.set_block_by_name(pos, "minecraft:sand", flags);
|
||||||
|
let tnt_pos = BlockPos { x, y: y - 1, z };
|
||||||
|
world.set_block_by_name(tnt_pos, "minecraft:tnt", flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server.broadcast("TNT Run arena has been regenerated and reset!");
|
||||||
|
sender.send_message(TextComponent::text("Arena reset complete!"));
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Movement & Decay Event Listener
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct TntRunMoveListener;
|
||||||
|
|
||||||
|
impl EventHandler<PlayerMoveEvent> for TntRunMoveListener {
|
||||||
|
fn handle(&self, server: Server, event: PlayerMoveEventData) -> PlayerMoveEventData {
|
||||||
|
let player_name = event.player.get_name();
|
||||||
|
let session_arc = get_session();
|
||||||
|
let mut session = session_arc.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
|
||||||
|
// Only process movement if game is active and player is an alive participant
|
||||||
|
if session.state != GameState::Active || !session.alive_players.contains(&player_name) {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
let to = &event.to_position;
|
||||||
|
|
||||||
|
// 1. Elimination Check: player fell below the elimination threshold
|
||||||
|
if to.1 < session.config.elimination_y {
|
||||||
|
session.alive_players.remove(&player_name);
|
||||||
|
server.broadcast(&format!("{player_name} fell into the void and was ELIMINATED!"));
|
||||||
|
|
||||||
|
// Teleport eliminated player back to lobby
|
||||||
|
let lobby = session.config.lobby_pos;
|
||||||
|
let world = event.player.get_world();
|
||||||
|
event.player.teleport(lobby, Some(0.0), Some(0.0), world);
|
||||||
|
event.player.show_title(TextComponent::text("ELIMINATED!"));
|
||||||
|
|
||||||
|
// 2. Win Condition Check
|
||||||
|
if session.alive_players.len() == 1 {
|
||||||
|
let winner_name = session.alive_players.iter().next().cloned().unwrap();
|
||||||
|
server.broadcast(&format!("VICTORY! {winner_name} is the last player standing and WINS TNT Run!"));
|
||||||
|
if let Some(winner) = server.get_player_by_name(&winner_name) {
|
||||||
|
winner.show_title(TextComponent::text("VICTORY!"));
|
||||||
|
winner.show_subtitle(TextComponent::text("You won TNT Run!"));
|
||||||
|
}
|
||||||
|
session.state = GameState::Ended;
|
||||||
|
} else if session.alive_players.is_empty() {
|
||||||
|
server.broadcast("Game Over! No players remaining.");
|
||||||
|
session.state = GameState::Ended;
|
||||||
|
}
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Block Decay Mechanic: if inside arena XZ, decay the block under feet
|
||||||
|
if session.config.is_inside_xz(to.0, to.2) {
|
||||||
|
let bx = to.0.floor() as i32;
|
||||||
|
let by = (to.1 - 0.2).floor() as i32;
|
||||||
|
let bz = to.2.floor() as i32;
|
||||||
|
|
||||||
|
// Only trigger decay if standing on one of the designated floor Y levels
|
||||||
|
if session.config.floor_y_levels.contains(&by) && session.recently_decaying.insert((bx, by, bz)) {
|
||||||
|
let world = event.player.get_world();
|
||||||
|
let flags = BlockFlags::NOTIFY_LISTENERS | BlockFlags::NOTIFY_NEIGHBORS;
|
||||||
|
|
||||||
|
// Turn sand and underlying TNT to air after delay
|
||||||
|
let session_clone = Arc::clone(&session_arc);
|
||||||
|
server.schedule_delayed_task(8, move |_| {
|
||||||
|
let pos = BlockPos { x: bx, y: by, z: bz };
|
||||||
|
let tnt_pos = BlockPos { x: bx, y: by - 1, z: bz };
|
||||||
|
world.set_block_by_name(pos, "minecraft:air", flags);
|
||||||
|
world.set_block_by_name(tnt_pos, "minecraft:air", flags);
|
||||||
|
|
||||||
|
if let Ok(mut s) = session_clone.lock() {
|
||||||
|
s.recently_decaying.remove(&(bx, by, bz));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Plugin Lifecycle
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub struct TntRunPlugin;
|
||||||
|
|
||||||
|
impl Plugin for TntRunPlugin {
|
||||||
|
fn new() -> Self {
|
||||||
|
TntRunPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&self) -> PluginMetadata {
|
||||||
|
PluginMetadata {
|
||||||
|
name: "tnt-run".into(),
|
||||||
|
version: env!("CARGO_PKG_VERSION").into(),
|
||||||
|
authors: vec!["Pumpkin Developer".into()],
|
||||||
|
description: "A complete TNT Run minigame for Pumpkin Minecraft server.".into(),
|
||||||
|
dependencies: vec![],
|
||||||
|
permissions: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_load(&self, context: Context) -> Result<(), String> {
|
||||||
|
let config = ArenaConfig::default();
|
||||||
|
let session = Arc::new(Mutex::new(GameSession::new(config)));
|
||||||
|
*SESSION.lock().unwrap_or_else(|e| e.into_inner()) = Some(session);
|
||||||
|
|
||||||
|
// Register /tntrun command tree
|
||||||
|
let names = ["tntrun".to_string(), "tr".to_string()];
|
||||||
|
let command = Command::new(&names, "TNT Run minigame management command")
|
||||||
|
.then(CommandNode::literal("join").execute(TntRunJoinHandler))
|
||||||
|
.then(CommandNode::literal("leave").execute(TntRunLeaveHandler))
|
||||||
|
.then(CommandNode::literal("start").execute(TntRunStartHandler))
|
||||||
|
.then(CommandNode::literal("status").execute(TntRunStatusHandler))
|
||||||
|
.then(CommandNode::literal("reset").execute(TntRunResetHandler))
|
||||||
|
.execute(TntRunRootHandler);
|
||||||
|
|
||||||
|
context.register_command(command, "pumpkin.command.tntrun");
|
||||||
|
|
||||||
|
// Register PlayerMoveEvent listener
|
||||||
|
context.register_event_handler(
|
||||||
|
TntRunMoveListener,
|
||||||
|
EventPriority::Normal,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
tracing::info!("TNT Run minigame plugin successfully loaded!");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_unload(&self, _context: Context) -> Result<(), String> {
|
||||||
|
tracing::info!("TNT Run plugin unloaded.");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register_plugin!(TntRunPlugin);
|
||||||
Loading…
Reference in New Issue
Block a user