added thing
This commit is contained in:
parent
1c2cf9bd3f
commit
ff4423d593
16 changed files with 974 additions and 78 deletions
545
Cargo.lock
generated
545
Cargo.lock
generated
|
@ -53,6 +53,12 @@ dependencies = [
|
|||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -76,10 +82,10 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
name = "bumpalo"
|
||||
version = "3.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
|
@ -93,12 +99,6 @@ version = "1.0.79"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -106,10 +106,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
name = "encoding_rs"
|
||||
version = "0.8.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
@ -158,13 +158,27 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.26"
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -173,6 +187,12 @@ version = "0.3.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.28"
|
||||
|
@ -199,29 +219,139 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
|
||||
|
||||
[[package]]
|
||||
name = "hematite-nbt"
|
||||
version = "0.5.2"
|
||||
name = "h2"
|
||||
version = "0.3.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "670d0784ee67cfb57393dc1837867d2951f9a59ca7db99a653499c854f745739"
|
||||
checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"cesu8",
|
||||
"flate2",
|
||||
"serde",
|
||||
"bytes",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7"
|
||||
dependencies = [
|
||||
"http",
|
||||
"hyper",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.9"
|
||||
|
@ -239,6 +369,15 @@ version = "1.0.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
|
@ -273,6 +412,12 @@ version = "2.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
|
@ -387,6 +532,12 @@ dependencies = [
|
|||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.10"
|
||||
|
@ -420,9 +571,10 @@ version = "0.2.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"env_logger",
|
||||
"hematite-nbt",
|
||||
"log",
|
||||
"mlua",
|
||||
"once_cell",
|
||||
"reqwest",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -477,6 +629,60 @@ version = "0.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"webpki-roots",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
|
@ -502,6 +708,37 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring",
|
||||
"rustls-webpki",
|
||||
"sct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
|
||||
dependencies = [
|
||||
"base64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.100.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
|
@ -514,6 +751,16 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.18"
|
||||
|
@ -525,9 +772,6 @@ name = "serde"
|
|||
version = "1.0.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-value"
|
||||
|
@ -539,17 +783,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.103"
|
||||
|
@ -561,6 +794,18 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1_smol"
|
||||
version = "1.0.0"
|
||||
|
@ -601,6 +846,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.26"
|
||||
|
@ -621,6 +872,21 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.29.1"
|
||||
|
@ -652,12 +918,100 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.4.1"
|
||||
|
@ -667,12 +1021,116 @@ dependencies = [
|
|||
"sha1_smol",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
|
||||
dependencies = [
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.22.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
|
||||
dependencies = [
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -769,3 +1227,12 @@ name = "windows_x86_64_msvc"
|
|||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
|
|
@ -9,8 +9,9 @@ serde_json = "1.0"
|
|||
serde = "1.0"
|
||||
anyhow = "1.0"
|
||||
uuid = { version = "1.4", features = ["v5"] }
|
||||
hematite-nbt = "0.5.2"
|
||||
log = "0.4"
|
||||
env_logger = "0.10"
|
||||
mlua = { version = "0.9.0-rc.1", features = ["luajit52", "async", "send", "serialize"] }
|
||||
semver = "1.0"
|
||||
reqwest = { version = "0.11", features = ["rustls-tls", "json"], default-features = false }
|
||||
once_cell = "1.18"
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use std::io::Cursor;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use log::{info, debug};
|
||||
use log::{info, debug, warn};
|
||||
use serde_json::json;
|
||||
use tokio::{net::{TcpStream, tcp::{OwnedReadHalf, OwnedWriteHalf}}, select, io::{AsyncReadExt, AsyncWriteExt}};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{varint::VarInt, ser::{Deserializable, Position}, protocol::{self, Protocol, ProtocolState, ClientPacket, ServerPacket}, Player, ClientInfo};
|
||||
use crate::{varint::VarInt, ser::{Deserializable, Position}, protocol::{self, Protocol, ProtocolState, ClientPacket, ServerPacket}, Player, ClientInfo, JsonValue, HTTP_CLIENT};
|
||||
use event::{ClientEvent, ServerEvent};
|
||||
|
||||
pub mod event;
|
||||
|
@ -14,11 +14,37 @@ pub mod event;
|
|||
type Sender = tokio::sync::mpsc::Sender<(i32, ClientEvent)>;
|
||||
type Receiver = tokio::sync::mpsc::Receiver<ServerEvent>;
|
||||
|
||||
// arbitrary
|
||||
const OFFLINE_NAMESPACE: Uuid = Uuid::from_bytes([0xc3, 0xe3, 0xe7, 0xa5, 0x58, 0xe5, 0x4c, 0xf4, 0x84, 0xef, 0x27, 0x4b, 0x9e, 0xf1, 0x5c, 0xc3]);
|
||||
|
||||
fn offline_uuid(name: &str) -> Uuid {
|
||||
async fn fetch_uuid(name: &str) -> anyhow::Result<Uuid> {
|
||||
let url = "https://api.mojang.com/users/profiles/minecraft/".to_owned() + name;
|
||||
let response = HTTP_CLIENT.get().unwrap()
|
||||
.get(url).send().await?;
|
||||
let status = response.status();
|
||||
let json: JsonValue = response.json().await?;
|
||||
if !status.is_success() || status.as_u16() == 204 {
|
||||
return Err(match json["errorMessage"].as_str() {
|
||||
Some(e) => anyhow!("request failed: {}", e),
|
||||
None => anyhow!("unknown error in request"),
|
||||
})
|
||||
}
|
||||
let uuid = json["id"].as_str().ok_or_else(|| anyhow!("response did not contain id field"))?;
|
||||
Ok(Uuid::parse_str(uuid)?)
|
||||
}
|
||||
|
||||
async fn get_offline_uuid(name: &str) -> Uuid {
|
||||
match fetch_uuid(name).await {
|
||||
Ok(uuid) => {
|
||||
debug!("fetched uuid for {name}: {uuid}");
|
||||
uuid
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("error fetching uuid for {name}: {e}");
|
||||
Uuid::new_v5(&OFFLINE_NAMESPACE, name.as_bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn read_varint_async(r: &mut OwnedReadHalf) -> std::io::Result<Option<i32>> {
|
||||
let mut buf = [0];
|
||||
|
@ -211,7 +237,13 @@ impl ClientState {
|
|||
},
|
||||
pk = self.read_packet() => match pk? {
|
||||
ReadPacketOutcome::Packet(ClientPacket::LoginStart { name, uuid }) => {
|
||||
let uuid = uuid.unwrap_or_else(|| offline_uuid(&name));
|
||||
let uuid = match uuid {
|
||||
Some(uuid) => uuid,
|
||||
None => {
|
||||
debug!("#{} no uuid provided, fetching", self.id);
|
||||
get_offline_uuid(&name).await
|
||||
}
|
||||
};
|
||||
info!("#{} logged in as {name} ({uuid})", self.id);
|
||||
self.write_packet(ServerPacket::LoginSuccess { name: name.clone(), uuid }).await?;
|
||||
self.state = ProtocolState::Play;
|
||||
|
@ -231,7 +263,7 @@ impl ClientState {
|
|||
debug!("#{} entering play", self.id);
|
||||
self.write_packet(ServerPacket::JoinGame {
|
||||
eid: self.id,
|
||||
gamemode: 3,
|
||||
gamemode: 1,
|
||||
hardcode: false,
|
||||
}).await?;
|
||||
|
||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -1,5 +1,6 @@
|
|||
use std::sync::Arc;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
use tokio::sync::Mutex;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -10,7 +11,8 @@ mod ser;
|
|||
mod varint;
|
||||
mod client;
|
||||
|
||||
pub static QC_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub const QC_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub static HTTP_CLIENT: OnceCell<reqwest::Client> = OnceCell::new();
|
||||
|
||||
pub type ArcMutex<T> = Arc<Mutex<T>>;
|
||||
pub type JsonValue = serde_json::Value;
|
||||
|
@ -32,6 +34,10 @@ pub struct ClientInfo {
|
|||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
HTTP_CLIENT.set(reqwest::ClientBuilder::new()
|
||||
.timeout(Duration::from_secs(5))
|
||||
.build().unwrap()
|
||||
).unwrap();
|
||||
server::run_server().await.unwrap()
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ mod v1_19_4;
|
|||
mod v1_18_2;
|
||||
mod v1_17_1;
|
||||
mod v1_16_5;
|
||||
mod v1_15_2;
|
||||
mod v1_14_4;
|
||||
mod v1_13_2;
|
||||
|
||||
pub use common::COMMON as COMMON;
|
||||
|
||||
|
@ -105,6 +108,9 @@ pub const fn get_protocol(version: i32) -> Option<Protocol> {
|
|||
v1_18_2::VERSION => Some(v1_18_2::PROTOCOL),
|
||||
v1_17_1::VERSION => Some(v1_17_1::PROTOCOL),
|
||||
v1_16_5::VERSION => Some(v1_16_5::PROTOCOL),
|
||||
v1_15_2::VERSION => Some(v1_15_2::PROTOCOL),
|
||||
v1_14_4::VERSION => Some(v1_14_4::PROTOCOL),
|
||||
v1_13_2::VERSION => Some(v1_13_2::PROTOCOL),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
124
src/protocol/v1_13_2.rs
Normal file
124
src/protocol/v1_13_2.rs
Normal file
|
@ -0,0 +1,124 @@
|
|||
use std::io::{Write, Read};
|
||||
|
||||
use log::trace;
|
||||
|
||||
use crate::{ser::{Serializable, Deserializable}, varint::VarInt};
|
||||
|
||||
use super::{ServerPacket, ClientPacket, Protocol, ProtocolState, common::COMMON};
|
||||
|
||||
pub const NAME: &str = "1.13.2";
|
||||
pub const VERSION: i32 = 404;
|
||||
|
||||
pub const PROTOCOL: Protocol = Protocol {
|
||||
name: NAME,
|
||||
version: VERSION,
|
||||
encode,
|
||||
decode,
|
||||
};
|
||||
|
||||
fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) -> anyhow::Result<()> {
|
||||
trace!("{NAME} encoding {ev:?}");
|
||||
match ev {
|
||||
ServerPacket::LoginSuccess { name, uuid } => {
|
||||
VarInt(0x02).serialize(&mut w)?;
|
||||
uuid.to_string().serialize(&mut w)?;
|
||||
name.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::ChatMessage(msg, _) => {
|
||||
VarInt(0x0E).serialize(&mut w)?;
|
||||
msg.serialize(&mut w)?;
|
||||
0u8.serialize(&mut w)?; // chat
|
||||
},
|
||||
ServerPacket::SystemMessage(msg, overlay) => {
|
||||
VarInt(0x0E).serialize(&mut w)?;
|
||||
msg.serialize(&mut w)?;
|
||||
if overlay { 2u8 } else { 1u8 } // system or overlay
|
||||
.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::PluginMessage { channel, data } => {
|
||||
VarInt(0x19).serialize(&mut w)?;
|
||||
channel.serialize(&mut w)?;
|
||||
w.write_all(&data)?;
|
||||
},
|
||||
ServerPacket::PlayDisconnect(msg) => {
|
||||
VarInt(0x1B).serialize(&mut w)?;
|
||||
msg.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::KeepAlive(data) => {
|
||||
VarInt(0x21).serialize(&mut w)?;
|
||||
data.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::ChunkData { x, z } => {
|
||||
VarInt(0x22).serialize(&mut w)?;
|
||||
// chunk x
|
||||
x.serialize(&mut w)?;
|
||||
// chunk z
|
||||
z.serialize(&mut w)?;
|
||||
// full chunk
|
||||
true.serialize(&mut w)?;
|
||||
// bit mask
|
||||
VarInt(0).serialize(&mut w)?;
|
||||
// chunk data size and chunk data (biomes)
|
||||
VarInt(256*4).serialize(&mut w)?;
|
||||
[127i32; 256].serialize(&mut w)?;
|
||||
// block entities
|
||||
VarInt(0).serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::JoinGame { eid, gamemode, hardcode } => {
|
||||
VarInt(0x25).serialize(&mut w)?;
|
||||
eid.serialize(&mut w)?;
|
||||
(gamemode | (hardcode as u8) << 3).serialize(&mut w)?;
|
||||
1i32.serialize(&mut w)?; // end dimension
|
||||
2u8.serialize(&mut w)?; // difficulty
|
||||
255u8.serialize(&mut w)?; // max players
|
||||
"default".serialize(&mut w)?; // level type
|
||||
false.serialize(&mut w)?; // reduce debug info
|
||||
}
|
||||
ServerPacket::PositionAndLook { pos, look, flags } => {
|
||||
VarInt(0x32).serialize(&mut w)?;
|
||||
pos.serialize(&mut w)?;
|
||||
look.serialize(&mut w)?;
|
||||
flags.serialize(&mut w)?;
|
||||
VarInt(0).serialize(&mut w)?; // teleport id
|
||||
}
|
||||
ServerPacket::SetDefaultSpawn { pos, angle: _ } => {
|
||||
VarInt(0x49).serialize(&mut w)?;
|
||||
pos.serialize(&mut w)?;
|
||||
},
|
||||
_ => { (COMMON.encode)(w, state, ev)?; }
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn decode(mut r: Box<&mut dyn Read>, state: ProtocolState, len: i32, id: i32) -> anyhow::Result<Option<ClientPacket>> {
|
||||
trace!("{NAME} decoding {state:?} {id}");
|
||||
type Ps = ProtocolState;
|
||||
match (state, id) {
|
||||
(Ps::Login, 0x00) => {
|
||||
let name = String::deserialize(&mut r)?;
|
||||
Ok(Some(ClientPacket::LoginStart { name, uuid: None }))
|
||||
}
|
||||
(Ps::Login, 0x01 | 0x02) => Ok(None), // unsupported
|
||||
(Ps::Play, 0x02) => {
|
||||
let mut msg = String::deserialize(&mut r)?;
|
||||
if msg.starts_with('/') {
|
||||
msg.remove(0);
|
||||
Ok(Some(ClientPacket::Command(msg)))
|
||||
} else {
|
||||
Ok(Some(ClientPacket::ChatMessage(msg)))
|
||||
}
|
||||
},
|
||||
(Ps::Play, 0x0A) => {
|
||||
let channel = String::deserialize(&mut r)?;
|
||||
let mut data = Vec::new();
|
||||
r.read_to_end(&mut data)?;
|
||||
Ok(Some(ClientPacket::PluginMessage { channel, data }))
|
||||
}
|
||||
(Ps::Play, 0x0E) => {
|
||||
let data = i64::deserialize(&mut r)?;
|
||||
Ok(Some(ClientPacket::KeepAlive(data)))
|
||||
}
|
||||
(Ps::Play, 0x10 | 0x11 | 0x12) => Ok(None), // position & rotation
|
||||
_ => (COMMON.decode)(r, state, len, id)
|
||||
}
|
||||
}
|
126
src/protocol/v1_14_4.rs
Normal file
126
src/protocol/v1_14_4.rs
Normal file
|
@ -0,0 +1,126 @@
|
|||
use std::io::{Write, Read};
|
||||
|
||||
use log::trace;
|
||||
|
||||
use crate::{ser::{Serializable, Deserializable}, varint::VarInt};
|
||||
|
||||
use super::{ServerPacket, ClientPacket, Protocol, ProtocolState, common::COMMON};
|
||||
|
||||
pub const NAME: &str = "1.14.4";
|
||||
pub const VERSION: i32 = 498;
|
||||
|
||||
pub const PROTOCOL: Protocol = Protocol {
|
||||
name: NAME,
|
||||
version: VERSION,
|
||||
encode,
|
||||
decode,
|
||||
};
|
||||
|
||||
fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) -> anyhow::Result<()> {
|
||||
trace!("{NAME} encoding {ev:?}");
|
||||
match ev {
|
||||
ServerPacket::LoginSuccess { name, uuid } => {
|
||||
VarInt(0x02).serialize(&mut w)?;
|
||||
uuid.to_string().serialize(&mut w)?;
|
||||
name.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::ChatMessage(msg, _) => {
|
||||
VarInt(0x0E).serialize(&mut w)?;
|
||||
msg.serialize(&mut w)?;
|
||||
0u8.serialize(&mut w)?; // chat
|
||||
},
|
||||
ServerPacket::SystemMessage(msg, overlay) => {
|
||||
VarInt(0x0E).serialize(&mut w)?;
|
||||
msg.serialize(&mut w)?;
|
||||
if overlay { 2u8 } else { 1u8 } // system or overlay
|
||||
.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::PluginMessage { channel, data } => {
|
||||
VarInt(0x18).serialize(&mut w)?;
|
||||
channel.serialize(&mut w)?;
|
||||
w.write_all(&data)?;
|
||||
},
|
||||
ServerPacket::PlayDisconnect(msg) => {
|
||||
VarInt(0x1A).serialize(&mut w)?;
|
||||
msg.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::KeepAlive(data) => {
|
||||
VarInt(0x20).serialize(&mut w)?;
|
||||
data.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::ChunkData { x, z } => {
|
||||
VarInt(0x21).serialize(&mut w)?;
|
||||
// chunk x
|
||||
x.serialize(&mut w)?;
|
||||
// chunk z
|
||||
z.serialize(&mut w)?;
|
||||
// full chunk
|
||||
true.serialize(&mut w)?;
|
||||
// bit mask
|
||||
VarInt(0).serialize(&mut w)?;
|
||||
// heightmap
|
||||
include_bytes!("../resources/heightmap_short.nbt").serialize(&mut w)?;
|
||||
// chunk data size and chunk data (biomes)
|
||||
VarInt(256*4).serialize(&mut w)?;
|
||||
[127i32; 256].serialize(&mut w)?;
|
||||
// block entities
|
||||
VarInt(0).serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::JoinGame { eid, gamemode, hardcode } => {
|
||||
VarInt(0x25).serialize(&mut w)?;
|
||||
eid.serialize(&mut w)?;
|
||||
(gamemode | (hardcode as u8) << 3).serialize(&mut w)?;
|
||||
1i32.serialize(&mut w)?; // end dimension
|
||||
255u8.serialize(&mut w)?; // max players
|
||||
"default".serialize(&mut w)?; // level type
|
||||
VarInt(8).serialize(&mut w)?; // view dist
|
||||
false.serialize(&mut w)?; // reduce debug info
|
||||
}
|
||||
ServerPacket::PositionAndLook { pos, look, flags } => {
|
||||
VarInt(0x35).serialize(&mut w)?;
|
||||
pos.serialize(&mut w)?;
|
||||
look.serialize(&mut w)?;
|
||||
flags.serialize(&mut w)?;
|
||||
VarInt(0).serialize(&mut w)?; // teleport id
|
||||
}
|
||||
ServerPacket::SetDefaultSpawn { pos, angle: _ } => {
|
||||
VarInt(0x4D).serialize(&mut w)?;
|
||||
pos.serialize(&mut w)?;
|
||||
},
|
||||
_ => { (COMMON.encode)(w, state, ev)?; }
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn decode(mut r: Box<&mut dyn Read>, state: ProtocolState, len: i32, id: i32) -> anyhow::Result<Option<ClientPacket>> {
|
||||
trace!("{NAME} decoding {state:?} {id}");
|
||||
type Ps = ProtocolState;
|
||||
match (state, id) {
|
||||
(Ps::Login, 0x00) => {
|
||||
let name = String::deserialize(&mut r)?;
|
||||
Ok(Some(ClientPacket::LoginStart { name, uuid: None }))
|
||||
}
|
||||
(Ps::Login, 0x01 | 0x02) => Ok(None), // unsupported
|
||||
(Ps::Play, 0x03) => {
|
||||
let mut msg = String::deserialize(&mut r)?;
|
||||
if msg.starts_with('/') {
|
||||
msg.remove(0);
|
||||
Ok(Some(ClientPacket::Command(msg)))
|
||||
} else {
|
||||
Ok(Some(ClientPacket::ChatMessage(msg)))
|
||||
}
|
||||
},
|
||||
(Ps::Play, 0x0B) => {
|
||||
let channel = String::deserialize(&mut r)?;
|
||||
let mut data = Vec::new();
|
||||
r.read_to_end(&mut data)?;
|
||||
Ok(Some(ClientPacket::PluginMessage { channel, data }))
|
||||
}
|
||||
(Ps::Play, 0x0F) => {
|
||||
let data = i64::deserialize(&mut r)?;
|
||||
Ok(Some(ClientPacket::KeepAlive(data)))
|
||||
}
|
||||
(Ps::Play, 0x11 | 0x12 | 0x13 | 0x14) => Ok(None), // position & rotation
|
||||
_ => (COMMON.decode)(r, state, len, id)
|
||||
}
|
||||
}
|
129
src/protocol/v1_15_2.rs
Normal file
129
src/protocol/v1_15_2.rs
Normal file
|
@ -0,0 +1,129 @@
|
|||
use std::io::{Write, Read};
|
||||
|
||||
use log::trace;
|
||||
|
||||
use crate::{ser::{Serializable, Deserializable}, varint::VarInt};
|
||||
|
||||
use super::{ServerPacket, ClientPacket, Protocol, ProtocolState, common::COMMON};
|
||||
|
||||
pub const NAME: &str = "1.15.2";
|
||||
pub const VERSION: i32 = 578;
|
||||
|
||||
pub const PROTOCOL: Protocol = Protocol {
|
||||
name: NAME,
|
||||
version: VERSION,
|
||||
encode,
|
||||
decode,
|
||||
};
|
||||
|
||||
fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) -> anyhow::Result<()> {
|
||||
trace!("{NAME} encoding {ev:?}");
|
||||
match ev {
|
||||
ServerPacket::LoginSuccess { name, uuid } => {
|
||||
VarInt(0x02).serialize(&mut w)?;
|
||||
uuid.to_string().serialize(&mut w)?;
|
||||
name.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::ChatMessage(msg, _) => {
|
||||
VarInt(0x0F).serialize(&mut w)?;
|
||||
msg.serialize(&mut w)?;
|
||||
0u8.serialize(&mut w)?; // chat
|
||||
},
|
||||
ServerPacket::SystemMessage(msg, overlay) => {
|
||||
VarInt(0x0F).serialize(&mut w)?;
|
||||
msg.serialize(&mut w)?;
|
||||
if overlay { 2u8 } else { 1u8 } // system or overlay
|
||||
.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::PluginMessage { channel, data } => {
|
||||
VarInt(0x19).serialize(&mut w)?;
|
||||
channel.serialize(&mut w)?;
|
||||
w.write_all(&data)?;
|
||||
},
|
||||
ServerPacket::PlayDisconnect(msg) => {
|
||||
VarInt(0x1B).serialize(&mut w)?;
|
||||
msg.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::KeepAlive(data) => {
|
||||
VarInt(0x21).serialize(&mut w)?;
|
||||
data.serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::ChunkData { x, z } => {
|
||||
VarInt(0x22).serialize(&mut w)?;
|
||||
// chunk x
|
||||
x.serialize(&mut w)?;
|
||||
// chunk z
|
||||
z.serialize(&mut w)?;
|
||||
// full chunk
|
||||
true.serialize(&mut w)?;
|
||||
// bit mask
|
||||
VarInt(0).serialize(&mut w)?;
|
||||
// heightmap
|
||||
include_bytes!("../resources/heightmap_short.nbt").serialize(&mut w)?;
|
||||
// biomes
|
||||
[0i32; 1024].serialize(&mut w)?;
|
||||
// chunk data size and chunk data
|
||||
VarInt(0).serialize(&mut w)?;
|
||||
// block entities
|
||||
VarInt(0).serialize(&mut w)?;
|
||||
},
|
||||
ServerPacket::JoinGame { eid, gamemode, hardcode } => {
|
||||
VarInt(0x26).serialize(&mut w)?;
|
||||
eid.serialize(&mut w)?;
|
||||
(gamemode | (hardcode as u8) << 3).serialize(&mut w)?;
|
||||
1i32.serialize(&mut w)?; // end dimension
|
||||
0i64.serialize(&mut w)?; // seed
|
||||
255u8.serialize(&mut w)?; // max players
|
||||
"default".serialize(&mut w)?; // level type
|
||||
VarInt(8).serialize(&mut w)?; // view dist
|
||||
false.serialize(&mut w)?; // reduce debug info
|
||||
false.serialize(&mut w)?; // respawn screen
|
||||
},
|
||||
ServerPacket::PositionAndLook { pos, look, flags } => {
|
||||
VarInt(0x36).serialize(&mut w)?;
|
||||
pos.serialize(&mut w)?;
|
||||
look.serialize(&mut w)?;
|
||||
flags.serialize(&mut w)?;
|
||||
VarInt(0).serialize(&mut w)?; // teleport id
|
||||
}
|
||||
ServerPacket::SetDefaultSpawn { pos, angle: _ } => {
|
||||
VarInt(0x4E).serialize(&mut w)?;
|
||||
pos.serialize(&mut w)?;
|
||||
},
|
||||
_ => { (COMMON.encode)(w, state, ev)?; }
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn decode(mut r: Box<&mut dyn Read>, state: ProtocolState, len: i32, id: i32) -> anyhow::Result<Option<ClientPacket>> {
|
||||
trace!("{NAME} decoding {state:?} {id}");
|
||||
type Ps = ProtocolState;
|
||||
match (state, id) {
|
||||
(Ps::Login, 0x00) => {
|
||||
let name = String::deserialize(&mut r)?;
|
||||
Ok(Some(ClientPacket::LoginStart { name, uuid: None }))
|
||||
}
|
||||
(Ps::Login, 0x01 | 0x02) => Ok(None), // unsupported
|
||||
(Ps::Play, 0x03) => {
|
||||
let mut msg = String::deserialize(&mut r)?;
|
||||
if msg.starts_with('/') {
|
||||
msg.remove(0);
|
||||
Ok(Some(ClientPacket::Command(msg)))
|
||||
} else {
|
||||
Ok(Some(ClientPacket::ChatMessage(msg)))
|
||||
}
|
||||
},
|
||||
(Ps::Play, 0x0B) => {
|
||||
let channel = String::deserialize(&mut r)?;
|
||||
let mut data = Vec::new();
|
||||
r.read_to_end(&mut data)?;
|
||||
Ok(Some(ClientPacket::PluginMessage { channel, data }))
|
||||
}
|
||||
(Ps::Play, 0x0F) => {
|
||||
let data = i64::deserialize(&mut r)?;
|
||||
Ok(Some(ClientPacket::KeepAlive(data)))
|
||||
}
|
||||
(Ps::Play, 0x11 | 0x12 | 0x13 | 0x14) => Ok(None), // position & rotation
|
||||
_ => (COMMON.decode)(r, state, len, id)
|
||||
}
|
||||
}
|
|
@ -6,17 +6,18 @@ use crate::{ser::{Serializable, Deserializable}, varint::VarInt};
|
|||
|
||||
use super::{ServerPacket, ClientPacket, Protocol, ProtocolState, common::COMMON};
|
||||
|
||||
pub const NAME: &str = "1.16.5";
|
||||
pub const VERSION: i32 = 754;
|
||||
|
||||
pub const PROTOCOL: Protocol = Protocol {
|
||||
name: "1.16.5",
|
||||
name: NAME,
|
||||
version: VERSION,
|
||||
encode,
|
||||
decode,
|
||||
};
|
||||
|
||||
fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) -> anyhow::Result<()> {
|
||||
trace!("1.18.2 encoding {ev:?}");
|
||||
trace!("{NAME} encoding {ev:?}");
|
||||
match ev {
|
||||
ServerPacket::LoginSuccess { name, uuid } => {
|
||||
VarInt(0x02).serialize(&mut w)?;
|
||||
|
@ -60,7 +61,7 @@ fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) ->
|
|||
// bit mask
|
||||
VarInt(0).serialize(&mut w)?;
|
||||
// heightmap
|
||||
include_bytes!("../resources/heightmap.nbt").serialize(&mut w)?;
|
||||
include_bytes!("../resources/heightmap_short.nbt").serialize(&mut w)?;
|
||||
// biomes
|
||||
VarInt(1024).serialize(&mut w)?;
|
||||
[VarInt(127); 1024].serialize(&mut w)?;
|
||||
|
@ -105,7 +106,7 @@ fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) ->
|
|||
}
|
||||
|
||||
fn decode(mut r: Box<&mut dyn Read>, state: ProtocolState, len: i32, id: i32) -> anyhow::Result<Option<ClientPacket>> {
|
||||
trace!("1.18.2 decoding {state:?} {id}");
|
||||
trace!("{NAME} decoding {state:?} {id}");
|
||||
type Ps = ProtocolState;
|
||||
match (state, id) {
|
||||
(Ps::Login, 0x00) => {
|
||||
|
|
|
@ -6,17 +6,18 @@ use crate::{ser::{Serializable, Deserializable}, varint::VarInt};
|
|||
|
||||
use super::{ServerPacket, ClientPacket, Protocol, ProtocolState, common::COMMON};
|
||||
|
||||
pub const NAME: &str = "1.17.1";
|
||||
pub const VERSION: i32 = 756;
|
||||
|
||||
pub const PROTOCOL: Protocol = Protocol {
|
||||
name: "1.17.1",
|
||||
name: NAME,
|
||||
version: VERSION,
|
||||
encode,
|
||||
decode,
|
||||
};
|
||||
|
||||
fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) -> anyhow::Result<()> {
|
||||
trace!("1.18.2 encoding {ev:?}");
|
||||
trace!("{NAME} encoding {ev:?}");
|
||||
match ev {
|
||||
ServerPacket::LoginSuccess { name, uuid } => {
|
||||
VarInt(0x02).serialize(&mut w)?;
|
||||
|
@ -105,7 +106,7 @@ fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) ->
|
|||
}
|
||||
|
||||
fn decode(mut r: Box<&mut dyn Read>, state: ProtocolState, len: i32, id: i32) -> anyhow::Result<Option<ClientPacket>> {
|
||||
trace!("1.18.2 decoding {state:?} {id}");
|
||||
trace!("{NAME} decoding {state:?} {id}");
|
||||
type Ps = ProtocolState;
|
||||
match (state, id) {
|
||||
(Ps::Login, 0x00) => {
|
||||
|
|
|
@ -6,17 +6,18 @@ use crate::{ser::{Serializable, Deserializable}, varint::VarInt};
|
|||
|
||||
use super::{ServerPacket, ClientPacket, Protocol, ProtocolState, common::COMMON};
|
||||
|
||||
pub const NAME: &str = "1.18.2";
|
||||
pub const VERSION: i32 = 758;
|
||||
|
||||
pub const PROTOCOL: Protocol = Protocol {
|
||||
name: "1.18.2",
|
||||
name: NAME,
|
||||
version: VERSION,
|
||||
encode,
|
||||
decode,
|
||||
};
|
||||
|
||||
fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) -> anyhow::Result<()> {
|
||||
trace!("1.18.2 encoding {ev:?}");
|
||||
trace!("{NAME} encoding {ev:?}");
|
||||
match ev {
|
||||
ServerPacket::LoginSuccess { name, uuid } => {
|
||||
VarInt(0x02).serialize(&mut w)?;
|
||||
|
@ -113,7 +114,7 @@ fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) ->
|
|||
}
|
||||
|
||||
fn decode(mut r: Box<&mut dyn Read>, state: ProtocolState, len: i32, id: i32) -> anyhow::Result<Option<ClientPacket>> {
|
||||
trace!("1.18.2 decoding {state:?} {id}");
|
||||
trace!("{NAME} decoding {state:?} {id}");
|
||||
type Ps = ProtocolState;
|
||||
match (state, id) {
|
||||
(Ps::Login, 0x00) => {
|
||||
|
|
|
@ -7,17 +7,18 @@ use crate::{ser::{Serializable, Deserializable}, varint::VarInt};
|
|||
|
||||
use super::{ServerPacket, ClientPacket, Protocol, ProtocolState, common::COMMON};
|
||||
|
||||
pub const NAME: &str = "1.19.4";
|
||||
pub const VERSION: i32 = 762;
|
||||
|
||||
pub const PROTOCOL: Protocol = Protocol {
|
||||
name: "1.19.4",
|
||||
name: NAME,
|
||||
version: VERSION,
|
||||
encode,
|
||||
decode,
|
||||
};
|
||||
|
||||
fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) -> anyhow::Result<()> {
|
||||
trace!("1.19. encoding {ev:?}");
|
||||
trace!("{NAME} encoding {ev:?}");
|
||||
match ev {
|
||||
ServerPacket::LoginSuccess { name, uuid } => {
|
||||
VarInt(0x02).serialize(&mut w)?;
|
||||
|
@ -115,7 +116,7 @@ fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) ->
|
|||
}
|
||||
|
||||
fn decode(mut r: Box<&mut dyn Read>, state: ProtocolState, len: i32, id: i32) -> anyhow::Result<Option<ClientPacket>> {
|
||||
trace!("1.19.4 decoding {state:?} {id}");
|
||||
trace!("{NAME} decoding {state:?} {id}");
|
||||
type Ps = ProtocolState;
|
||||
match (state, id) {
|
||||
(Ps::Login, 0x00) => {
|
||||
|
|
|
@ -7,17 +7,18 @@ use crate::{ser::{Serializable, Deserializable}, varint::VarInt};
|
|||
|
||||
use super::{ServerPacket, ClientPacket, Protocol, ProtocolState, common::COMMON};
|
||||
|
||||
pub const NAME: &str = "1.20.1";
|
||||
pub const VERSION: i32 = 763;
|
||||
|
||||
pub const PROTOCOL: Protocol = Protocol {
|
||||
name: "1.20.1",
|
||||
name: NAME,
|
||||
version: VERSION,
|
||||
encode,
|
||||
decode,
|
||||
};
|
||||
|
||||
fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) -> anyhow::Result<()> {
|
||||
trace!("1.20.1 encoding {ev:?}");
|
||||
trace!("{NAME} encoding {ev:?}");
|
||||
match ev {
|
||||
ServerPacket::LoginSuccess { name, uuid } => {
|
||||
VarInt(0x02).serialize(&mut w)?;
|
||||
|
@ -114,7 +115,7 @@ fn encode(mut w: Box<&mut dyn Write>, state: ProtocolState, ev: ServerPacket) ->
|
|||
}
|
||||
|
||||
fn decode(mut r: Box<&mut dyn Read>, state: ProtocolState, len: i32, id: i32) -> anyhow::Result<Option<ClientPacket>> {
|
||||
trace!("1.20.1 decoding {state:?} {id}");
|
||||
trace!("{NAME} decoding {state:?} {id}");
|
||||
type Ps = ProtocolState;
|
||||
match (state, id) {
|
||||
(Ps::Login, 0x00) => {
|
||||
|
|
BIN
src/resources/heightmap_short.nbt
Normal file
BIN
src/resources/heightmap_short.nbt
Normal file
Binary file not shown.
24
src/ser.rs
24
src/ser.rs
|
@ -214,18 +214,18 @@ impl Deserializable for Uuid {
|
|||
}
|
||||
}
|
||||
|
||||
impl Serializable for nbt::Blob {
|
||||
fn serialize(&self, w: &mut impl Write) -> anyhow::Result<()> {
|
||||
self.to_writer(w)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserializable for nbt::Blob {
|
||||
fn deserialize(r: &mut impl ReadExt) -> anyhow::Result<Self> {
|
||||
Ok(nbt::Blob::from_reader(r)?)
|
||||
}
|
||||
}
|
||||
// impl Serializable for nbt::Blob {
|
||||
// fn serialize(&self, w: &mut impl Write) -> anyhow::Result<()> {
|
||||
// self.to_writer(w)?;
|
||||
// Ok(())
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl Deserializable for nbt::Blob {
|
||||
// fn deserialize(r: &mut impl ReadExt) -> anyhow::Result<Self> {
|
||||
// Ok(nbt::Blob::from_reader(r)?)
|
||||
// }
|
||||
// }
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Position {
|
||||
|
|
|
@ -91,8 +91,8 @@ async fn accept_connection(server: &mut Server, stream: TcpStream, addr: SocketA
|
|||
tokio::spawn(async move {
|
||||
let c_tx2 = gc_tx.clone();
|
||||
match run_client(id, stream, gc_tx, gs_rx).await {
|
||||
Ok(_) => info!("client {id} disconnected"),
|
||||
Err(e) => error!("client {id} error: {e}"),
|
||||
Ok(_) => info!("#{id} disconnected"),
|
||||
Err(e) => error!("#{id} disconnected: {e}"),
|
||||
}
|
||||
c_tx2.send((id, ClientEvent::Disconnect)).await.unwrap();
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue