diff --git a/Cargo.lock b/Cargo.lock index 755d921..f5c2fcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", +] diff --git a/Cargo.toml b/Cargo.toml index 0b16d5a..f0ca663 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/client/mod.rs b/src/client/mod.rs index 256d07f..c85b280 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -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,10 +14,36 @@ pub mod event; type Sender = tokio::sync::mpsc::Sender<(i32, ClientEvent)>; type Receiver = tokio::sync::mpsc::Receiver; +// 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 { - Uuid::new_v5(&OFFLINE_NAMESPACE, name.as_bytes()) +async fn fetch_uuid(name: &str) -> anyhow::Result { + 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> { @@ -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?; diff --git a/src/main.rs b/src/main.rs index 4b5e42c..3936aa4 100644 --- a/src/main.rs +++ b/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 = OnceCell::new(); pub type ArcMutex = Arc>; 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() } diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 3404235..3706127 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -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 { 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, } } diff --git a/src/protocol/v1_13_2.rs b/src/protocol/v1_13_2.rs new file mode 100644 index 0000000..dcaab5a --- /dev/null +++ b/src/protocol/v1_13_2.rs @@ -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> { + 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) + } +} diff --git a/src/protocol/v1_14_4.rs b/src/protocol/v1_14_4.rs new file mode 100644 index 0000000..39750af --- /dev/null +++ b/src/protocol/v1_14_4.rs @@ -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> { + 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) + } +} diff --git a/src/protocol/v1_15_2.rs b/src/protocol/v1_15_2.rs new file mode 100644 index 0000000..84bc055 --- /dev/null +++ b/src/protocol/v1_15_2.rs @@ -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> { + 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) + } +} diff --git a/src/protocol/v1_16_5.rs b/src/protocol/v1_16_5.rs index 7c8a600..e32281f 100644 --- a/src/protocol/v1_16_5.rs +++ b/src/protocol/v1_16_5.rs @@ -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> { - trace!("1.18.2 decoding {state:?} {id}"); + trace!("{NAME} decoding {state:?} {id}"); type Ps = ProtocolState; match (state, id) { (Ps::Login, 0x00) => { diff --git a/src/protocol/v1_17_1.rs b/src/protocol/v1_17_1.rs index be00d9b..ab059c2 100644 --- a/src/protocol/v1_17_1.rs +++ b/src/protocol/v1_17_1.rs @@ -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> { - trace!("1.18.2 decoding {state:?} {id}"); + trace!("{NAME} decoding {state:?} {id}"); type Ps = ProtocolState; match (state, id) { (Ps::Login, 0x00) => { diff --git a/src/protocol/v1_18_2.rs b/src/protocol/v1_18_2.rs index 2207619..3143f29 100644 --- a/src/protocol/v1_18_2.rs +++ b/src/protocol/v1_18_2.rs @@ -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> { - trace!("1.18.2 decoding {state:?} {id}"); + trace!("{NAME} decoding {state:?} {id}"); type Ps = ProtocolState; match (state, id) { (Ps::Login, 0x00) => { diff --git a/src/protocol/v1_19_4.rs b/src/protocol/v1_19_4.rs index 7dae692..2283d44 100644 --- a/src/protocol/v1_19_4.rs +++ b/src/protocol/v1_19_4.rs @@ -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> { - trace!("1.19.4 decoding {state:?} {id}"); + trace!("{NAME} decoding {state:?} {id}"); type Ps = ProtocolState; match (state, id) { (Ps::Login, 0x00) => { diff --git a/src/protocol/v1_20_1.rs b/src/protocol/v1_20_1.rs index 7aa6268..806ad4a 100644 --- a/src/protocol/v1_20_1.rs +++ b/src/protocol/v1_20_1.rs @@ -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> { - trace!("1.20.1 decoding {state:?} {id}"); + trace!("{NAME} decoding {state:?} {id}"); type Ps = ProtocolState; match (state, id) { (Ps::Login, 0x00) => { diff --git a/src/resources/heightmap_short.nbt b/src/resources/heightmap_short.nbt new file mode 100644 index 0000000..1e1dabd Binary files /dev/null and b/src/resources/heightmap_short.nbt differ diff --git a/src/ser.rs b/src/ser.rs index 233709f..d033656 100644 --- a/src/ser.rs +++ b/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 { - 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 { +// Ok(nbt::Blob::from_reader(r)?) +// } +// } #[derive(Clone, Copy, Debug)] pub struct Position { diff --git a/src/server.rs b/src/server.rs index 03ccafb..a2b154a 100644 --- a/src/server.rs +++ b/src/server.rs @@ -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(); });