premier commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
[build]
|
||||
target = "wasm32-wasip2"
|
||||
Generated
+640
@@ -0,0 +1,640 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||
|
||||
[[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 = "bedwars_pumpkin"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"pumpkin-plugin-api",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[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 = "getrandom"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[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.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
||||
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 = "libc"
|
||||
version = "0.2.186"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
||||
|
||||
[[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.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8"
|
||||
|
||||
[[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 = "ppv-lite86"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pumpkin-plugin-api"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin#30303a8cbd9c3dedac4ff13abd1de64537c6203b"
|
||||
dependencies = [
|
||||
"postcard",
|
||||
"serde_json",
|
||||
"tracing",
|
||||
"tracing-serde-structured",
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
||||
|
||||
[[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.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.150"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.34+deprecated"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"unsafe-libyaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
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.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[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",
|
||||
]
|
||||
|
||||
[[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 = "unicode-xid"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.247.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30b6733b8b91d010a6ac5b0fb237dc46a19650bc4c67db66857e2e787d437204"
|
||||
dependencies = [
|
||||
"leb128fmt",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-metadata"
|
||||
version = "0.247.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "665fe59e56cc9b419ca6fcca56673e3421d1a5011e3b65caf6b726fd9e041d10"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indexmap",
|
||||
"wasm-encoder",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.247.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"hashbrown",
|
||||
"indexmap",
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.57.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
|
||||
dependencies = [
|
||||
"wit-bindgen-rust-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-core"
|
||||
version = "0.57.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02dee27a2dc20d1008016c742ec9fc6ea498492994ba3750be7454cbc97ff04c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"wit-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust"
|
||||
version = "0.57.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5007dae772945b7a5003d69d90a3a4a78929d41f19d004e980c4259a6af4484"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"indexmap",
|
||||
"prettyplease",
|
||||
"syn",
|
||||
"wasm-metadata",
|
||||
"wit-bindgen-core",
|
||||
"wit-component",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust-macro"
|
||||
version = "0.57.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af9237d678e3513ad24e96fe98beacdc0db6405284ba2a2400418cf0d42caa89"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wit-bindgen-core",
|
||||
"wit-bindgen-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-component"
|
||||
version = "0.247.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d567162a6b9843080e5e0053f696623ff694bae8ae017c9ec536d1873bbe3d8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
"indexmap",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"wasm-encoder",
|
||||
"wasm-metadata",
|
||||
"wasmparser",
|
||||
"wit-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-parser"
|
||||
version = "0.247.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ffe4064318cdf3c08cb99343b44c039fcefe61ccdf58aa9975285f13d74d1fc"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"hashbrown",
|
||||
"id-arena",
|
||||
"indexmap",
|
||||
"log",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"unicode-xid",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "bedwars_pumpkin"
|
||||
version = "1.0.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
pumpkin-plugin-api = { git = "https://github.com/Pumpkin-MC/Pumpkin", package = "pumpkin-plugin-api" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_yaml = "0.9"
|
||||
tracing = "0.1"
|
||||
rand = "0.8"
|
||||
@@ -0,0 +1,36 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct BlockPos {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub z: i32,
|
||||
}
|
||||
|
||||
pub struct ArenaManager {
|
||||
pub player_placed_blocks: HashSet<BlockPos>,
|
||||
}
|
||||
|
||||
impl ArenaManager {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
player_placed_blocks: HashSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn track_block(&mut self, pos: BlockPos) {
|
||||
self.player_placed_blocks.insert(pos);
|
||||
}
|
||||
|
||||
pub fn untrack_block(&mut self, pos: &BlockPos) -> bool {
|
||||
self.player_placed_blocks.remove(pos)
|
||||
}
|
||||
|
||||
pub fn is_player_placed(&self, pos: &BlockPos) -> bool {
|
||||
self.player_placed_blocks.contains(pos)
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.player_placed_blocks.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
use crate::config::{BedwarsConfig, Loc, TeamConfig, GeneratorConfig};
|
||||
use crate::team::BedwarsTeam;
|
||||
use crate::game::GameManager;
|
||||
|
||||
pub enum BedwarsCommand {
|
||||
SetLobby,
|
||||
SetSpawn { team: BedwarsTeam },
|
||||
SetBed { team: BedwarsTeam },
|
||||
SetShop { team: BedwarsTeam },
|
||||
SetUpgrades { team: BedwarsTeam },
|
||||
SetGenerator { team: BedwarsTeam },
|
||||
SetEnderchest { team: BedwarsTeam },
|
||||
AddGenerator { gen_type: String },
|
||||
Save,
|
||||
Start,
|
||||
Help,
|
||||
}
|
||||
|
||||
impl BedwarsCommand {
|
||||
pub fn parse(args: &[String]) -> Result<Self, String> {
|
||||
if args.is_empty() {
|
||||
return Ok(Self::Help);
|
||||
}
|
||||
|
||||
match args[0].to_lowercase().as_str() {
|
||||
"setlobby" => Ok(Self::SetLobby),
|
||||
"setspawn" => {
|
||||
if args.len() < 2 {
|
||||
return Err("Usage: /bw setspawn <red|blue|purple|yellow>".to_string());
|
||||
}
|
||||
let team = BedwarsTeam::from_str(&args[1]).ok_or("Invalid team name")?;
|
||||
Ok(Self::SetSpawn { team })
|
||||
}
|
||||
"setbed" => {
|
||||
if args.len() < 2 {
|
||||
return Err("Usage: /bw setbed <red|blue|purple|yellow>".to_string());
|
||||
}
|
||||
let team = BedwarsTeam::from_str(&args[1]).ok_or("Invalid team name")?;
|
||||
Ok(Self::SetBed { team })
|
||||
}
|
||||
"setshop" => {
|
||||
if args.len() < 2 {
|
||||
return Err("Usage: /bw setshop <red|blue|purple|yellow>".to_string());
|
||||
}
|
||||
let team = BedwarsTeam::from_str(&args[1]).ok_or("Invalid team name")?;
|
||||
Ok(Self::SetShop { team })
|
||||
}
|
||||
"setupgrades" => {
|
||||
if args.len() < 2 {
|
||||
return Err("Usage: /bw setupgrades <red|blue|purple|yellow>".to_string());
|
||||
}
|
||||
let team = BedwarsTeam::from_str(&args[1]).ok_or("Invalid team name")?;
|
||||
Ok(Self::SetUpgrades { team })
|
||||
}
|
||||
"setgenerator" => {
|
||||
if args.len() < 2 {
|
||||
return Err("Usage: /bw setgenerator <red|blue|purple|yellow>".to_string());
|
||||
}
|
||||
let team = BedwarsTeam::from_str(&args[1]).ok_or("Invalid team name")?;
|
||||
Ok(Self::SetGenerator { team })
|
||||
}
|
||||
"setenderchest" => {
|
||||
if args.len() < 2 {
|
||||
return Err("Usage: /bw setenderchest <red|blue|purple|yellow>".to_string());
|
||||
}
|
||||
let team = BedwarsTeam::from_str(&args[1]).ok_or("Invalid team name")?;
|
||||
Ok(Self::SetEnderchest { team })
|
||||
}
|
||||
"addgenerator" => {
|
||||
if args.len() < 2 {
|
||||
return Err("Usage: /bw addgenerator <diamond|emerald>".to_string());
|
||||
}
|
||||
let gen_type = args[1].to_lowercase();
|
||||
if gen_type != "diamond" && gen_type != "emerald" {
|
||||
return Err("Generator type must be 'diamond' or 'emerald'".to_string());
|
||||
}
|
||||
Ok(Self::AddGenerator { gen_type })
|
||||
}
|
||||
"save" => Ok(Self::Save),
|
||||
"start" => Ok(Self::Start),
|
||||
"help" => Ok(Self::Help),
|
||||
_ => Err("Unknown command. Type /bw help for options.".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute(
|
||||
&self,
|
||||
config: &mut BedwarsConfig,
|
||||
game_manager: &mut GameManager,
|
||||
player_loc: Loc,
|
||||
target_block_loc: Option<Loc>,
|
||||
) -> Result<String, String> {
|
||||
match self {
|
||||
Self::SetLobby => {
|
||||
config.locations.lobby = player_loc;
|
||||
Ok("Lobby location updated in config".to_string())
|
||||
}
|
||||
Self::SetSpawn { team } => {
|
||||
let team_name = team.get_name().to_lowercase();
|
||||
let team_conf = config.locations.teams.entry(team_name.clone()).or_insert_with(|| TeamConfig {
|
||||
enabled: true,
|
||||
spawn: player_loc.clone(),
|
||||
bed: player_loc.clone(),
|
||||
generator: player_loc.clone(),
|
||||
shop: player_loc.clone(),
|
||||
upgrades: player_loc.clone(),
|
||||
enderchest: player_loc.clone(),
|
||||
});
|
||||
team_conf.spawn = player_loc;
|
||||
team_conf.enabled = true;
|
||||
game_manager.enable_team(*team);
|
||||
Ok(format!("Spawn for team {} set and enabled", team.get_name()))
|
||||
}
|
||||
Self::SetBed { team } => {
|
||||
let block_loc = target_block_loc.ok_or("You must look at a bed block")?;
|
||||
let team_name = team.get_name().to_lowercase();
|
||||
if let Some(t_conf) = config.locations.teams.get_mut(&team_name) {
|
||||
t_conf.bed = block_loc;
|
||||
Ok(format!("Bed for team {} set", team.get_name()))
|
||||
} else {
|
||||
Err("Team not configured yet. Set spawn first.".to_string())
|
||||
}
|
||||
}
|
||||
Self::SetShop { team } => {
|
||||
let team_name = team.get_name().to_lowercase();
|
||||
if let Some(t_conf) = config.locations.teams.get_mut(&team_name) {
|
||||
t_conf.shop = player_loc;
|
||||
Ok(format!("Shop for team {} set", team.get_name()))
|
||||
} else {
|
||||
Err("Team not configured yet. Set spawn first.".to_string())
|
||||
}
|
||||
}
|
||||
Self::SetUpgrades { team } => {
|
||||
let team_name = team.get_name().to_lowercase();
|
||||
if let Some(t_conf) = config.locations.teams.get_mut(&team_name) {
|
||||
t_conf.upgrades = player_loc;
|
||||
Ok(format!("Upgrades for team {} set", team.get_name()))
|
||||
} else {
|
||||
Err("Team not configured yet. Set spawn first.".to_string())
|
||||
}
|
||||
}
|
||||
Self::SetGenerator { team } => {
|
||||
let team_name = team.get_name().to_lowercase();
|
||||
if let Some(t_conf) = config.locations.teams.get_mut(&team_name) {
|
||||
t_conf.generator = player_loc;
|
||||
Ok(format!("Generator for team {} set", team.get_name()))
|
||||
} else {
|
||||
Err("Team not configured yet. Set spawn first.".to_string())
|
||||
}
|
||||
}
|
||||
Self::SetEnderchest { team } => {
|
||||
let team_name = team.get_name().to_lowercase();
|
||||
if let Some(t_conf) = config.locations.teams.get_mut(&team_name) {
|
||||
t_conf.enderchest = player_loc;
|
||||
Ok(format!("Ender Chest for team {} set", team.get_name()))
|
||||
} else {
|
||||
Err("Team not configured yet. Set spawn first.".to_string())
|
||||
}
|
||||
}
|
||||
Self::AddGenerator { gen_type } => {
|
||||
config.locations.generators.push(GeneratorConfig {
|
||||
x: player_loc.x,
|
||||
y: player_loc.y,
|
||||
z: player_loc.z,
|
||||
generator_type: gen_type.to_uppercase(),
|
||||
});
|
||||
Ok(format!("Added a {} generator at your location", gen_type.to_uppercase()))
|
||||
}
|
||||
Self::Save => {
|
||||
// Return string representation to write to file
|
||||
Ok("Config ready to save".to_string())
|
||||
}
|
||||
Self::Start => {
|
||||
game_manager.start_game()?;
|
||||
Ok("Match starting now!".to_string())
|
||||
}
|
||||
Self::Help => {
|
||||
let mut help = String::new();
|
||||
help.push_str("§d§m================ §b§lBEDWARS SETUP (RUST) §d§m================\n");
|
||||
help.push_str("§d/bw setlobby §7- Set waiting lobby coordinate\n");
|
||||
help.push_str("§d/bw setspawn <team> §7- Set team player spawn point\n");
|
||||
help.push_str("§d/bw setbed <team> §7- Register team bed (look at block)\n");
|
||||
help.push_str("§d/bw setshop <team> §7- Set shop NPC position\n");
|
||||
help.push_str("§d/bw setupgrades <team> §7- Set upgrades NPC position\n");
|
||||
help.push_str("§d/bw setgenerator <team> §7- Set base spawner location\n");
|
||||
help.push_str("§d/bw setenderchest <team> §7- Set team Ender Chest\n");
|
||||
help.push_str("§d/bw addgenerator <diamond|emerald> §7- Add generator\n");
|
||||
help.push_str("§d/bw save §7- Save config file\n");
|
||||
help.push_str("§d/bw start §7- Force start game immediately\n");
|
||||
help.push_str("§d§m================================================\n");
|
||||
Ok(help)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Loc {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
pub z: f64,
|
||||
pub yaw: Option<f32>,
|
||||
pub pitch: Option<f32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct TeamConfig {
|
||||
pub enabled: bool,
|
||||
pub spawn: Loc,
|
||||
pub bed: Loc,
|
||||
pub generator: Loc,
|
||||
pub shop: Loc,
|
||||
pub upgrades: Loc,
|
||||
pub enderchest: Loc,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct GeneratorConfig {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
pub z: f64,
|
||||
#[serde(rename = "type")]
|
||||
pub generator_type: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct RatesConfig {
|
||||
pub iron: u32,
|
||||
pub gold: u32,
|
||||
pub diamond: u32,
|
||||
pub emerald: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct LocationsConfig {
|
||||
pub lobby: Loc,
|
||||
pub teams: HashMap<String, TeamConfig>,
|
||||
pub generators: Vec<GeneratorConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct BedwarsConfig {
|
||||
#[serde(rename = "world-name")]
|
||||
pub world_name: String,
|
||||
#[serde(rename = "lobby-server")]
|
||||
pub lobby_server: String,
|
||||
#[serde(rename = "min-players")]
|
||||
pub min_players: u32,
|
||||
#[serde(rename = "countdown-seconds")]
|
||||
pub countdown_seconds: u32,
|
||||
pub rates: RatesConfig,
|
||||
pub locations: LocationsConfig,
|
||||
}
|
||||
|
||||
impl BedwarsConfig {
|
||||
pub fn load_from_str(content: &str) -> Result<Self, serde_yaml::Error> {
|
||||
serde_yaml::from_str(content)
|
||||
}
|
||||
|
||||
pub fn save_to_string(&self) -> Result<String, serde_yaml::Error> {
|
||||
serde_yaml::to_string(self)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
use crate::config::Loc;
|
||||
use crate::team::BedwarsTeam;
|
||||
use crate::game::GameManager;
|
||||
use crate::arena::{ArenaManager, BlockPos};
|
||||
use crate::state::GameState;
|
||||
|
||||
pub struct BedwarsEvents;
|
||||
|
||||
impl BedwarsEvents {
|
||||
pub fn handle_block_place(
|
||||
arena: &mut ArenaManager,
|
||||
pos: BlockPos,
|
||||
block_type: &str,
|
||||
is_spectator: bool,
|
||||
) -> Result<Option<String>, &'static str> {
|
||||
if is_spectator {
|
||||
return Err("Spectators cannot place blocks");
|
||||
}
|
||||
|
||||
if block_type == "minecraft:tnt" {
|
||||
// Return command to spawn primed TNT and bypass block placement
|
||||
Ok(Some("spawn_primed_tnt".to_string()))
|
||||
} else {
|
||||
arena.track_block(pos);
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_block_break(
|
||||
arena: &mut ArenaManager,
|
||||
game_manager: &mut GameManager,
|
||||
pos: BlockPos,
|
||||
block_type: &str,
|
||||
breaker_uuid: &str,
|
||||
) -> Result<Option<BedwarsTeam>, &'static str> {
|
||||
let breaker = game_manager.players.get(breaker_uuid).ok_or("Player not found")?;
|
||||
if breaker.is_spectator {
|
||||
return Err("Spectators cannot break blocks");
|
||||
}
|
||||
|
||||
// 1. Bed Break logic
|
||||
if block_type.ends_with("_bed") {
|
||||
let breaker_team = breaker.team.ok_or("You are not on a team")?;
|
||||
|
||||
// Search config locations for which team's bed is broken
|
||||
let mut target_team = None;
|
||||
for team_state in game_manager.teams.values() {
|
||||
if team_state.enabled && team_state.has_bed {
|
||||
// In host adapter, we would check block coordinate equality.
|
||||
// For logic module, we match block team color to block type.
|
||||
let bed_mat = team_state.team.get_bed_material();
|
||||
if block_type == format!("minecraft:{}", bed_mat) {
|
||||
target_team = Some(team_state.team);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(broken_team) = target_team {
|
||||
if breaker_team == broken_team {
|
||||
return Err("You cannot break your own bed!");
|
||||
}
|
||||
|
||||
game_manager.set_bed_broken(broken_team);
|
||||
if let Some(p) = game_manager.players.get_mut(breaker_uuid) {
|
||||
p.beds_broken += 1;
|
||||
}
|
||||
return Ok(Some(broken_team));
|
||||
} else {
|
||||
return Err("This bed block is not registered to a team");
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Standard Block Break logic
|
||||
if arena.is_player_placed(&pos) {
|
||||
arena.untrack_block(&pos);
|
||||
Ok(None)
|
||||
} else {
|
||||
Err("You can only break blocks placed by players!")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_void_check(
|
||||
game_manager: &mut GameManager,
|
||||
uuid: &str,
|
||||
y_coord: f64,
|
||||
) -> bool {
|
||||
if game_manager.state != GameState::Playing {
|
||||
return false;
|
||||
}
|
||||
|
||||
if let Some(player) = game_manager.players.get(uuid) {
|
||||
if player.is_spectator {
|
||||
return false;
|
||||
}
|
||||
|
||||
if y_coord <= -20.0 {
|
||||
game_manager.handle_death(uuid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn handle_pickup_resource(
|
||||
item_type: &str,
|
||||
is_generator_spawned: bool,
|
||||
picker_uuid: &str,
|
||||
game_manager: &GameManager,
|
||||
teammate_distances: Vec<(String, f64)>, // uuid -> distance squared
|
||||
) -> Vec<(String, String, u32)> {
|
||||
// Vec of (teammate_uuid, item_type, amount) to replicate
|
||||
|
||||
// Critical dupe check - only replicate resource drops spawned by a generator
|
||||
if !is_generator_spawned {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
if item_type != "minecraft:iron_ingot" &&
|
||||
item_type != "minecraft:gold_ingot" &&
|
||||
item_type != "minecraft:diamond" &&
|
||||
item_type != "minecraft:emerald" {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
let picker = match game_manager.players.get(picker_uuid) {
|
||||
Some(p) => p,
|
||||
None => return Vec::new(),
|
||||
};
|
||||
|
||||
let picker_team = match picker.team {
|
||||
Some(t) => t,
|
||||
None => return Vec::new(),
|
||||
};
|
||||
|
||||
let mut replicate_spawns = Vec::new();
|
||||
|
||||
for (other_uuid, distance_sq) in teammate_distances {
|
||||
if other_uuid == picker_uuid {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(other) = game_manager.players.get(&other_uuid) {
|
||||
if !other.is_spectator && other.team == Some(picker_team) {
|
||||
// Check if teammate is within 3.5 blocks (12.25 blocks squared)
|
||||
if distance_sq <= 12.25 {
|
||||
replicate_spawns.push((other_uuid, item_type.to_string(), 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
replicate_spawns
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::state::GameState;
|
||||
use crate::team::BedwarsTeam;
|
||||
use crate::generator::Generator;
|
||||
use crate::arena::ArenaManager;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PlayerState {
|
||||
pub uuid: String,
|
||||
pub name: String,
|
||||
pub team: Option<BedwarsTeam>,
|
||||
pub is_spectator: bool,
|
||||
pub kills: u32,
|
||||
pub deaths: u32,
|
||||
pub beds_broken: u32,
|
||||
pub respawn_timer: Option<u32>, // seconds remaining
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TeamState {
|
||||
pub team: BedwarsTeam,
|
||||
pub has_bed: bool,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
pub struct GameManager {
|
||||
pub state: GameState,
|
||||
pub players: HashMap<String, PlayerState>,
|
||||
pub teams: HashMap<BedwarsTeam, TeamState>,
|
||||
pub countdown: Option<u32>,
|
||||
pub generators: Vec<Generator>,
|
||||
pub arena: ArenaManager,
|
||||
pub min_players: u32,
|
||||
}
|
||||
|
||||
impl GameManager {
|
||||
pub fn new(min_players: u32, countdown_seconds: u32) -> Self {
|
||||
let mut teams = HashMap::new();
|
||||
for team in &[BedwarsTeam::Red, BedwarsTeam::Blue, BedwarsTeam::Purple, BedwarsTeam::Yellow] {
|
||||
teams.insert(*team, TeamState {
|
||||
team: *team,
|
||||
has_bed: true,
|
||||
enabled: false,
|
||||
});
|
||||
}
|
||||
|
||||
Self {
|
||||
state: GameState::Lobby,
|
||||
players: HashMap::new(),
|
||||
teams,
|
||||
countdown: Some(countdown_seconds),
|
||||
generators: Vec::new(),
|
||||
arena: ArenaManager::new(),
|
||||
min_players,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn join_player(&mut self, uuid: &str, name: &str) {
|
||||
let state = PlayerState {
|
||||
uuid: uuid.to_string(),
|
||||
name: name.to_string(),
|
||||
team: None,
|
||||
is_spectator: false,
|
||||
kills: 0,
|
||||
deaths: 0,
|
||||
beds_broken: 0,
|
||||
respawn_timer: None,
|
||||
};
|
||||
self.players.insert(uuid.to_string(), state);
|
||||
}
|
||||
|
||||
pub fn quit_player(&mut self, uuid: &str) {
|
||||
self.players.remove(uuid);
|
||||
if self.state == GameState::Playing {
|
||||
self.check_winner();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enable_team(&mut self, team: BedwarsTeam) {
|
||||
if let Some(state) = self.teams.get_mut(&team) {
|
||||
state.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_game(&mut self) -> Result<(), &'static str> {
|
||||
let enabled_teams: Vec<BedwarsTeam> = self.teams.values()
|
||||
.filter(|t| t.enabled)
|
||||
.map(|t| t.team)
|
||||
.collect();
|
||||
|
||||
if enabled_teams.len() < 2 {
|
||||
return Err("At least two teams must be enabled to start the game");
|
||||
}
|
||||
|
||||
// Assign players to enabled teams evenly
|
||||
let mut team_idx = 0;
|
||||
for player in self.players.values_mut() {
|
||||
if player.is_spectator {
|
||||
continue;
|
||||
}
|
||||
let team = enabled_teams[team_idx];
|
||||
player.team = Some(team);
|
||||
team_idx = (team_idx + 1) % enabled_teams.len();
|
||||
}
|
||||
|
||||
self.state = GameState::Playing;
|
||||
self.countdown = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_death(&mut self, uuid: &str) {
|
||||
if let Some(player) = self.players.get_mut(uuid) {
|
||||
player.deaths += 1;
|
||||
if let Some(team) = player.team {
|
||||
let has_bed = self.teams.get(&team).map(|t| t.has_bed).unwrap_or(false);
|
||||
if has_bed {
|
||||
player.respawn_timer = Some(5); // 5 seconds respawn queue
|
||||
} else {
|
||||
player.is_spectator = true;
|
||||
player.respawn_timer = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.check_winner();
|
||||
}
|
||||
|
||||
pub fn tick_game(&mut self) -> Vec<(String, String)> {
|
||||
let mut events = Vec::new();
|
||||
|
||||
// Handle Lobby countdown
|
||||
if self.state == GameState::Lobby {
|
||||
if let Some(ref mut time) = self.countdown {
|
||||
if self.players.len() as u32 >= self.min_players {
|
||||
if *time > 0 {
|
||||
*time -= 1;
|
||||
if *time == 0 {
|
||||
if let Err(e) = self.start_game() {
|
||||
tracing::error!("Failed to start game: {}", e);
|
||||
self.countdown = Some(10); // retry in 10s
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Reset countdown if player count drops below min_players
|
||||
*time = 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Playing respawn timers
|
||||
if self.state == GameState::Playing {
|
||||
for player in self.players.values_mut() {
|
||||
if let Some(ref mut time) = player.respawn_timer {
|
||||
if *time > 0 {
|
||||
*time -= 1;
|
||||
if *time == 0 {
|
||||
player.respawn_timer = None;
|
||||
events.push((player.uuid.clone(), "respawn".to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
events
|
||||
}
|
||||
|
||||
pub fn set_bed_broken(&mut self, team: BedwarsTeam) {
|
||||
if let Some(state) = self.teams.get_mut(&team) {
|
||||
state.has_bed = false;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_winner(&mut self) -> Option<BedwarsTeam> {
|
||||
if self.state != GameState::Playing {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Find teams that still have active, non-spectator players
|
||||
let mut active_teams = HashMap::new();
|
||||
for player in self.players.values() {
|
||||
if !player.is_spectator {
|
||||
if let Some(team) = player.team {
|
||||
*active_teams.entry(team).or_insert(0) += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if active_teams.len() == 1 {
|
||||
let winning_team = *active_teams.keys().next().unwrap();
|
||||
self.state = GameState::Ending;
|
||||
Some(winning_team)
|
||||
} else if active_teams.is_empty() {
|
||||
// Tie or no players left
|
||||
self.state = GameState::Ending;
|
||||
None
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
use crate::config::Loc;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum GeneratorType {
|
||||
IronGold,
|
||||
Diamond,
|
||||
Emerald,
|
||||
}
|
||||
|
||||
pub struct Generator {
|
||||
pub location: Loc,
|
||||
pub gen_type: GeneratorType,
|
||||
pub ticks_until_spawn: i32,
|
||||
pub max_spawn_ticks: i32,
|
||||
pub upgrade_level: u32,
|
||||
}
|
||||
|
||||
impl Generator {
|
||||
pub fn new(location: Loc, gen_type: GeneratorType, max_spawn_ticks: i32) -> Self {
|
||||
Self {
|
||||
location,
|
||||
gen_type,
|
||||
ticks_until_spawn: max_spawn_ticks,
|
||||
max_spawn_ticks,
|
||||
upgrade_level: 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(&mut self, random_roll: f64) -> Option<Vec<&'static str>> {
|
||||
self.ticks_until_spawn -= 1;
|
||||
if self.ticks_until_spawn <= 0 {
|
||||
let mut spawned = Vec::new();
|
||||
match self.gen_type {
|
||||
GeneratorType::IronGold => {
|
||||
spawned.push("minecraft:iron_ingot");
|
||||
// Gold at 1/4 rate, modified by upgrade
|
||||
if random_roll < (0.25 * self.upgrade_level as f64) {
|
||||
spawned.push("minecraft:gold_ingot");
|
||||
}
|
||||
self.ticks_until_spawn = std::cmp::max(5, self.max_spawn_ticks - (self.upgrade_level as i32 - 1) * 3);
|
||||
}
|
||||
GeneratorType::Diamond => {
|
||||
spawned.push("minecraft:diamond");
|
||||
self.ticks_until_spawn = self.max_spawn_ticks;
|
||||
}
|
||||
GeneratorType::Emerald => {
|
||||
spawned.push("minecraft:emerald");
|
||||
self.ticks_until_spawn = self.max_spawn_ticks;
|
||||
}
|
||||
}
|
||||
Some(spawned)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GeneratorManager {
|
||||
pub generators: Vec<Generator>,
|
||||
}
|
||||
|
||||
impl GeneratorManager {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
generators: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick_all(&mut self) -> Vec<(Loc, Vec<&'static str>)> {
|
||||
let mut spawns = Vec::new();
|
||||
for gen in &mut self.generators {
|
||||
let roll = rand::random::<f64>(); // Bypassed in tests or run directly
|
||||
if let Some(items) = gen.tick(roll) {
|
||||
spawns.push((gen.location.clone(), items));
|
||||
}
|
||||
}
|
||||
spawns
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
pub mod config;
|
||||
pub mod team;
|
||||
pub mod state;
|
||||
pub mod generator;
|
||||
pub mod arena;
|
||||
pub mod shop;
|
||||
pub mod game;
|
||||
pub mod commands;
|
||||
pub mod events;
|
||||
|
||||
use pumpkin_plugin_api::{Context, Plugin, PluginMetadata};
|
||||
use tracing::info;
|
||||
|
||||
pub struct BedwarsPlugin {
|
||||
pub game_manager: Option<game::GameManager>,
|
||||
pub config: Option<config::BedwarsConfig>,
|
||||
}
|
||||
|
||||
impl Plugin for BedwarsPlugin {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
game_manager: None,
|
||||
config: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn metadata(&self) -> PluginMetadata {
|
||||
PluginMetadata {
|
||||
name: "Bedwars Rust".into(),
|
||||
version: env!("CARGO_PKG_VERSION").into(),
|
||||
authors: vec!["Antigravity".into()],
|
||||
description: "Rewrite of Bedwars plugin in Rust for Pumpkin MC".into(),
|
||||
dependencies: vec![],
|
||||
permissions: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn on_load(&mut self, _context: Context) -> pumpkin_plugin_api::Result<()> {
|
||||
info!("Bedwars Rust Plugin has been loaded successfully!");
|
||||
|
||||
// Initialize default GameManager (requires min 2 players, 30 seconds lobby time)
|
||||
let game_manager = game::GameManager::new(2, 30);
|
||||
self.game_manager = Some(game_manager);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_unload(&mut self, _context: Context) -> pumpkin_plugin_api::Result<()> {
|
||||
info!("Bedwars Rust Plugin has been unloaded. Goodbye!");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pumpkin_plugin_api::register_plugin!(BedwarsPlugin);
|
||||
@@ -0,0 +1,118 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ShopItem {
|
||||
pub material: String,
|
||||
pub cost_material: String,
|
||||
pub cost_amount: u32,
|
||||
pub display_name: String,
|
||||
pub give_amount: u32,
|
||||
}
|
||||
|
||||
impl ShopItem {
|
||||
pub fn parse(config_str: &str) -> Option<Self> {
|
||||
// Example format: WOOL:IRON:4:&fWhite Wool:16
|
||||
let parts: Vec<&str> = config_str.split(':').collect();
|
||||
if parts.len() < 4 {
|
||||
return None;
|
||||
}
|
||||
let raw_mat = parts[0].to_uppercase();
|
||||
let material = format!("minecraft:{}", raw_mat.to_lowercase());
|
||||
|
||||
let cost_type = parts[1].to_uppercase();
|
||||
let cost_material = match cost_type.as_str() {
|
||||
"IRON" => "minecraft:iron_ingot",
|
||||
"GOLD" => "minecraft:gold_ingot",
|
||||
"DIAMOND" => "minecraft:diamond",
|
||||
"EMERALD" => "minecraft:emerald",
|
||||
_ => "minecraft:iron_ingot",
|
||||
}.to_string();
|
||||
|
||||
let cost_amount = parts[2].parse::<u32>().ok()?;
|
||||
let display_name = parts[3].to_string();
|
||||
|
||||
let give_amount = if parts.len() >= 5 {
|
||||
parts[4].parse::<u32>().unwrap_or(1)
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
Some(Self {
|
||||
material,
|
||||
cost_material,
|
||||
cost_amount,
|
||||
display_name,
|
||||
give_amount,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PlayerInventory {
|
||||
pub items: HashMap<String, u32>,
|
||||
}
|
||||
|
||||
impl PlayerInventory {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
items: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_item_count(&self, item_id: &str) -> u32 {
|
||||
*self.items.get(item_id).unwrap_or(&0)
|
||||
}
|
||||
|
||||
pub fn take_items(&mut self, item_id: &str, amount: u32) -> bool {
|
||||
let current = self.get_item_count(item_id);
|
||||
if current >= amount {
|
||||
if current == amount {
|
||||
self.items.remove(item_id);
|
||||
} else {
|
||||
self.items.insert(item_id.to_string(), current - amount);
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn give_items(&mut self, item_id: &str, amount: u32) {
|
||||
let current = self.get_item_count(item_id);
|
||||
self.items.insert(item_id.to_string(), current + amount);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ShopManager {
|
||||
pub categories: HashMap<String, Vec<ShopItem>>,
|
||||
}
|
||||
|
||||
impl ShopManager {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
categories: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_item(&mut self, category: &str, item_str: &str) {
|
||||
if let Some(item) = ShopItem::parse(item_str) {
|
||||
self.categories.entry(category.to_string()).or_default().push(item);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn attempt_purchase(
|
||||
&self,
|
||||
inventory: &mut PlayerInventory,
|
||||
category: &str,
|
||||
item_index: usize,
|
||||
) -> Result<ShopItem, &'static str> {
|
||||
let items = self.categories.get(category).ok_or("Category not found")?;
|
||||
let item = items.get(item_index).ok_or("Item not found")?;
|
||||
|
||||
if inventory.take_items(&item.cost_material, item.cost_amount) {
|
||||
inventory.give_items(&item.material, item.give_amount);
|
||||
Ok(item.clone())
|
||||
} else {
|
||||
Err("Insufficient funds")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum GameState {
|
||||
Lobby,
|
||||
Playing,
|
||||
Ending,
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum BedwarsTeam {
|
||||
Red,
|
||||
Blue,
|
||||
Purple,
|
||||
Yellow,
|
||||
}
|
||||
|
||||
impl BedwarsTeam {
|
||||
pub fn from_str(s: &str) -> Option<Self> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"red" => Some(Self::Red),
|
||||
"blue" => Some(Self::Blue),
|
||||
"purple" => Some(Self::Purple),
|
||||
"yellow" => Some(Self::Yellow),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Red => "Red",
|
||||
Self::Blue => "Blue",
|
||||
Self::Purple => "Purple",
|
||||
Self::Yellow => "Yellow",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_color_code(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Red => "§c",
|
||||
Self::Blue => "§9",
|
||||
Self::Purple => "§5",
|
||||
Self::Yellow => "§e",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_prefix(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Red => "§c[RED] ",
|
||||
Self::Blue => "§9[BLUE] ",
|
||||
Self::Purple => "§5[PURPLE] ",
|
||||
Self::Yellow => "§e[YELLOW] ",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_wool_material(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Red => "red_wool",
|
||||
Self::Blue => "blue_wool",
|
||||
Self::Purple => "purple_wool",
|
||||
Self::Yellow => "yellow_wool",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_bed_material(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Red => "red_bed",
|
||||
Self::Blue => "blue_bed",
|
||||
Self::Purple => "purple_bed",
|
||||
Self::Yellow => "yellow_bed",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_colorized_name(&self) -> String {
|
||||
format!("{}{}", self.get_color_code(), self.get_name())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user