mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
CHUNK LOADING KINDA WORKS
This commit is contained in:
308
Cargo.lock
generated
308
Cargo.lock
generated
@@ -67,12 +67,6 @@ version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
@@ -135,9 +129,9 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.7"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
|
||||
checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
@@ -170,12 +164,6 @@ dependencies = [
|
||||
"inout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.1.0"
|
||||
@@ -301,6 +289,12 @@ dependencies = [
|
||||
"crypto-common 0.2.0-rc.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.34"
|
||||
@@ -326,37 +320,6 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastanvil"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "619fbd9bb48f9e54a7ff88cdd0f7048b8ea519448518c690057f9d03d3e81ebf"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
"byteorder",
|
||||
"fastnbt 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2",
|
||||
"image 0.23.14",
|
||||
"log",
|
||||
"num_enum",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tar",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastnbt"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d4a73a95dc65551ccd98e1ecd1adb5d1ba5361146963b31f481ca42fc0520a3"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"cesu8",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastnbt"
|
||||
version = "2.5.0"
|
||||
@@ -396,18 +359,6 @@ dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.31"
|
||||
@@ -448,6 +399,21 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.30"
|
||||
@@ -455,6 +421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -463,6 +430,34 @@ version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.30"
|
||||
@@ -481,10 +476,16 @@ version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -649,9 +650,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956"
|
||||
checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
@@ -677,20 +678,6 @@ dependencies = [
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.23.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.25.2"
|
||||
@@ -728,6 +715,15 @@ version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
@@ -885,7 +881,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -908,17 +904,6 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
@@ -929,27 +914,6 @@ dependencies = [
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.7"
|
||||
@@ -961,9 +925,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.2"
|
||||
version = "0.36.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e"
|
||||
checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -997,7 +961,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1050,7 +1014,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1120,16 +1084,6 @@ dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"toml_edit 0.19.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
@@ -1146,7 +1100,7 @@ dependencies = [
|
||||
"base64",
|
||||
"crossbeam-channel",
|
||||
"digest 0.11.0-pre.9",
|
||||
"image 0.25.2",
|
||||
"image",
|
||||
"log",
|
||||
"mio",
|
||||
"num-bigint",
|
||||
@@ -1184,7 +1138,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1194,12 +1148,14 @@ dependencies = [
|
||||
"aes",
|
||||
"bytes",
|
||||
"cfb8",
|
||||
"fastnbt 2.5.0 (git+https://github.com/owengage/fastnbt.git)",
|
||||
"fastnbt",
|
||||
"flate2",
|
||||
"itertools",
|
||||
"log",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"pumpkin-macros",
|
||||
"pumpkin-world",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"take_mut",
|
||||
@@ -1211,7 +1167,7 @@ dependencies = [
|
||||
name = "pumpkin-registry"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fastnbt 2.5.0 (git+https://github.com/owengage/fastnbt.git)",
|
||||
"fastnbt",
|
||||
"fastsnbt",
|
||||
"pumpkin-protocol",
|
||||
"serde",
|
||||
@@ -1221,10 +1177,15 @@ dependencies = [
|
||||
name = "pumpkin-world"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fastanvil",
|
||||
"fastnbt 2.5.0 (git+https://github.com/owengage/fastnbt.git)",
|
||||
"fastnbt",
|
||||
"fastsnbt",
|
||||
"pumpkin-protocol",
|
||||
"flate2",
|
||||
"futures",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@@ -1267,15 +1228,6 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.5"
|
||||
@@ -1407,9 +1359,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.7.0"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
|
||||
checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
@@ -1462,9 +1414,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.204"
|
||||
version = "1.0.205"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||
checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@@ -1480,13 +1432,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.204"
|
||||
version = "1.0.205"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1620,17 +1572,6 @@ version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.72"
|
||||
@@ -1675,27 +1616,17 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909"
|
||||
dependencies = [
|
||||
"filetime",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.11.0"
|
||||
version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53"
|
||||
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1715,7 +1646,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1790,7 +1721,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1836,7 +1767,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.22.20",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1848,17 +1779,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.19.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
"winnow 0.5.40",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.20"
|
||||
@@ -1869,7 +1789,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow 0.6.18",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2025,7 +1945,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -2059,7 +1979,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -2098,6 +2018,15 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
@@ -2219,15 +2148,6 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.18"
|
||||
@@ -2265,7 +2185,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -6,6 +6,7 @@ edition.workspace = true
|
||||
[dependencies]
|
||||
|
||||
pumpkin-macros = { path = "../pumpkin-macros" }
|
||||
pumpkin-world = { path = "../pumpkin-world" }
|
||||
|
||||
bytes = "1.7"
|
||||
|
||||
@@ -29,3 +30,4 @@ fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
|
||||
aes = "0.8.4"
|
||||
cfb8 = "0.8.1"
|
||||
take_mut = "0.2.2"
|
||||
itertools = "0.13.0"
|
||||
|
||||
@@ -3,10 +3,20 @@ use serde::{
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
};
|
||||
|
||||
use crate::{ClientPacket, ServerPacket, VarInt, VarIntType};
|
||||
use crate::{BitSet, ClientPacket, ServerPacket, VarInt, VarIntType};
|
||||
|
||||
use super::{deserializer, serializer, ByteBuffer, DeserializerError};
|
||||
|
||||
impl Serialize for BitSet {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
// TODO: make this right
|
||||
(self.0.clone(), self.1.clone()).serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for VarInt {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
|
||||
10
pumpkin-protocol/src/client/play/c_center_chunk.rs
Normal file
10
pumpkin-protocol/src/client/play/c_center_chunk.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
use pumpkin_macros::packet;
|
||||
|
||||
use crate::VarInt;
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
#[packet(0x54)]
|
||||
pub struct CCenterChunk {
|
||||
pub chunk_x: VarInt,
|
||||
pub chunk_z: VarInt
|
||||
}
|
||||
113
pumpkin-protocol/src/client/play/c_chunk_data.rs
Normal file
113
pumpkin-protocol/src/client/play/c_chunk_data.rs
Normal file
@@ -0,0 +1,113 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::{bytebuf::ByteBuffer, BitSet, ClientPacket, VarInt};
|
||||
use fastnbt::LongArray;
|
||||
use itertools::Itertools;
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_world::chunk::ChunkData;
|
||||
|
||||
#[packet(0x27)]
|
||||
pub struct CChunkData<'a>(pub &'a ChunkData);
|
||||
|
||||
impl<'a> ClientPacket for CChunkData<'a> {
|
||||
fn write(&self, buf: &mut crate::bytebuf::ByteBuffer) {
|
||||
// Chunk X
|
||||
buf.put_i32(self.0.position.0);
|
||||
// Chunk Z
|
||||
buf.put_i32(self.0.position.1);
|
||||
|
||||
let heightmap_nbt =
|
||||
fastnbt::to_bytes_with_opts(&self.0.heightmaps, fastnbt::SerOpts::network_nbt())
|
||||
.unwrap();
|
||||
// Heightmaps
|
||||
buf.put_slice(&heightmap_nbt);
|
||||
|
||||
let mut data_buf = ByteBuffer::empty();
|
||||
self.0
|
||||
.blocks
|
||||
.iter()
|
||||
.chunks(16 * 16 * 16)
|
||||
.into_iter()
|
||||
.for_each(|chunk| {
|
||||
let chunk = chunk.collect_vec();
|
||||
let block_count = chunk
|
||||
.iter()
|
||||
.filter(|block| ***block != 0 && ***block != 12959 && ***block != 12958)
|
||||
.count() as i16;
|
||||
// Block count
|
||||
data_buf.put_i16(block_count);
|
||||
//// Block states
|
||||
let palette = chunk.clone().into_iter().dedup().collect_vec();
|
||||
let mut palette_map = HashMap::new();
|
||||
let block_size = 8;
|
||||
// let block_size = {
|
||||
// let palette_bit_len = palette.len().leading_zeros();
|
||||
// if palette_bit_len > 3 {
|
||||
// palette_bit_len
|
||||
// } else {
|
||||
// 4
|
||||
// }
|
||||
// };
|
||||
// Bits per entry
|
||||
data_buf.put_u8(block_size as u8);
|
||||
// Palette length
|
||||
data_buf.put_var_int(&VarInt(palette.len() as i32));
|
||||
palette.iter().enumerate().for_each(|(i, id)| {
|
||||
palette_map.insert(*id, i);
|
||||
// Palette
|
||||
data_buf.put_var_int(&VarInt(**id as i32));
|
||||
});
|
||||
let mut block_data_array = Vec::new();
|
||||
for block_clump in chunk.chunks(64 / block_size as usize) {
|
||||
let mut out_long: i64 = 0;
|
||||
let mut first = true;
|
||||
for block in block_clump {
|
||||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
out_long = out_long << block_size;
|
||||
}
|
||||
let index = palette_map
|
||||
.get(block)
|
||||
.expect("Its just got added, ofc it should be there");
|
||||
out_long = out_long | *index as i64;
|
||||
}
|
||||
block_data_array.push(out_long);
|
||||
}
|
||||
|
||||
// Data array length
|
||||
data_buf.put_var_int(&VarInt(block_data_array.len() as i32));
|
||||
// Data array
|
||||
for data_int in block_data_array {
|
||||
data_buf.put_i64(data_int);
|
||||
}
|
||||
|
||||
//// Biomes
|
||||
// TODO: make biomes work
|
||||
data_buf.put_u8(0);
|
||||
data_buf.put_var_int(&VarInt(0));
|
||||
data_buf.put_var_int(&VarInt(0));
|
||||
});
|
||||
|
||||
// Size
|
||||
buf.put_var_int(&VarInt(data_buf.buf().len() as i32));
|
||||
// Data
|
||||
buf.put_slice(&data_buf.buf());
|
||||
|
||||
// TODO: block entities
|
||||
buf.put_var_int(&VarInt(0));
|
||||
|
||||
// TODO
|
||||
buf.put_bit_set(&BitSet(VarInt(1), vec![0]));
|
||||
buf.put_bit_set(&BitSet(VarInt(1), vec![0]));
|
||||
buf.put_bit_set(&BitSet(VarInt(1), vec![0]));
|
||||
buf.put_bit_set(&BitSet(VarInt(1), vec![0]));
|
||||
// buf.put_bit_set(&BitSet(VarInt(0), vec![]));
|
||||
// buf.put_bit_set(&BitSet(VarInt(0), vec![]));
|
||||
// buf.put_bit_set(&BitSet(VarInt(0), vec![]));
|
||||
// buf.put_bit_set(&BitSet(VarInt(0), vec![]));
|
||||
|
||||
buf.put_var_int(&VarInt(0));
|
||||
buf.put_var_int(&VarInt(0));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
mod c_center_chunk;
|
||||
mod c_change_difficulty;
|
||||
mod c_chunk_data;
|
||||
mod c_chunk_data_update_light;
|
||||
mod c_disguised_chat_message;
|
||||
mod c_entity_animation;
|
||||
@@ -20,7 +22,9 @@ mod c_update_entity_pos;
|
||||
mod c_update_entity_rot;
|
||||
mod player_action;
|
||||
|
||||
pub use c_center_chunk::*;
|
||||
pub use c_change_difficulty::*;
|
||||
pub use c_chunk_data::*;
|
||||
pub use c_chunk_data_update_light::*;
|
||||
pub use c_disguised_chat_message::*;
|
||||
pub use c_entity_animation::*;
|
||||
|
||||
@@ -32,7 +32,7 @@ impl PacketEncoder {
|
||||
.encode(&mut writer)
|
||||
.map_err(|_| PacketError::EncodeID)?;
|
||||
packet.write(&mut packet_buf);
|
||||
|
||||
|
||||
writer
|
||||
.write(packet_buf.buf())
|
||||
.map_err(|_| PacketError::EncodeFailedWrite)?;
|
||||
|
||||
@@ -4,8 +4,14 @@ version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
pumpkin-protocol = { path = "../pumpkin-protocol"}
|
||||
fastanvil = "0.31"
|
||||
# fastanvil = "0.31"
|
||||
fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
|
||||
fastsnbt = "0.2"
|
||||
tokio.workspace = true
|
||||
tokio.workspace = true
|
||||
itertools = "0.13.0"
|
||||
thiserror = "1.0.63"
|
||||
futures = "0.3.30"
|
||||
flate2 = "1.0.31"
|
||||
serde = { version = "1.0.205", features = ["derive"] }
|
||||
lazy_static = "1.5.0"
|
||||
serde_json = "1.0.122"
|
||||
|
||||
272408
pumpkin-world/blocks.json
Normal file
272408
pumpkin-world/blocks.json
Normal file
File diff suppressed because it is too large
Load Diff
58
pumpkin-world/src/block_registry.rs
Normal file
58
pumpkin-world/src/block_registry.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use crate::world::WorldError;
|
||||
|
||||
const BLOCKS_JSON: &'static str = include_str!("../blocks.json");
|
||||
|
||||
#[derive(serde::Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
struct BlockDefinition {
|
||||
#[serde(rename = "type")]
|
||||
kind: String,
|
||||
block_set_type: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
struct BlockState {
|
||||
default: Option<bool>,
|
||||
id: i64,
|
||||
properties: Option<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
struct BlocksElement {
|
||||
definition: BlockDefinition,
|
||||
properties: Option<HashMap<String, Vec<String>>>,
|
||||
states: Vec<BlockState>,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref BLOCKS: HashMap<String, BlocksElement> =
|
||||
serde_json::from_str(BLOCKS_JSON).expect("Could not parse block.json registry.");
|
||||
}
|
||||
|
||||
pub fn block_id_and_properties_to_block_state_id(
|
||||
block_id: &str,
|
||||
properties: Option<&HashMap<String, String>>,
|
||||
) -> Result<i64, WorldError> {
|
||||
let block = match BLOCKS.get(block_id) {
|
||||
Some(block) => block,
|
||||
None => return Err(WorldError::BlockStateIdNotFound),
|
||||
};
|
||||
let block_state_id = match properties {
|
||||
None => Ok(block
|
||||
.states
|
||||
.iter()
|
||||
.find(|state| state.default.unwrap_or(false))
|
||||
.expect("Each block should have at least one default state")
|
||||
.id),
|
||||
Some(properties) => block
|
||||
.states
|
||||
.iter()
|
||||
.find(|state| state.properties.as_ref() == Some(properties))
|
||||
.map(|state| state.id)
|
||||
.ok_or(WorldError::BlockStateIdNotFound),
|
||||
};
|
||||
block_state_id
|
||||
}
|
||||
@@ -1,26 +1,161 @@
|
||||
use fastnbt::nbt;
|
||||
// use fastnbt::nbt;
|
||||
|
||||
pub const BLOCKS_AND_BIOMES: [u8; 2000] = [0x80; 2000];
|
||||
pub const SKY_LIGHT_ARRAYS: [FixedArray<u8, 2048>; 26] = [FixedArray([0xff; 2048]); 26];
|
||||
// pub const BLOCKS_AND_BIOMES: [u8; 2000] = [0x80; 2000];
|
||||
// pub const SKY_LIGHT_ARRAYS: [FixedArray<u8, 2048>; 26] = [FixedArray([0xff; 2048]); 26];
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct FixedArray<T, const N: usize>(pub [T; N]);
|
||||
// #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
// #[repr(transparent)]
|
||||
// pub struct FixedArray<T, const N: usize>(pub [T; N]);
|
||||
|
||||
pub struct TestChunk {
|
||||
pub heightmap: Vec<u8>,
|
||||
// pub struct TestChunk {
|
||||
// pub heightmap: Vec<u8>,
|
||||
// }
|
||||
|
||||
// impl Default for TestChunk {
|
||||
// fn default() -> Self {
|
||||
// Self::new()
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl TestChunk {
|
||||
// pub fn new() -> Self {
|
||||
// let bytes = fastnbt::to_bytes(&nbt!({"MOTION_BLOCKING": [L; 123, 256]})).unwrap();
|
||||
|
||||
// Self { heightmap: bytes }
|
||||
// }
|
||||
// }
|
||||
|
||||
use std::{collections::HashMap, io::Write};
|
||||
|
||||
use fastnbt::LongArray;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::{world::WorldError, WORLD_HEIGHT};
|
||||
|
||||
pub struct ChunkData {
|
||||
pub blocks: Box<[i64; 16 * 16 * WORLD_HEIGHT]>,
|
||||
pub position: (i32, i32),
|
||||
pub heightmaps: ChunkHeightmaps,
|
||||
}
|
||||
|
||||
impl Default for TestChunk {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
#[derive(serde::Deserialize, Debug, Clone)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
struct PaletteEntry {
|
||||
name: String,
|
||||
properties: Option<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
impl TestChunk {
|
||||
pub fn new() -> Self {
|
||||
let bytes = fastnbt::to_bytes(&nbt!({"MOTION_BLOCKING": [L; 123, 256]})).unwrap();
|
||||
#[derive(serde::Deserialize, Debug, Clone)]
|
||||
struct ChunkSectionBlockStates {
|
||||
data: Option<LongArray>, // TODO: see if you can use u32 here
|
||||
palette: Vec<PaletteEntry>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
pub struct ChunkHeightmaps {
|
||||
motion_blocking: LongArray,
|
||||
world_surface: LongArray,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct ChunkSection {
|
||||
#[serde(rename = "Y")]
|
||||
y: i32,
|
||||
block_states: Option<ChunkSectionBlockStates>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
struct ChunkNbt {
|
||||
#[serde(rename = "DataVersion")]
|
||||
data_version: usize,
|
||||
sections: Vec<ChunkSection>,
|
||||
#[serde(rename = "Heightmaps")]
|
||||
heightmaps: ChunkHeightmaps,
|
||||
}
|
||||
|
||||
impl ChunkData {
|
||||
pub fn from_bytes(chunk_data: Vec<u8>, at: (i32, i32)) -> Result<Self, WorldError> {
|
||||
let chunk_data = match fastnbt::from_bytes::<ChunkNbt>(chunk_data.as_slice()) {
|
||||
Ok(v) => v,
|
||||
Err(err) => return Err(WorldError::ErrorDeserializingChunk(err.to_string())),
|
||||
};
|
||||
|
||||
// this needs to be boxed, otherwise it will cause a stack-overflow
|
||||
let mut blocks = Box::new([0; 16 * 16 * WORLD_HEIGHT]);
|
||||
|
||||
for (k, section) in chunk_data.sections.into_iter().enumerate() {
|
||||
let block_states = match section.block_states {
|
||||
Some(states) => states,
|
||||
None => continue, // this should instead fill all blocks with the only element of the palette
|
||||
};
|
||||
let palette = block_states
|
||||
.palette
|
||||
.iter()
|
||||
.map(|entry| {
|
||||
crate::block_registry::block_id_and_properties_to_block_state_id(
|
||||
&entry.name,
|
||||
entry.properties.as_ref(),
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let block_data = match block_states.data {
|
||||
None => continue,
|
||||
Some(d) => d,
|
||||
}
|
||||
.into_inner();
|
||||
let block_size = {
|
||||
let size = 64 - (palette.len() - 1).leading_zeros();
|
||||
if size >= 4 {
|
||||
size
|
||||
} else {
|
||||
4
|
||||
}
|
||||
};
|
||||
|
||||
let mask = (1 << block_size) - 1;
|
||||
println!("{block_size} {:#08b}", mask);
|
||||
println!(
|
||||
"{} {}",
|
||||
block_size,
|
||||
palette.iter().map(|v| v.to_string()).join(",")
|
||||
);
|
||||
let mut blocks_left = 16 * 16 * 16;
|
||||
'block_loop: for (j, block) in block_data.iter().enumerate() {
|
||||
for i in 0..64 / block_size {
|
||||
if blocks_left <= 0 {
|
||||
break 'block_loop;
|
||||
}
|
||||
let index = (block >> (i * block_size)) & mask;
|
||||
let block = palette[index as usize];
|
||||
blocks[k * 16 * 16 * 16 + j * ((64 / block_size) as usize) + i as usize] =
|
||||
block;
|
||||
blocks_left -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// std::fs::File::create_new("../mafaile.txt")
|
||||
// .unwrap()
|
||||
// .write_all(
|
||||
// blocks
|
||||
// .iter()
|
||||
// .map(|v| v.to_string())
|
||||
// .collect::<Vec<_>>()
|
||||
// .join(",")
|
||||
// .as_bytes(),
|
||||
// );
|
||||
|
||||
Self { heightmap: bytes }
|
||||
if at == (0, 0) {
|
||||
println!(
|
||||
"[{}]",
|
||||
&blocks[0..10000].iter().map(|v| v.to_string()).join(",")
|
||||
);
|
||||
}
|
||||
Ok(ChunkData {
|
||||
blocks: blocks,
|
||||
position: at,
|
||||
heightmaps: chunk_data.heightmaps,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
21
pumpkin-world/src/dimension.rs
Normal file
21
pumpkin-world/src/dimension.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::world::Level;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum Dimension {
|
||||
OverWorld,
|
||||
Nether,
|
||||
End,
|
||||
}
|
||||
|
||||
impl Dimension {
|
||||
pub fn into_level(&self, mut base_directory: PathBuf) -> Level {
|
||||
match self {
|
||||
Dimension::OverWorld => {}
|
||||
Dimension::Nether => base_directory.push("DIM-1"),
|
||||
Dimension::End => base_directory.push("DIM1"),
|
||||
}
|
||||
Level::from_root_folder(base_directory)
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,6 @@
|
||||
use std::{fs::File, path::Path};
|
||||
|
||||
use fastanvil::Region;
|
||||
|
||||
pub mod chunk;
|
||||
|
||||
pub struct World {
|
||||
pub region: Region<File>,
|
||||
}
|
||||
|
||||
impl World {
|
||||
pub fn load<P: AsRef<Path>>(path: P) -> Self {
|
||||
let file = std::fs::File::open(path).unwrap();
|
||||
|
||||
let region = Region::from_stream(file).unwrap();
|
||||
Self { region }
|
||||
}
|
||||
|
||||
/* pub fn load_chunk(&mut self, x: usize, y: usize) -> Chunk {
|
||||
let data = self.region.read_chunk(x, y).unwrap().unwrap();
|
||||
|
||||
let complete_chunk = complete::Chunk::from_bytes(&data).unwrap();
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
pub mod dimension;
|
||||
pub const WORLD_HEIGHT: usize = 384;
|
||||
pub const WORLD_Y_START_AT: i32 = -64; // TODO: make sure where it actually starts at (i think its at -64 but not sure)
|
||||
mod world;
|
||||
mod block_registry;
|
||||
245
pumpkin-world/src/world.rs
Normal file
245
pumpkin-world/src/world.rs
Normal file
@@ -0,0 +1,245 @@
|
||||
use std::{collections::VecDeque, future, io::Read, path::PathBuf, sync::Arc};
|
||||
|
||||
use flate2::bufread::ZlibDecoder;
|
||||
use itertools::Itertools;
|
||||
use thiserror::Error;
|
||||
use tokio::{
|
||||
fs::File,
|
||||
io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt},
|
||||
sync::Mutex,
|
||||
};
|
||||
|
||||
use crate::{chunk::ChunkData, dimension::Dimension};
|
||||
|
||||
pub struct Level {
|
||||
root_folder: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum WorldError {
|
||||
// using ErrorKind instead of Error, beacuse the function read_chunks and read_region_chunks is designed to return an error on a per-chunk basis, while std::io::Error does not implement Copy or Clone
|
||||
#[error("Io error: {0}")]
|
||||
IoError(std::io::ErrorKind),
|
||||
#[error("Region not found")]
|
||||
RegionNotFound,
|
||||
#[error("Region is invalid")]
|
||||
RegionIsInvalid,
|
||||
#[error("Chunk not found")]
|
||||
ChunkNotFound,
|
||||
#[error("Compression scheme not recognised")]
|
||||
UnknownCompression,
|
||||
#[error("Error while working with zlib compression: {0}")]
|
||||
ZlibError(std::io::Error),
|
||||
#[error("Error deserializing chunk: {0}")]
|
||||
ErrorDeserializingChunk(String),
|
||||
#[error("The requested block state id does not exist")]
|
||||
BlockStateIdNotFound,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Compression {
|
||||
Gzip,
|
||||
Zlib,
|
||||
None,
|
||||
LZ4,
|
||||
}
|
||||
|
||||
impl Level {
|
||||
pub fn from_root_folder(root_folder: PathBuf) -> Self {
|
||||
Level { root_folder }
|
||||
}
|
||||
|
||||
/// Read one chunk in the world
|
||||
///
|
||||
/// Do not use this function if reading many chunks is required, since in case those two chunks which are read seperately using `.read_chunk` are in the same region file, it will need to be opened and closed separately for both of them, leading to a performance loss.
|
||||
pub async fn read_chunk(&self, chunk: (i32, i32)) -> Result<ChunkData, WorldError> {
|
||||
self.read_chunks(vec![chunk])
|
||||
.await
|
||||
.pop()
|
||||
.expect("Read chunks must return a chunk")
|
||||
.1
|
||||
}
|
||||
|
||||
/// Read many chunks in a world
|
||||
///
|
||||
/// Note: The order of the output chunks will almost never be in the same order as the order of input chunks
|
||||
pub async fn read_chunks(
|
||||
&self,
|
||||
chunks: Vec<(i32, i32)>,
|
||||
) -> Vec<((i32, i32), Result<ChunkData, WorldError>)> {
|
||||
futures::future::join_all(
|
||||
chunks
|
||||
.into_iter()
|
||||
// split chunks into their corresponding region files to be able to read all of them at once, instead of reopening the file multiple times
|
||||
.chunk_by(|chunk| {
|
||||
(
|
||||
((chunk.0 as f32) / 32.0).floor() as i32,
|
||||
((chunk.1 as f32) / 32.0).floor() as i32,
|
||||
)
|
||||
})
|
||||
.into_iter()
|
||||
.map(|(region, chunk_vec)| {
|
||||
let mut path = self.root_folder.clone();
|
||||
path.push("region");
|
||||
path.push(format!("r.{}.{}.mca", region.0, region.1));
|
||||
self.read_region_chunks(path, chunk_vec.collect_vec())
|
||||
}),
|
||||
)
|
||||
.await
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect_vec()
|
||||
}
|
||||
async fn read_region_chunks(
|
||||
&self,
|
||||
region_file: PathBuf,
|
||||
chunks: Vec<(i32, i32)>,
|
||||
) -> Vec<((i32, i32), Result<ChunkData, WorldError>)> {
|
||||
// dbg!(at);
|
||||
println!(
|
||||
"Getting chunks {:?}, from region file {}",
|
||||
&chunks,
|
||||
region_file.to_str().unwrap_or("")
|
||||
);
|
||||
// return different error when file is not found (because that means that the chunks have just not been generated yet)
|
||||
let mut region_file = match File::open(region_file).await {
|
||||
Ok(f) => f,
|
||||
Err(err) => match err.kind() {
|
||||
std::io::ErrorKind::NotFound => {
|
||||
return chunks
|
||||
.into_iter()
|
||||
.map(|c| (c, Err(WorldError::RegionNotFound)))
|
||||
.collect_vec()
|
||||
}
|
||||
_ => {
|
||||
return chunks
|
||||
.into_iter()
|
||||
.map(|c| (c, Err(WorldError::IoError(err.kind()))))
|
||||
.collect_vec()
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let mut location_table: [u8; 4096] = [0; 4096];
|
||||
let mut timestamp_table: [u8; 4096] = [0; 4096];
|
||||
|
||||
// fill the location and timestamp tables
|
||||
{
|
||||
match region_file.read_exact(&mut location_table).await {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
return chunks
|
||||
.into_iter()
|
||||
.map(|c| (c, Err(WorldError::IoError(err.kind()))))
|
||||
.collect_vec()
|
||||
}
|
||||
}
|
||||
match region_file.read_exact(&mut timestamp_table).await {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
return chunks
|
||||
.into_iter()
|
||||
.map(|c| (c, Err(WorldError::IoError(err.kind()))))
|
||||
.collect_vec()
|
||||
}
|
||||
}
|
||||
}
|
||||
// println!("Location table: {:?}", &location_table);
|
||||
|
||||
// wrap file with arc mutex to allow for multithreading
|
||||
let region_file = Arc::new(Mutex::new(region_file));
|
||||
futures::future::join_all(chunks.into_iter().map(|(old_chunk_x, old_chunk_z)| {
|
||||
let region_file = region_file.clone();
|
||||
let modulus = |a: i32, b: i32| ((a % b) + b) % b;
|
||||
let chunk_x = modulus(old_chunk_x, 32) as u32;
|
||||
let chunk_z = modulus(old_chunk_z, 32) as u32;
|
||||
async move {
|
||||
let table_entry = (chunk_x + chunk_z * 32) * 4;
|
||||
|
||||
let mut offset = vec![0u8];
|
||||
offset.extend_from_slice(
|
||||
&location_table[table_entry as usize..table_entry as usize + 3],
|
||||
);
|
||||
let offset = u32::from_be_bytes(offset.try_into().unwrap()) as u64 * 4096;
|
||||
let size = location_table[table_entry as usize + 3] as usize * 4096;
|
||||
|
||||
if offset == 0 && size == 0 {
|
||||
return ((old_chunk_x, old_chunk_z), Err(WorldError::ChunkNotFound));
|
||||
}
|
||||
// Read the file using the offset and size
|
||||
let mut file_buf = {
|
||||
let mut region_file = region_file.lock().await;
|
||||
let seek_result = region_file.seek(std::io::SeekFrom::Start(offset)).await;
|
||||
if seek_result.is_err() {
|
||||
return ((old_chunk_x, old_chunk_z), Err(WorldError::RegionIsInvalid));
|
||||
}
|
||||
let mut out = vec![0; size];
|
||||
let read_result = region_file.read_exact(&mut out).await;
|
||||
if read_result.is_err() {
|
||||
return ((old_chunk_x, old_chunk_z), Err(WorldError::RegionIsInvalid));
|
||||
}
|
||||
out
|
||||
};
|
||||
|
||||
// TODO: check checksum to make sure chunk is not corrupted
|
||||
let header = file_buf.drain(0..5).collect_vec();
|
||||
|
||||
let compression = match header[4] {
|
||||
1 => Compression::Gzip,
|
||||
2 => Compression::Zlib,
|
||||
3 => Compression::None,
|
||||
4 => Compression::LZ4,
|
||||
_ => return ((old_chunk_x, old_chunk_z), Err(WorldError::RegionIsInvalid)),
|
||||
};
|
||||
|
||||
match compression {
|
||||
Compression::Zlib => {}
|
||||
_ => panic!(), // TODO: support other compression types
|
||||
}
|
||||
|
||||
let size = u32::from_be_bytes(header[0..4].try_into().unwrap());
|
||||
|
||||
let chunk_data = file_buf.drain(0..size as usize).collect_vec();
|
||||
|
||||
let mut z = ZlibDecoder::new(&chunk_data[..]);
|
||||
let mut chunk_data = Vec::new();
|
||||
match z.read_to_end(&mut chunk_data) {
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
return ((old_chunk_x, old_chunk_z), Err(WorldError::ZlibError(err)))
|
||||
}
|
||||
}
|
||||
// TODO: remove
|
||||
// File::create_new(format!("./test-{}.{}.nbt", old_chunk_x, old_chunk_z))
|
||||
// .await
|
||||
// .unwrap()
|
||||
// .write_all(&chunk_data)
|
||||
// .await
|
||||
// .unwrap();
|
||||
|
||||
(
|
||||
(old_chunk_x, old_chunk_z),
|
||||
ChunkData::from_bytes(chunk_data, (old_chunk_x, old_chunk_z)),
|
||||
)
|
||||
}
|
||||
}))
|
||||
.await
|
||||
.into_iter()
|
||||
.collect_vec()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wawa() {
|
||||
tokio::runtime::Runtime::new().unwrap().block_on(async {
|
||||
Dimension::OverWorld
|
||||
.into_level(
|
||||
"C:\\Users\\lukza\\Desktop\\code\\rust\\vanilla_mc_server\\world"
|
||||
.parse()
|
||||
.unwrap(),
|
||||
)
|
||||
.read_chunk((0, 0))
|
||||
.await
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
BIN
pumpkin-world/test.nbt
Normal file
BIN
pumpkin-world/test.nbt
Normal file
Binary file not shown.
@@ -217,7 +217,7 @@ impl Client {
|
||||
self.send_packet(CFinishConfig::new());
|
||||
}
|
||||
|
||||
pub fn handle_config_acknowledged(
|
||||
pub async fn handle_config_acknowledged(
|
||||
&mut self,
|
||||
server: &mut Server,
|
||||
_config_acknowledged: SAcknowledgeFinishConfig,
|
||||
@@ -225,6 +225,6 @@ impl Client {
|
||||
dbg!("config acknowledged");
|
||||
self.connection_state = ConnectionState::Play;
|
||||
// generate a player
|
||||
server.spawn_player(self);
|
||||
server.spawn_player(self).await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ impl Client {
|
||||
SAcknowledgeFinishConfig::PACKET_ID => self.handle_config_acknowledged(
|
||||
server,
|
||||
SAcknowledgeFinishConfig::read(bytebuf).unwrap(),
|
||||
),
|
||||
).await,
|
||||
SKnownPacks::PACKET_ID => {
|
||||
self.handle_known_packs(server, SKnownPacks::read(bytebuf).unwrap())
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ use config::BasicConfiguration;
|
||||
use server::Server;
|
||||
|
||||
// Setup some tokens to allow us to identify which event is for which socket.
|
||||
const SERVER: Token = Token(0);
|
||||
|
||||
pub mod client;
|
||||
pub mod commands;
|
||||
@@ -25,6 +24,7 @@ pub mod util;
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
#[tokio::main]
|
||||
async fn main() -> io::Result<()> {
|
||||
const SERVER: Token = Token(0);
|
||||
use std::{cell::RefCell, time::Instant};
|
||||
|
||||
let time = Instant::now();
|
||||
|
||||
@@ -15,13 +15,13 @@ use pumpkin_protocol::{
|
||||
client::{
|
||||
config::CPluginMessage,
|
||||
play::{
|
||||
CChunkDataUpdateLight, CGameEvent, CLogin, CPlayerAbilities, CPlayerInfoUpdate,
|
||||
CRemoveEntities, CSpawnEntity, PlayerAction,
|
||||
CCenterChunk, CChunkData, CChunkDataUpdateLight, CGameEvent, CLogin, CPlayerAbilities,
|
||||
CPlayerInfoUpdate, CRemoveEntities, CSpawnEntity, PlayerAction,
|
||||
},
|
||||
},
|
||||
BitSet, ClientPacket, Players, Sample, StatusResponse, VarInt, Version, CURRENT_MC_PROTOCOL,
|
||||
};
|
||||
use pumpkin_world::chunk::TestChunk;
|
||||
use pumpkin_world::dimension::Dimension;
|
||||
use rsa::{traits::PublicKeyParts, RsaPrivateKey, RsaPublicKey};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -123,7 +123,7 @@ impl Server {
|
||||
|
||||
// here is where the magic happens
|
||||
// TODO: do this in a world
|
||||
pub fn spawn_player(&mut self, client: &mut Client) {
|
||||
pub async fn spawn_player(&mut self, client: &mut Client) {
|
||||
// This code follows the vanilla packet order
|
||||
let entity_id = self.new_entity_id();
|
||||
log::debug!("spawning player, entity id {}", entity_id);
|
||||
@@ -163,7 +163,7 @@ impl Server {
|
||||
|
||||
// teleport
|
||||
let x = 10.0;
|
||||
let y = 500.0;
|
||||
let y = 120.0;
|
||||
let z = 10.0;
|
||||
client.teleport(x, y, z, 10.0, 10.0);
|
||||
let gameprofile = client.gameprofile.as_ref().unwrap();
|
||||
@@ -257,7 +257,7 @@ impl Server {
|
||||
}
|
||||
*/
|
||||
|
||||
// Server::spawn_test_chunk(client);
|
||||
Server::spawn_test_chunk(client).await;
|
||||
}
|
||||
|
||||
/// Sends a Packet to all Players
|
||||
@@ -294,20 +294,49 @@ impl Server {
|
||||
}
|
||||
|
||||
// TODO: do this in a world
|
||||
fn _spawn_test_chunk(client: &mut Client) {
|
||||
let test_chunk = TestChunk::new();
|
||||
client.send_packet(CChunkDataUpdateLight::new(
|
||||
10,
|
||||
10,
|
||||
test_chunk.heightmap,
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
BitSet(0.into(), Vec::new()),
|
||||
BitSet(0.into(), Vec::new()),
|
||||
BitSet(0.into(), Vec::new()),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
));
|
||||
async fn spawn_test_chunk(client: &mut Client) {
|
||||
let mut wanted_chunks = Vec::new();
|
||||
|
||||
for i in -3i32..3 {
|
||||
for j in -3i32..3 {
|
||||
wanted_chunks.push((i, j))
|
||||
}
|
||||
}
|
||||
let chunks = Dimension::OverWorld
|
||||
.into_level(
|
||||
"C:\\Users\\lukza\\Desktop\\code\\rust\\vanilla_mc_server\\world"
|
||||
.parse()
|
||||
.unwrap(),
|
||||
)
|
||||
.read_chunks(wanted_chunks)
|
||||
.await;
|
||||
|
||||
client.send_packet(CCenterChunk {
|
||||
chunk_x: 0.into(),
|
||||
chunk_z: 0.into(),
|
||||
});
|
||||
|
||||
chunks.iter().for_each(|chunk| match &chunk.1 {
|
||||
Err(err) => println!(
|
||||
"Chunk loading failed for chunk ({},{}): {}",
|
||||
chunk.0 .0, chunk.0 .1, err
|
||||
),
|
||||
Ok(data) => client.send_packet(CChunkData(data)),
|
||||
});
|
||||
|
||||
// let test_chunk = TestChunk::new();
|
||||
// client.send_packet(CChunkDataUpdateLight::new(
|
||||
// 10,
|
||||
// 10,
|
||||
// test_chunk.heightmap,
|
||||
// Vec::new(),
|
||||
// Vec::new(),
|
||||
// BitSet(0.into(), Vec::new()),
|
||||
// BitSet(0.into(), Vec::new()),
|
||||
// BitSet(0.into(), Vec::new()),
|
||||
// Vec::new(),
|
||||
// Vec::new(),
|
||||
// ));
|
||||
}
|
||||
|
||||
// move to world
|
||||
|
||||
Reference in New Issue
Block a user