Extract packets into composition-protocol crate and make into workspace
This commit is contained in:
parent
cc68d3a942
commit
e591cd8a4d
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,5 +1,5 @@
|
||||
.DS_Store
|
||||
/output.log
|
||||
/target
|
||||
/world
|
||||
composition/output.log
|
||||
target
|
||||
composition/world
|
||||
/.cargo
|
||||
|
637
Cargo.lock
generated
637
Cargo.lock
generated
@ -9,10 +9,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.56"
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
@ -20,24 +29,13 @@ version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
@ -54,6 +52,12 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
@ -62,15 +66,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.1.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
||||
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
@ -92,17 +96,29 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.19"
|
||||
version = "0.4.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||
checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"time",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
|
||||
dependencies = [
|
||||
"termcolor",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "1.9.3"
|
||||
@ -118,11 +134,18 @@ dependencies = [
|
||||
name = "composition"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"composition-core",
|
||||
"log",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "composition-core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"ctrlc",
|
||||
"fern",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"quartz_nbt",
|
||||
@ -135,6 +158,22 @@ dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "composition-protocol"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"nom",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
@ -146,12 +185,56 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "3.2.1"
|
||||
version = "3.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf"
|
||||
checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a140f260e6f3f79013b8bfc65e7ce630c9ab4388c6a89c71e07226f49487b72"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
"cxxbridge-macro",
|
||||
"link-cplusplus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx-build"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da6383f459341ea689374bf0a42979739dc421874f112ff26f829b8040b8e613"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"codespan-reporting",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"scratch",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90201c1a650e95ccff1c8c0bb5a343213bdd317c6e600a93075bca2eff54ec97"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -166,105 +249,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.23"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af"
|
||||
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
@ -275,10 +267,52 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.1"
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
|
||||
dependencies = [
|
||||
"cxx",
|
||||
"cxx-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
@ -288,15 +322,24 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.123"
|
||||
version = "0.2.139"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.7"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
|
||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
@ -304,87 +347,73 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.16"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.5.1"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082"
|
||||
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.2"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
|
||||
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"miow",
|
||||
"ntapi",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.23.1"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
|
||||
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"memoffset",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.7"
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
@ -392,34 +421,43 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.2.6",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.10.0"
|
||||
version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "packet_logger"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"composition-protocol",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
@ -427,9 +465,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.2"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37"
|
||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
@ -440,23 +478,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.8"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.37"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
|
||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -486,9 +518,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.18"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -505,18 +537,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.13"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.9"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
@ -525,19 +557,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.136"
|
||||
name = "scratch"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
|
||||
checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.136"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
|
||||
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -546,9 +584,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.79"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95"
|
||||
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@ -557,35 +595,35 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.8.0"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.4"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
|
||||
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "substring"
|
||||
version = "1.4.5"
|
||||
@ -597,20 +635,49 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.91"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.44"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
@ -619,29 +686,29 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.17.0"
|
||||
version = "1.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee"
|
||||
checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "1.7.0"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
|
||||
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -650,18 +717,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.9"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
name = "unicode-ident"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
checksum = "775c11906edafc97bc378816b94585fbd9a054eabaf86fdd0ced94af449efab7"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
@ -681,6 +754,60 @@ 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.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@ -697,6 +824,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
@ -705,43 +841,66 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.34.0"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.34.0"
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d"
|
||||
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.34.0"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed"
|
||||
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.34.0"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956"
|
||||
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.34.0"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4"
|
||||
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.34.0"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9"
|
||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
||||
|
36
Cargo.toml
36
Cargo.toml
@ -1,33 +1,15 @@
|
||||
[workspace]
|
||||
members = [ "crates/*", "crates/*/examples/*" ]
|
||||
|
||||
[package]
|
||||
authors = ["Garen Tyler <garentyler@garen.dev>"]
|
||||
description = "An extremely fast Minecraft server"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "composition"
|
||||
version = "0.1.0"
|
||||
build = "build.rs"
|
||||
edition = "2021"
|
||||
authors = ["Garen Tyler <garentyler@garen.dev>"]
|
||||
description = "An extremely fast Minecraft server"
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1.48"
|
||||
chrono = "0.4.13"
|
||||
ctrlc = "3.1.8"
|
||||
# fastnbt = "*"
|
||||
fern = {version = "0.6", features = ["colored"]}
|
||||
futures = "0.3.13"
|
||||
lazy_static = "1.4.0"
|
||||
composition-core = { path = "./crates/composition-core" }
|
||||
log = "0.4"
|
||||
radix64 = "0.6.2"
|
||||
serde = {version = "1.0.114", features = ["serde_derive"]}
|
||||
serde_json = "1.0.59"
|
||||
tokio = {version = "1", features = ["full"]}
|
||||
toml = "0.5"
|
||||
uuid = "0.8.2"
|
||||
substring = "1.4.5"
|
||||
quartz_nbt = {version = "0.2.6", features = ["serde"]}
|
||||
|
||||
# colorful = "0.2.1"
|
||||
# ozelot = "0.9.0" # Ozelot 0.9.0 supports protocol version 578 (1.15.2)
|
||||
# toml = "0.5.6"
|
||||
# base64 = "0.12.3"
|
||||
# mojang-api = "0.6.1"
|
||||
# backtrace = "0.3.50"
|
||||
tokio = "1"
|
||||
|
31
crates/composition-core/Cargo.toml
Normal file
31
crates/composition-core/Cargo.toml
Normal file
@ -0,0 +1,31 @@
|
||||
[package]
|
||||
name = "composition-core"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4.13"
|
||||
ctrlc = "3.1.8"
|
||||
fern = { version = "0.6", features = ["colored"] }
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4"
|
||||
quartz_nbt = { version = "0.2.6", features = ["serde"] }
|
||||
radix64 = "0.6.2"
|
||||
serde = { version = "1.0.114", features = ["serde_derive"] }
|
||||
serde_json = "1.0.59"
|
||||
substring = "1.4.5"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
toml = "0.5"
|
||||
uuid = "0.8.2"
|
||||
|
||||
# async-trait = "0.1.48"
|
||||
# backtrace = "0.3.50"
|
||||
# base64 = "0.12.3"
|
||||
# colorful = "0.2.1"
|
||||
# composition-protocol = { path = "../composition-protocol" }
|
||||
# fastnbt = "*"
|
||||
# futures = "0.3.13"
|
||||
# mojang-api = "0.6.1"
|
||||
# ozelot = "0.9.0" # Ozelot 0.9.0 supports protocol version 578 (1.15.2)
|
||||
# toml = "0.5.6"
|
@ -32,7 +32,7 @@ impl Default for Config {
|
||||
max_players: 20,
|
||||
motd: "Hello world!".to_owned(),
|
||||
server_icon: "server-icon.png".to_owned(),
|
||||
server_icon_bytes: include_bytes!("../server-icon.png").to_vec(),
|
||||
server_icon_bytes: include_bytes!("./server-icon.png").to_vec(),
|
||||
server_string: server_version.clone(),
|
||||
log_level: if cfg!(debug_assertions) {
|
||||
log::LevelFilter::Debug
|
BIN
crates/composition-core/src/server-icon.png
Normal file
BIN
crates/composition-core/src/server-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
14
crates/composition-protocol/Cargo.toml
Normal file
14
crates/composition-protocol/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "composition-protocol"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
nom = "7"
|
||||
serde_json = "1.0.94"
|
||||
anyhow = "1.0.69"
|
||||
thiserror = "1.0.39"
|
||||
|
||||
[[example]]
|
||||
name = "packet_logger"
|
||||
path = "examples/packet_logger/src/main.rs"
|
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "packet_logger"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.69"
|
||||
composition-protocol = { path = "../../" }
|
||||
tokio = { version = "1.26.0", features = [ "full" ] }
|
117
crates/composition-protocol/examples/packet_logger/src/main.rs
Normal file
117
crates/composition-protocol/examples/packet_logger/src/main.rs
Normal file
@ -0,0 +1,117 @@
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let listener = TcpListener::bind("0.0.0.0:25566").await?;
|
||||
|
||||
println!("Proxy listening on port 25566, expecting server at 25565");
|
||||
|
||||
loop {
|
||||
let (stream, _) = listener.accept().await?;
|
||||
process_client(stream).await?;
|
||||
}
|
||||
}
|
||||
|
||||
async fn process_client(client: TcpStream) -> anyhow::Result<()> {
|
||||
use composition_protocol::packet::GenericPacket;
|
||||
client.readable().await?;
|
||||
println!("Client connected");
|
||||
let server = TcpStream::connect("localhost:25565").await?;
|
||||
server.writable().await?;
|
||||
println!("Server connected");
|
||||
|
||||
let mut client_state = composition_protocol::ClientState::Handshake;
|
||||
let mut last_client_data_time = std::time::Instant::now();
|
||||
let mut last_client_data = vec![];
|
||||
let mut last_server_data_time = std::time::Instant::now();
|
||||
let mut last_server_data = vec![];
|
||||
|
||||
loop {
|
||||
let bytes = copy_bytes(&client, &server).await?;
|
||||
if !bytes.is_empty() {
|
||||
last_client_data_time = std::time::Instant::now();
|
||||
last_client_data.extend_from_slice(&bytes);
|
||||
|
||||
if let Ok((d, packet)) =
|
||||
GenericPacket::parse_uncompressed(&client_state, true, &last_client_data)
|
||||
{
|
||||
last_client_data = d.to_vec();
|
||||
println!("C -> S: {:?}", packet);
|
||||
match packet {
|
||||
GenericPacket::SH00Handshake(handshake) => {
|
||||
client_state = handshake.next_state;
|
||||
}
|
||||
GenericPacket::CP17Disconnect(_) => {
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let bytes = copy_bytes(&server, &client).await?;
|
||||
if !bytes.is_empty() {
|
||||
last_server_data_time = std::time::Instant::now();
|
||||
last_server_data.extend_from_slice(&bytes);
|
||||
|
||||
if let Ok((d, packet)) =
|
||||
GenericPacket::parse_uncompressed(&client_state, false, &last_server_data)
|
||||
{
|
||||
last_server_data = d.to_vec();
|
||||
println!("S -> C: {:?}", packet);
|
||||
match packet {
|
||||
GenericPacket::CS01PingResponse(_) | GenericPacket::CL00Disconnect(_) => {
|
||||
break;
|
||||
}
|
||||
GenericPacket::CL02LoginSuccess(_) => {
|
||||
client_state = composition_protocol::ClientState::Play;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if last_client_data_time.elapsed() > std::time::Duration::from_secs(10)
|
||||
|| last_server_data_time.elapsed() > std::time::Duration::from_secs(10)
|
||||
{
|
||||
println!("timed out");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn copy_bytes(from: &TcpStream, to: &TcpStream) -> anyhow::Result<Vec<u8>> {
|
||||
let mut bytes = vec![];
|
||||
|
||||
loop {
|
||||
// Read 8kb at a time
|
||||
let mut buf = vec![0u8; 8192];
|
||||
|
||||
let num_bytes = match from.try_read(&mut buf) {
|
||||
Ok(0) => break,
|
||||
Ok(n) => n,
|
||||
Err(ref e) if e.kind() == tokio::io::ErrorKind::WouldBlock => {
|
||||
break;
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(e.into());
|
||||
}
|
||||
};
|
||||
|
||||
bytes.extend_from_slice(&buf[0..num_bytes]);
|
||||
|
||||
match to.try_write(&buf[0..num_bytes]) {
|
||||
Ok(_n) => {}
|
||||
Err(ref e) if e.kind() == tokio::io::ErrorKind::WouldBlock => {
|
||||
break;
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(e.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(bytes)
|
||||
}
|
56
crates/composition-protocol/src/lib.rs
Normal file
56
crates/composition-protocol/src/lib.rs
Normal file
@ -0,0 +1,56 @@
|
||||
pub mod packet;
|
||||
pub mod util;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
pub type Json = serde_json::Value;
|
||||
pub type Chat = Json;
|
||||
pub type Uuid = u128;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ClientState {
|
||||
Handshake,
|
||||
Status,
|
||||
Login,
|
||||
Play,
|
||||
Disconnected,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Difficulty {
|
||||
Peaceful = 0,
|
||||
Easy = 1,
|
||||
Normal = 2,
|
||||
Hard = 3,
|
||||
}
|
||||
impl TryFrom<u8> for Difficulty {
|
||||
type Error = ();
|
||||
fn try_from(value: u8) -> std::result::Result<Self, Self::Error> {
|
||||
match value {
|
||||
0 => Ok(Difficulty::Peaceful),
|
||||
1 => Ok(Difficulty::Easy),
|
||||
2 => Ok(Difficulty::Normal),
|
||||
3 => Ok(Difficulty::Hard),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ProtocolError {
|
||||
#[error("invalid packet data")]
|
||||
InvalidPacket,
|
||||
#[error("not enough data")]
|
||||
NotEnoughData,
|
||||
#[error("unexpected end of file")]
|
||||
UnexpectedEOF,
|
||||
#[error("stream timed out")]
|
||||
Timeout,
|
||||
#[error("communicating to disconnected client")]
|
||||
Disconnected,
|
||||
#[error(transparent)]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
#[error(transparent)]
|
||||
Other(#[from] anyhow::Error),
|
||||
}
|
||||
pub type Result<T> = std::result::Result<T, ProtocolError>;
|
308
crates/composition-protocol/src/packet/clientbound/login.rs
Normal file
308
crates/composition-protocol/src/packet/clientbound/login.rs
Normal file
@ -0,0 +1,308 @@
|
||||
use crate::{
|
||||
packet::{GenericPacket, Packet, PacketId},
|
||||
util::{
|
||||
parse_json, parse_string, parse_uuid, parse_varint, serialize_json, serialize_string,
|
||||
serialize_uuid, serialize_varint,
|
||||
},
|
||||
Chat, Uuid,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CL00Disconnect {
|
||||
reason: Chat,
|
||||
}
|
||||
impl Packet for CL00Disconnect {
|
||||
fn id() -> PacketId {
|
||||
0x00
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Login
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, reason) = parse_json(data)?;
|
||||
Ok((data, CL00Disconnect { reason }))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
serialize_json(&self.reason)
|
||||
}
|
||||
}
|
||||
impl From<CL00Disconnect> for GenericPacket {
|
||||
fn from(value: CL00Disconnect) -> Self {
|
||||
GenericPacket::CL00Disconnect(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CL00Disconnect {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CL00Disconnect(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CL01EncryptionRequest {
|
||||
server_id: String,
|
||||
public_key: Vec<u8>,
|
||||
verify_token: Vec<u8>,
|
||||
}
|
||||
impl Packet for CL01EncryptionRequest {
|
||||
fn id() -> PacketId {
|
||||
0x01
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Login
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, server_id) = parse_string(data)?;
|
||||
let (data, public_key_len) = parse_varint(data)?;
|
||||
let (data, public_key) = nom::bytes::streaming::take(public_key_len as usize)(data)?;
|
||||
let (data, verify_token_len) = parse_varint(data)?;
|
||||
let (data, verify_token) = nom::bytes::streaming::take(verify_token_len as usize)(data)?;
|
||||
|
||||
Ok((
|
||||
data,
|
||||
CL01EncryptionRequest {
|
||||
server_id,
|
||||
public_key: public_key.to_vec(),
|
||||
verify_token: verify_token.to_vec(),
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_string(&self.server_id));
|
||||
output.extend_from_slice(&serialize_varint(self.public_key.len() as i32));
|
||||
output.extend_from_slice(&self.public_key);
|
||||
output.extend_from_slice(&serialize_varint(self.verify_token.len() as i32));
|
||||
output.extend_from_slice(&self.verify_token);
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<CL01EncryptionRequest> for GenericPacket {
|
||||
fn from(value: CL01EncryptionRequest) -> Self {
|
||||
GenericPacket::CL01EncryptionRequest(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CL01EncryptionRequest {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CL01EncryptionRequest(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CL02LoginSuccess {
|
||||
uuid: Uuid,
|
||||
username: String,
|
||||
properties: Vec<CL02LoginSuccessProperty>,
|
||||
}
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CL02LoginSuccessProperty {
|
||||
name: String,
|
||||
value: String,
|
||||
signature: Option<String>,
|
||||
}
|
||||
impl CL02LoginSuccessProperty {
|
||||
pub fn parse(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, name) = parse_string(data)?;
|
||||
let (data, value) = parse_string(data)?;
|
||||
let (data, is_signed) = nom::bytes::streaming::take(1usize)(data)?;
|
||||
if is_signed == [0x01] {
|
||||
let (data, signature) = parse_string(data)?;
|
||||
Ok((
|
||||
data,
|
||||
CL02LoginSuccessProperty {
|
||||
name,
|
||||
value,
|
||||
signature: Some(signature),
|
||||
},
|
||||
))
|
||||
} else {
|
||||
Ok((
|
||||
data,
|
||||
CL02LoginSuccessProperty {
|
||||
name,
|
||||
value,
|
||||
signature: None,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_string(&self.name));
|
||||
output.extend_from_slice(&serialize_string(&self.value));
|
||||
match &self.signature {
|
||||
Some(signature) => {
|
||||
output.push(0x01);
|
||||
output.extend_from_slice(&serialize_string(signature));
|
||||
}
|
||||
None => output.push(0x00),
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
impl Packet for CL02LoginSuccess {
|
||||
fn id() -> PacketId {
|
||||
0x02
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Login
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, uuid) = parse_uuid(data)?;
|
||||
let (data, username) = parse_string(data)?;
|
||||
let (mut data, properties_len) = parse_varint(data)?;
|
||||
let mut properties = Vec::with_capacity(properties_len as usize);
|
||||
for _ in 0..properties_len {
|
||||
let (d, property) = CL02LoginSuccessProperty::parse(data)?;
|
||||
data = d;
|
||||
properties.push(property);
|
||||
}
|
||||
|
||||
Ok((
|
||||
data,
|
||||
CL02LoginSuccess {
|
||||
uuid,
|
||||
username,
|
||||
properties,
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_uuid(&self.uuid));
|
||||
output.extend_from_slice(&serialize_string(&self.username));
|
||||
output.extend_from_slice(&serialize_varint(self.properties.len() as i32));
|
||||
for property in &self.properties {
|
||||
output.extend_from_slice(&property.serialize());
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<CL02LoginSuccess> for GenericPacket {
|
||||
fn from(value: CL02LoginSuccess) -> Self {
|
||||
GenericPacket::CL02LoginSuccess(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CL02LoginSuccess {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CL02LoginSuccess(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CL03SetCompression {
|
||||
threshold: i32,
|
||||
}
|
||||
impl Packet for CL03SetCompression {
|
||||
fn id() -> PacketId {
|
||||
0x03
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Login
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, threshold) = parse_varint(data)?;
|
||||
Ok((data, CL03SetCompression { threshold }))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
serialize_varint(self.threshold)
|
||||
}
|
||||
}
|
||||
impl From<CL03SetCompression> for GenericPacket {
|
||||
fn from(value: CL03SetCompression) -> Self {
|
||||
GenericPacket::CL03SetCompression(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CL03SetCompression {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CL03SetCompression(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CL04LoginPluginRequest {
|
||||
message_id: i32,
|
||||
channel: String,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
impl Packet for CL04LoginPluginRequest {
|
||||
fn id() -> PacketId {
|
||||
0x04
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Login
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, message_id) = parse_varint(data)?;
|
||||
let (data, channel) = parse_string(data)?;
|
||||
Ok((
|
||||
data,
|
||||
CL04LoginPluginRequest {
|
||||
message_id,
|
||||
channel,
|
||||
data: data.to_vec(),
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_varint(self.message_id));
|
||||
output.extend_from_slice(&serialize_string(&self.channel));
|
||||
output.extend_from_slice(&self.data);
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<CL04LoginPluginRequest> for GenericPacket {
|
||||
fn from(value: CL04LoginPluginRequest) -> Self {
|
||||
GenericPacket::CL04LoginPluginRequest(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CL04LoginPluginRequest {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CL04LoginPluginRequest(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
pub mod login;
|
||||
pub mod play;
|
||||
pub mod status;
|
||||
|
||||
pub use login::*;
|
||||
pub use play::*;
|
||||
pub use status::*;
|
494
crates/composition-protocol/src/packet/clientbound/play.rs
Normal file
494
crates/composition-protocol/src/packet/clientbound/play.rs
Normal file
@ -0,0 +1,494 @@
|
||||
use crate::{
|
||||
packet::{GenericPacket, Packet, PacketId},
|
||||
util::{
|
||||
parse_json, parse_uuid, parse_varint, serialize_json, serialize_uuid, serialize_varint,
|
||||
Position,
|
||||
},
|
||||
Chat, Difficulty, Uuid,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CP00SpawnEntity {
|
||||
entity_id: i32,
|
||||
entity_uuid: Uuid,
|
||||
kind: i32,
|
||||
x: f64,
|
||||
y: f64,
|
||||
z: f64,
|
||||
pitch: u8,
|
||||
yaw: u8,
|
||||
head_yaw: u8,
|
||||
data: i32,
|
||||
velocity_x: i16,
|
||||
velocity_y: i16,
|
||||
velocity_z: i16,
|
||||
}
|
||||
impl Packet for CP00SpawnEntity {
|
||||
fn id() -> PacketId {
|
||||
0x00
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, entity_id) = parse_varint(data)?;
|
||||
let (data, entity_uuid) = parse_uuid(data)?;
|
||||
let (data, kind) = parse_varint(data)?;
|
||||
let (data, x) = nom::number::streaming::be_f64(data)?;
|
||||
let (data, y) = nom::number::streaming::be_f64(data)?;
|
||||
let (data, z) = nom::number::streaming::be_f64(data)?;
|
||||
let (data, t) = nom::bytes::streaming::take(3usize)(data)?;
|
||||
let (data, d) = parse_varint(data)?;
|
||||
let (data, velocity_x) = nom::number::streaming::be_i16(data)?;
|
||||
let (data, velocity_y) = nom::number::streaming::be_i16(data)?;
|
||||
let (data, velocity_z) = nom::number::streaming::be_i16(data)?;
|
||||
Ok((
|
||||
data,
|
||||
CP00SpawnEntity {
|
||||
entity_id,
|
||||
entity_uuid,
|
||||
kind,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
pitch: t[0],
|
||||
yaw: t[1],
|
||||
head_yaw: t[2],
|
||||
data: d,
|
||||
velocity_x,
|
||||
velocity_y,
|
||||
velocity_z,
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_varint(self.entity_id));
|
||||
output.extend_from_slice(&serialize_uuid(&self.entity_uuid));
|
||||
output.extend_from_slice(&serialize_varint(self.kind));
|
||||
output.extend_from_slice(&self.x.to_be_bytes());
|
||||
output.extend_from_slice(&self.y.to_be_bytes());
|
||||
output.extend_from_slice(&self.z.to_be_bytes());
|
||||
output.push(self.pitch);
|
||||
output.push(self.yaw);
|
||||
output.push(self.head_yaw);
|
||||
output.extend_from_slice(&serialize_varint(self.data));
|
||||
output.extend_from_slice(&self.velocity_x.to_be_bytes());
|
||||
output.extend_from_slice(&self.velocity_y.to_be_bytes());
|
||||
output.extend_from_slice(&self.velocity_z.to_be_bytes());
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<CP00SpawnEntity> for GenericPacket {
|
||||
fn from(value: CP00SpawnEntity) -> Self {
|
||||
GenericPacket::CP00SpawnEntity(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CP00SpawnEntity {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CP00SpawnEntity(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CP0BChangeDifficulty {
|
||||
difficulty: Difficulty,
|
||||
is_locked: bool,
|
||||
}
|
||||
impl Packet for CP0BChangeDifficulty {
|
||||
fn id() -> PacketId {
|
||||
0x0b
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, difficulty) = nom::number::streaming::be_u8(data)?;
|
||||
let difficulty: Difficulty = difficulty
|
||||
.try_into()
|
||||
.expect("TODO: handle incorrect difficulty");
|
||||
let (data, is_locked) = nom::number::streaming::be_u8(data)?;
|
||||
let is_locked = is_locked > 0;
|
||||
Ok((
|
||||
data,
|
||||
CP0BChangeDifficulty {
|
||||
difficulty,
|
||||
is_locked,
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.push(self.difficulty as u8);
|
||||
output.push(if self.is_locked { 0x01 } else { 0x00 });
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<CP0BChangeDifficulty> for GenericPacket {
|
||||
fn from(value: CP0BChangeDifficulty) -> Self {
|
||||
GenericPacket::CP0BChangeDifficulty(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CP0BChangeDifficulty {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CP0BChangeDifficulty(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CP17Disconnect {
|
||||
reason: Chat,
|
||||
}
|
||||
impl Packet for CP17Disconnect {
|
||||
fn id() -> PacketId {
|
||||
0x17
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, reason) = parse_json(data)?;
|
||||
Ok((data, CP17Disconnect { reason }))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
serialize_json(&self.reason)
|
||||
}
|
||||
}
|
||||
impl From<CP17Disconnect> for GenericPacket {
|
||||
fn from(value: CP17Disconnect) -> Self {
|
||||
GenericPacket::CP17Disconnect(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CP17Disconnect {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CP17Disconnect(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct CP1FKeepAlive {
|
||||
payload: i64,
|
||||
}
|
||||
impl Packet for CP1FKeepAlive {
|
||||
fn id() -> PacketId {
|
||||
0x1f
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, payload) = nom::number::streaming::be_i64(data)?;
|
||||
Ok((data, CP1FKeepAlive { payload }))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
self.payload.to_be_bytes().to_vec()
|
||||
}
|
||||
}
|
||||
impl From<CP1FKeepAlive> for GenericPacket {
|
||||
fn from(value: CP1FKeepAlive) -> Self {
|
||||
GenericPacket::CP1FKeepAlive(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CP1FKeepAlive {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CP1FKeepAlive(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct CP21WorldEvent {
|
||||
event: i32,
|
||||
location: Position,
|
||||
data: i32,
|
||||
disable_relative_volume: bool,
|
||||
}
|
||||
impl Packet for CP21WorldEvent {
|
||||
fn id() -> PacketId {
|
||||
0x21
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, event) = nom::number::streaming::be_i32(data)?;
|
||||
let (data, location) = Position::parse(data)?;
|
||||
let (data, d) = nom::number::streaming::be_i32(data)?;
|
||||
let (data, disable_relative_volume) = nom::bytes::streaming::take(1usize)(data)?;
|
||||
let disable_relative_volume = disable_relative_volume == [0x01];
|
||||
Ok((
|
||||
data,
|
||||
CP21WorldEvent {
|
||||
event,
|
||||
location,
|
||||
data: d,
|
||||
disable_relative_volume,
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&self.event.to_be_bytes());
|
||||
output.extend_from_slice(&self.location.serialize());
|
||||
output.extend_from_slice(&self.data.to_be_bytes());
|
||||
output.push(if self.disable_relative_volume {
|
||||
0x01
|
||||
} else {
|
||||
0x00
|
||||
});
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<CP21WorldEvent> for GenericPacket {
|
||||
fn from(value: CP21WorldEvent) -> Self {
|
||||
GenericPacket::CP21WorldEvent(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CP21WorldEvent {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CP21WorldEvent(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CP50SetEntityVelocity {
|
||||
entity_id: i32,
|
||||
velocity_x: i16,
|
||||
velocity_y: i16,
|
||||
velocity_z: i16,
|
||||
}
|
||||
impl Packet for CP50SetEntityVelocity {
|
||||
fn id() -> PacketId {
|
||||
0x50
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, entity_id) = parse_varint(data)?;
|
||||
let (data, velocity_x) = nom::number::streaming::be_i16(data)?;
|
||||
let (data, velocity_y) = nom::number::streaming::be_i16(data)?;
|
||||
let (data, velocity_z) = nom::number::streaming::be_i16(data)?;
|
||||
Ok((
|
||||
data,
|
||||
CP50SetEntityVelocity {
|
||||
entity_id,
|
||||
velocity_x,
|
||||
velocity_y,
|
||||
velocity_z,
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_varint(self.entity_id));
|
||||
output.extend_from_slice(&self.velocity_x.to_be_bytes());
|
||||
output.extend_from_slice(&self.velocity_y.to_be_bytes());
|
||||
output.extend_from_slice(&self.velocity_z.to_be_bytes());
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<CP50SetEntityVelocity> for GenericPacket {
|
||||
fn from(value: CP50SetEntityVelocity) -> Self {
|
||||
GenericPacket::CP50SetEntityVelocity(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CP50SetEntityVelocity {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CP50SetEntityVelocity(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CP52SetExperience {
|
||||
experience_bar: f32,
|
||||
total_experience: i32,
|
||||
level: i32,
|
||||
}
|
||||
impl Packet for CP52SetExperience {
|
||||
fn id() -> PacketId {
|
||||
0x52
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, experience_bar) = nom::number::streaming::be_f32(data)?;
|
||||
let (data, total_experience) = parse_varint(data)?;
|
||||
let (data, level) = parse_varint(data)?;
|
||||
Ok((
|
||||
data,
|
||||
CP52SetExperience {
|
||||
experience_bar,
|
||||
total_experience,
|
||||
level,
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&self.experience_bar.to_be_bytes());
|
||||
output.extend_from_slice(&serialize_varint(self.total_experience));
|
||||
output.extend_from_slice(&serialize_varint(self.level));
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<CP52SetExperience> for GenericPacket {
|
||||
fn from(value: CP52SetExperience) -> Self {
|
||||
GenericPacket::CP52SetExperience(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CP52SetExperience {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CP52SetExperience(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CP68EntityEffect {
|
||||
entity_id: i32,
|
||||
effect_id: i32,
|
||||
amplifier: i8,
|
||||
duration: i32,
|
||||
is_ambient: bool,
|
||||
show_particles: bool,
|
||||
show_icon: bool,
|
||||
has_factor_data: bool,
|
||||
// TODO: factor_codec: NBT
|
||||
}
|
||||
impl Packet for CP68EntityEffect {
|
||||
fn id() -> PacketId {
|
||||
0x68
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, entity_id) = parse_varint(data)?;
|
||||
let (data, effect_id) = parse_varint(data)?;
|
||||
let (data, amplifier) = nom::number::streaming::be_i8(data)?;
|
||||
let (data, duration) = parse_varint(data)?;
|
||||
let (data, flags) = nom::number::streaming::be_i8(data)?;
|
||||
let is_ambient = flags & 0x01 > 0;
|
||||
let show_particles = flags & 0x02 > 0;
|
||||
let show_icon = flags & 0x04 > 0;
|
||||
let (data, has_factor_data) = nom::number::streaming::be_u8(data)?;
|
||||
let has_factor_data = has_factor_data > 0;
|
||||
// TODO: factor_codec
|
||||
|
||||
Ok((
|
||||
data,
|
||||
CP68EntityEffect {
|
||||
entity_id,
|
||||
effect_id,
|
||||
amplifier,
|
||||
duration,
|
||||
is_ambient,
|
||||
show_particles,
|
||||
show_icon,
|
||||
has_factor_data,
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_varint(self.entity_id));
|
||||
output.extend_from_slice(&serialize_varint(self.effect_id));
|
||||
output.push(self.amplifier as u8);
|
||||
output.extend_from_slice(&serialize_varint(self.duration));
|
||||
let mut flags = 0x00i8;
|
||||
if self.is_ambient {
|
||||
flags |= 0x01;
|
||||
}
|
||||
if self.show_particles {
|
||||
flags |= 0x02;
|
||||
}
|
||||
if self.show_icon {
|
||||
flags |= 0x04;
|
||||
}
|
||||
output.push(flags as u8);
|
||||
// TODO: factor_codec
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<CP68EntityEffect> for GenericPacket {
|
||||
fn from(value: CP68EntityEffect) -> Self {
|
||||
GenericPacket::CP68EntityEffect(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CP68EntityEffect {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CP68EntityEffect(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
83
crates/composition-protocol/src/packet/clientbound/status.rs
Normal file
83
crates/composition-protocol/src/packet/clientbound/status.rs
Normal file
@ -0,0 +1,83 @@
|
||||
use crate::{
|
||||
packet::{GenericPacket, Packet, PacketId},
|
||||
util::{parse_json, serialize_json},
|
||||
Json,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct CS00StatusResponse {
|
||||
response: Json,
|
||||
}
|
||||
impl Packet for CS00StatusResponse {
|
||||
fn id() -> PacketId {
|
||||
0x00
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Status
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, response) = parse_json(data)?;
|
||||
Ok((data, CS00StatusResponse { response }))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
serialize_json(&self.response)
|
||||
}
|
||||
}
|
||||
impl From<CS00StatusResponse> for GenericPacket {
|
||||
fn from(value: CS00StatusResponse) -> Self {
|
||||
GenericPacket::CS00StatusResponse(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CS00StatusResponse {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CS00StatusResponse(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct CS01PingResponse {
|
||||
payload: i64,
|
||||
}
|
||||
impl Packet for CS01PingResponse {
|
||||
fn id() -> PacketId {
|
||||
0x01
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Status
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, payload) = nom::number::streaming::be_i64(data)?;
|
||||
Ok((data, CS01PingResponse { payload }))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
self.payload.to_be_bytes().to_vec()
|
||||
}
|
||||
}
|
||||
impl From<CS01PingResponse> for GenericPacket {
|
||||
fn from(value: CS01PingResponse) -> Self {
|
||||
GenericPacket::CS01PingResponse(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for CS01PingResponse {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::CS01PingResponse(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
288
crates/composition-protocol/src/packet/mod.rs
Normal file
288
crates/composition-protocol/src/packet/mod.rs
Normal file
@ -0,0 +1,288 @@
|
||||
pub mod clientbound;
|
||||
pub mod serverbound;
|
||||
|
||||
use crate::ClientState;
|
||||
|
||||
pub type PacketId = i32;
|
||||
|
||||
pub trait Packet: TryFrom<GenericPacket> + Into<GenericPacket> + std::fmt::Debug {
|
||||
fn id() -> PacketId;
|
||||
fn client_state() -> crate::ClientState;
|
||||
fn serverbound() -> bool;
|
||||
|
||||
// The slice given should only be the exact amount of data in the body.
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self>
|
||||
where
|
||||
Self: Sized;
|
||||
fn serialize_body(&self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum GenericPacket {
|
||||
// Handshake
|
||||
SH00Handshake(serverbound::SH00Handshake),
|
||||
|
||||
// Status
|
||||
SS00StatusRequest(serverbound::SS00StatusRequest),
|
||||
SS01PingRequest(serverbound::SS01PingRequest),
|
||||
|
||||
CS00StatusResponse(clientbound::CS00StatusResponse),
|
||||
CS01PingResponse(clientbound::CS01PingResponse),
|
||||
|
||||
// Login
|
||||
SL00LoginStart(serverbound::SL00LoginStart),
|
||||
SL01EncryptionResponse(serverbound::SL01EncryptionResponse),
|
||||
SL02LoginPluginResponse(serverbound::SL02LoginPluginResponse),
|
||||
|
||||
CL00Disconnect(clientbound::CL00Disconnect),
|
||||
CL01EncryptionRequest(clientbound::CL01EncryptionRequest),
|
||||
CL02LoginSuccess(clientbound::CL02LoginSuccess),
|
||||
CL03SetCompression(clientbound::CL03SetCompression),
|
||||
CL04LoginPluginRequest(clientbound::CL04LoginPluginRequest),
|
||||
|
||||
// Play
|
||||
SP08CommandSuggestionsRequest(serverbound::SP08CommandSuggestionsRequest),
|
||||
SP11KeepAlive(serverbound::SP11KeepAlive),
|
||||
SP13SetPlayerPosition(serverbound::SP13SetPlayerPosition),
|
||||
SP14SetPlayerPositionAndRotation(serverbound::SP14SetPlayerPositionAndRotation),
|
||||
SP15SetPlayerRotation(serverbound::SP15SetPlayerRotation),
|
||||
|
||||
CP00SpawnEntity(clientbound::CP00SpawnEntity),
|
||||
CP0BChangeDifficulty(clientbound::CP0BChangeDifficulty),
|
||||
CP17Disconnect(clientbound::CP17Disconnect),
|
||||
CP1FKeepAlive(clientbound::CP1FKeepAlive),
|
||||
CP21WorldEvent(clientbound::CP21WorldEvent),
|
||||
CP50SetEntityVelocity(clientbound::CP50SetEntityVelocity),
|
||||
CP52SetExperience(clientbound::CP52SetExperience),
|
||||
CP68EntityEffect(clientbound::CP68EntityEffect),
|
||||
|
||||
// Until we implement all the packets this will stay.
|
||||
UnimplementedPacket(PacketId),
|
||||
}
|
||||
impl GenericPacket {
|
||||
pub fn parse_uncompressed<'data>(
|
||||
client_state: &ClientState,
|
||||
serverbound: bool,
|
||||
data: &'data [u8],
|
||||
) -> nom::IResult<&'data [u8], Self> {
|
||||
let (data, packet_length) = crate::util::parse_varint(data)?;
|
||||
let (data, packet_data) = nom::bytes::streaming::take(packet_length as usize)(data)?;
|
||||
|
||||
let (packet_data, packet_id) = crate::util::parse_varint(packet_data)?;
|
||||
let (_packet_data, packet_body) =
|
||||
Self::parse_body(client_state, packet_id, serverbound, packet_data)?;
|
||||
|
||||
// if !packet_data.is_empty() {
|
||||
// println!("Packet data not empty after parsing!");
|
||||
// }
|
||||
|
||||
Ok((data, packet_body))
|
||||
}
|
||||
pub fn parse_body<'data>(
|
||||
client_state: &ClientState,
|
||||
packet_id: PacketId,
|
||||
serverbound: bool,
|
||||
data: &'data [u8],
|
||||
) -> nom::IResult<&'data [u8], Self> {
|
||||
fn mapper<P: Into<GenericPacket> + Sized>(
|
||||
(data, packet): (&[u8], P),
|
||||
) -> (&[u8], GenericPacket) {
|
||||
(data, Into::<GenericPacket>::into(packet))
|
||||
}
|
||||
|
||||
match (client_state, packet_id, serverbound) {
|
||||
// Handshake
|
||||
(ClientState::Handshake, 0x00, true) => {
|
||||
serverbound::SH00Handshake::parse_body(data).map(mapper)
|
||||
}
|
||||
|
||||
// Status
|
||||
(ClientState::Status, 0x00, true) => {
|
||||
serverbound::SS00StatusRequest::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Status, 0x01, true) => {
|
||||
serverbound::SS00StatusRequest::parse_body(data).map(mapper)
|
||||
}
|
||||
|
||||
(ClientState::Status, 0x00, false) => {
|
||||
clientbound::CS00StatusResponse::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Status, 0x01, false) => {
|
||||
clientbound::CS01PingResponse::parse_body(data).map(mapper)
|
||||
}
|
||||
|
||||
// Login
|
||||
(ClientState::Login, 0x00, true) => {
|
||||
serverbound::SL00LoginStart::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Login, 0x01, true) => {
|
||||
serverbound::SL01EncryptionResponse::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Login, 0x02, true) => {
|
||||
serverbound::SL02LoginPluginResponse::parse_body(data).map(mapper)
|
||||
}
|
||||
|
||||
(ClientState::Login, 0x00, false) => {
|
||||
clientbound::CL00Disconnect::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Login, 0x01, false) => {
|
||||
clientbound::CL01EncryptionRequest::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Login, 0x02, false) => {
|
||||
clientbound::CL02LoginSuccess::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Login, 0x03, false) => {
|
||||
clientbound::CL03SetCompression::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Login, 0x04, false) => {
|
||||
clientbound::CL04LoginPluginRequest::parse_body(data).map(mapper)
|
||||
}
|
||||
|
||||
// Play
|
||||
(ClientState::Play, 0x08, true) => {
|
||||
serverbound::SP08CommandSuggestionsRequest::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Play, 0x11, true) => {
|
||||
serverbound::SP11KeepAlive::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Play, 0x13, true) => {
|
||||
serverbound::SP13SetPlayerPosition::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Play, 0x14, true) => {
|
||||
serverbound::SP14SetPlayerPositionAndRotation::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Play, 0x15, true) => {
|
||||
serverbound::SP15SetPlayerRotation::parse_body(data).map(mapper)
|
||||
}
|
||||
|
||||
(ClientState::Play, 0x00, false) => {
|
||||
clientbound::CP00SpawnEntity::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Play, 0x0b, false) => {
|
||||
clientbound::CP0BChangeDifficulty::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Play, 0x17, false) => {
|
||||
clientbound::CP17Disconnect::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Play, 0x1f, false) => {
|
||||
clientbound::CP1FKeepAlive::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Play, 0x21, false) => {
|
||||
clientbound::CP21WorldEvent::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Play, 0x50, false) => {
|
||||
clientbound::CP50SetEntityVelocity::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Play, 0x52, false) => {
|
||||
clientbound::CP52SetExperience::parse_body(data).map(mapper)
|
||||
}
|
||||
(ClientState::Play, 0x68, false) => {
|
||||
clientbound::CP68EntityEffect::parse_body(data).map(mapper)
|
||||
}
|
||||
|
||||
_ => Ok((&data[0..0], GenericPacket::UnimplementedPacket(packet_id))),
|
||||
// Invalid packet
|
||||
// _ => Err(nom::Err::Failure(nom::error::Error::new(
|
||||
// data,
|
||||
// nom::error::ErrorKind::Verify,
|
||||
// ))),
|
||||
}
|
||||
}
|
||||
pub fn serialize(&self) -> (PacketId, Vec<u8>) {
|
||||
use GenericPacket::*;
|
||||
|
||||
match self {
|
||||
// Handshake
|
||||
SH00Handshake(packet) => (serverbound::SH00Handshake::id(), packet.serialize_body()),
|
||||
|
||||
// Status
|
||||
SS00StatusRequest(packet) => (
|
||||
serverbound::SS00StatusRequest::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
SS01PingRequest(packet) => {
|
||||
(serverbound::SS01PingRequest::id(), packet.serialize_body())
|
||||
}
|
||||
|
||||
CS00StatusResponse(packet) => (
|
||||
clientbound::CS00StatusResponse::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
CS01PingResponse(packet) => {
|
||||
(clientbound::CS01PingResponse::id(), packet.serialize_body())
|
||||
}
|
||||
|
||||
// Login
|
||||
SL00LoginStart(packet) => (serverbound::SL00LoginStart::id(), packet.serialize_body()),
|
||||
SL01EncryptionResponse(packet) => (
|
||||
serverbound::SL01EncryptionResponse::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
SL02LoginPluginResponse(packet) => (
|
||||
serverbound::SL02LoginPluginResponse::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
|
||||
CL00Disconnect(packet) => (clientbound::CL00Disconnect::id(), packet.serialize_body()),
|
||||
CL01EncryptionRequest(packet) => (
|
||||
clientbound::CL01EncryptionRequest::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
CL02LoginSuccess(packet) => {
|
||||
(clientbound::CL02LoginSuccess::id(), packet.serialize_body())
|
||||
}
|
||||
CL03SetCompression(packet) => (
|
||||
clientbound::CL03SetCompression::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
CL04LoginPluginRequest(packet) => (
|
||||
clientbound::CL04LoginPluginRequest::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
|
||||
// Play
|
||||
SP08CommandSuggestionsRequest(packet) => (
|
||||
serverbound::SP08CommandSuggestionsRequest::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
SP11KeepAlive(packet) => (serverbound::SP11KeepAlive::id(), packet.serialize_body()),
|
||||
SP13SetPlayerPosition(packet) => (
|
||||
serverbound::SP13SetPlayerPosition::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
SP14SetPlayerPositionAndRotation(packet) => (
|
||||
serverbound::SP14SetPlayerPositionAndRotation::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
SP15SetPlayerRotation(packet) => (
|
||||
serverbound::SP15SetPlayerRotation::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
|
||||
CP00SpawnEntity(packet) => {
|
||||
(clientbound::CP00SpawnEntity::id(), packet.serialize_body())
|
||||
}
|
||||
CP0BChangeDifficulty(packet) => (
|
||||
clientbound::CP0BChangeDifficulty::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
CP17Disconnect(packet) => (clientbound::CP17Disconnect::id(), packet.serialize_body()),
|
||||
CP1FKeepAlive(packet) => (clientbound::CP1FKeepAlive::id(), packet.serialize_body()),
|
||||
CP21WorldEvent(packet) => (clientbound::CP21WorldEvent::id(), packet.serialize_body()),
|
||||
CP50SetEntityVelocity(packet) => (
|
||||
clientbound::CP50SetEntityVelocity::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
CP52SetExperience(packet) => (
|
||||
clientbound::CP52SetExperience::id(),
|
||||
packet.serialize_body(),
|
||||
),
|
||||
CP68EntityEffect(packet) => {
|
||||
(clientbound::CP68EntityEffect::id(), packet.serialize_body())
|
||||
}
|
||||
|
||||
// Unimplemented packets get no body.
|
||||
UnimplementedPacket(packet_id) => (*packet_id, vec![]),
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
use crate::{
|
||||
packet::{GenericPacket, Packet, PacketId},
|
||||
util::{parse_string, parse_varint, serialize_string, serialize_varint},
|
||||
ClientState,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct SH00Handshake {
|
||||
pub protocol_version: i32,
|
||||
pub server_address: String,
|
||||
pub server_port: u16,
|
||||
pub next_state: ClientState,
|
||||
}
|
||||
impl Packet for SH00Handshake {
|
||||
fn id() -> PacketId {
|
||||
0x00
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Handshake
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, protocol_version) = parse_varint(data)?;
|
||||
let (data, server_address) = parse_string(data)?;
|
||||
let (data, server_port) = nom::number::streaming::be_u16(data)?;
|
||||
let (data, next_state) = parse_varint(data)?;
|
||||
|
||||
Ok((
|
||||
data,
|
||||
SH00Handshake {
|
||||
protocol_version,
|
||||
server_address,
|
||||
server_port,
|
||||
next_state: match next_state {
|
||||
1 => ClientState::Status,
|
||||
2 => ClientState::Login,
|
||||
_ => todo!("Invalid next state"),
|
||||
},
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&self.protocol_version.to_be_bytes());
|
||||
output.extend_from_slice(&serialize_string(&self.server_address));
|
||||
output.extend_from_slice(&self.server_port.to_be_bytes());
|
||||
output.extend_from_slice(&serialize_varint(match self.next_state {
|
||||
ClientState::Status => 0x01,
|
||||
ClientState::Login => 0x02,
|
||||
_ => panic!("invalid SH00Handshake next_state"),
|
||||
}));
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<SH00Handshake> for GenericPacket {
|
||||
fn from(value: SH00Handshake) -> Self {
|
||||
GenericPacket::SH00Handshake(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for SH00Handshake {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::SH00Handshake(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
184
crates/composition-protocol/src/packet/serverbound/login.rs
Normal file
184
crates/composition-protocol/src/packet/serverbound/login.rs
Normal file
@ -0,0 +1,184 @@
|
||||
use crate::{
|
||||
packet::{GenericPacket, Packet, PacketId},
|
||||
util::{
|
||||
parse_string, parse_uuid, parse_varint, serialize_string, serialize_uuid, serialize_varint,
|
||||
},
|
||||
Uuid,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct SL00LoginStart {
|
||||
name: String,
|
||||
uuid: Option<Uuid>,
|
||||
}
|
||||
impl Packet for SL00LoginStart {
|
||||
fn id() -> PacketId {
|
||||
0x00
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Login
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, name) = parse_string(data)?;
|
||||
let (data, has_uuid) = nom::bytes::streaming::take(1usize)(data)?;
|
||||
if has_uuid == [0x01] {
|
||||
let (data, uuid) = parse_uuid(data)?;
|
||||
Ok((
|
||||
data,
|
||||
SL00LoginStart {
|
||||
name,
|
||||
uuid: Some(uuid),
|
||||
},
|
||||
))
|
||||
} else {
|
||||
Ok((data, SL00LoginStart { name, uuid: None }))
|
||||
}
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_string(&self.name));
|
||||
match self.uuid {
|
||||
Some(uuid) => {
|
||||
output.push(0x01);
|
||||
output.extend_from_slice(&serialize_uuid(&uuid));
|
||||
}
|
||||
None => output.push(0x00),
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<SL00LoginStart> for GenericPacket {
|
||||
fn from(value: SL00LoginStart) -> Self {
|
||||
GenericPacket::SL00LoginStart(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for SL00LoginStart {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::SL00LoginStart(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct SL01EncryptionResponse {
|
||||
shared_secret: Vec<u8>,
|
||||
verify_token: Vec<u8>,
|
||||
}
|
||||
impl Packet for SL01EncryptionResponse {
|
||||
fn id() -> PacketId {
|
||||
0x01
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Login
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, shared_secret_len) = parse_varint(data)?;
|
||||
let (data, shared_secret) = nom::bytes::streaming::take(shared_secret_len as usize)(data)?;
|
||||
let (data, verify_token_len) = parse_varint(data)?;
|
||||
let (data, verify_token) = nom::bytes::streaming::take(verify_token_len as usize)(data)?;
|
||||
|
||||
Ok((
|
||||
data,
|
||||
SL01EncryptionResponse {
|
||||
shared_secret: shared_secret.to_vec(),
|
||||
verify_token: verify_token.to_vec(),
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_varint(self.shared_secret.len() as i32));
|
||||
output.extend_from_slice(&self.shared_secret);
|
||||
output.extend_from_slice(&serialize_varint(self.verify_token.len() as i32));
|
||||
output.extend_from_slice(&self.verify_token);
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<SL01EncryptionResponse> for GenericPacket {
|
||||
fn from(value: SL01EncryptionResponse) -> Self {
|
||||
GenericPacket::SL01EncryptionResponse(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for SL01EncryptionResponse {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::SL01EncryptionResponse(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct SL02LoginPluginResponse {
|
||||
message_id: i32,
|
||||
successful: bool,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
impl Packet for SL02LoginPluginResponse {
|
||||
fn id() -> PacketId {
|
||||
0x02
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Login
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, message_id) = parse_varint(data)?;
|
||||
let (data, successful) = nom::bytes::streaming::take(1usize)(data)?;
|
||||
let successful = successful == [0x01];
|
||||
Ok((
|
||||
data,
|
||||
SL02LoginPluginResponse {
|
||||
message_id,
|
||||
successful,
|
||||
data: match successful {
|
||||
true => data.to_vec(),
|
||||
false => vec![],
|
||||
},
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_varint(self.message_id));
|
||||
if self.successful {
|
||||
output.push(0x01);
|
||||
output.extend_from_slice(&self.data);
|
||||
} else {
|
||||
output.push(0x00);
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<SL02LoginPluginResponse> for GenericPacket {
|
||||
fn from(value: SL02LoginPluginResponse) -> Self {
|
||||
GenericPacket::SL02LoginPluginResponse(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for SL02LoginPluginResponse {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::SL02LoginPluginResponse(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
pub mod handshake;
|
||||
pub mod login;
|
||||
pub mod play;
|
||||
pub mod status;
|
||||
|
||||
pub use handshake::*;
|
||||
pub use login::*;
|
||||
pub use play::*;
|
||||
pub use status::*;
|
266
crates/composition-protocol/src/packet/serverbound/play.rs
Normal file
266
crates/composition-protocol/src/packet/serverbound/play.rs
Normal file
@ -0,0 +1,266 @@
|
||||
use crate::{
|
||||
packet::{GenericPacket, Packet, PacketId},
|
||||
util::{parse_string, parse_varint, serialize_string, serialize_varint},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct SP08CommandSuggestionsRequest {
|
||||
transaction_id: i32,
|
||||
text: String,
|
||||
}
|
||||
impl Packet for SP08CommandSuggestionsRequest {
|
||||
fn id() -> PacketId {
|
||||
0x08
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, transaction_id) = parse_varint(data)?;
|
||||
let (data, text) = parse_string(data)?;
|
||||
Ok((
|
||||
data,
|
||||
SP08CommandSuggestionsRequest {
|
||||
transaction_id,
|
||||
text,
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_varint(self.transaction_id));
|
||||
output.extend_from_slice(&serialize_string(&self.text));
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<SP08CommandSuggestionsRequest> for GenericPacket {
|
||||
fn from(value: SP08CommandSuggestionsRequest) -> Self {
|
||||
GenericPacket::SP08CommandSuggestionsRequest(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for SP08CommandSuggestionsRequest {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::SP08CommandSuggestionsRequest(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct SP11KeepAlive {
|
||||
payload: i64,
|
||||
}
|
||||
impl Packet for SP11KeepAlive {
|
||||
fn id() -> PacketId {
|
||||
0x11
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, payload) = nom::number::streaming::be_i64(data)?;
|
||||
Ok((data, SP11KeepAlive { payload }))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
self.payload.to_be_bytes().to_vec()
|
||||
}
|
||||
}
|
||||
impl From<SP11KeepAlive> for GenericPacket {
|
||||
fn from(value: SP11KeepAlive) -> Self {
|
||||
GenericPacket::SP11KeepAlive(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for SP11KeepAlive {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::SP11KeepAlive(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct SP13SetPlayerPosition {
|
||||
x: f64,
|
||||
y: f64,
|
||||
z: f64,
|
||||
on_ground: bool,
|
||||
}
|
||||
impl Packet for SP13SetPlayerPosition {
|
||||
fn id() -> PacketId {
|
||||
0x13
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, x) = nom::number::streaming::be_f64(data)?;
|
||||
let (data, y) = nom::number::streaming::be_f64(data)?;
|
||||
let (data, z) = nom::number::streaming::be_f64(data)?;
|
||||
let (data, on_ground) = nom::bytes::streaming::take(1usize)(data)?;
|
||||
let on_ground = on_ground == [0x01];
|
||||
Ok((data, SP13SetPlayerPosition { x, y, z, on_ground }))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&self.x.to_be_bytes());
|
||||
output.extend_from_slice(&self.y.to_be_bytes());
|
||||
output.extend_from_slice(&self.z.to_be_bytes());
|
||||
output.push(if self.on_ground { 0x01 } else { 0x00 });
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<SP13SetPlayerPosition> for GenericPacket {
|
||||
fn from(value: SP13SetPlayerPosition) -> Self {
|
||||
GenericPacket::SP13SetPlayerPosition(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for SP13SetPlayerPosition {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::SP13SetPlayerPosition(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct SP14SetPlayerPositionAndRotation {
|
||||
x: f64,
|
||||
y: f64,
|
||||
z: f64,
|
||||
yaw: f32,
|
||||
pitch: f32,
|
||||
on_ground: bool,
|
||||
}
|
||||
impl Packet for SP14SetPlayerPositionAndRotation {
|
||||
fn id() -> PacketId {
|
||||
0x14
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, x) = nom::number::streaming::be_f64(data)?;
|
||||
let (data, y) = nom::number::streaming::be_f64(data)?;
|
||||
let (data, z) = nom::number::streaming::be_f64(data)?;
|
||||
let (data, yaw) = nom::number::streaming::be_f32(data)?;
|
||||
let (data, pitch) = nom::number::streaming::be_f32(data)?;
|
||||
let (data, on_ground) = nom::bytes::streaming::take(1usize)(data)?;
|
||||
let on_ground = on_ground == [0x01];
|
||||
Ok((
|
||||
data,
|
||||
SP14SetPlayerPositionAndRotation {
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
yaw,
|
||||
pitch,
|
||||
on_ground,
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&self.x.to_be_bytes());
|
||||
output.extend_from_slice(&self.y.to_be_bytes());
|
||||
output.extend_from_slice(&self.z.to_be_bytes());
|
||||
output.extend_from_slice(&self.yaw.to_be_bytes());
|
||||
output.extend_from_slice(&self.pitch.to_be_bytes());
|
||||
output.push(if self.on_ground { 0x01 } else { 0x00 });
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<SP14SetPlayerPositionAndRotation> for GenericPacket {
|
||||
fn from(value: SP14SetPlayerPositionAndRotation) -> Self {
|
||||
GenericPacket::SP14SetPlayerPositionAndRotation(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for SP14SetPlayerPositionAndRotation {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::SP14SetPlayerPositionAndRotation(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct SP15SetPlayerRotation {
|
||||
yaw: f32,
|
||||
pitch: f32,
|
||||
on_ground: bool,
|
||||
}
|
||||
impl Packet for SP15SetPlayerRotation {
|
||||
fn id() -> PacketId {
|
||||
0x15
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Play
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, yaw) = nom::number::streaming::be_f32(data)?;
|
||||
let (data, pitch) = nom::number::streaming::be_f32(data)?;
|
||||
let (data, on_ground) = nom::bytes::streaming::take(1usize)(data)?;
|
||||
let on_ground = on_ground == [0x01];
|
||||
Ok((
|
||||
data,
|
||||
SP15SetPlayerRotation {
|
||||
yaw,
|
||||
pitch,
|
||||
on_ground,
|
||||
},
|
||||
))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&self.yaw.to_be_bytes());
|
||||
output.extend_from_slice(&self.pitch.to_be_bytes());
|
||||
output.push(if self.on_ground { 0x01 } else { 0x00 });
|
||||
output
|
||||
}
|
||||
}
|
||||
impl From<SP15SetPlayerRotation> for GenericPacket {
|
||||
fn from(value: SP15SetPlayerRotation) -> Self {
|
||||
GenericPacket::SP15SetPlayerRotation(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for SP15SetPlayerRotation {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::SP15SetPlayerRotation(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
76
crates/composition-protocol/src/packet/serverbound/status.rs
Normal file
76
crates/composition-protocol/src/packet/serverbound/status.rs
Normal file
@ -0,0 +1,76 @@
|
||||
use crate::packet::{GenericPacket, Packet, PacketId};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct SS00StatusRequest;
|
||||
impl Packet for SS00StatusRequest {
|
||||
fn id() -> PacketId {
|
||||
0x00
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Status
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
Ok((data, SS00StatusRequest))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
impl From<SS00StatusRequest> for GenericPacket {
|
||||
fn from(value: SS00StatusRequest) -> Self {
|
||||
GenericPacket::SS00StatusRequest(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for SS00StatusRequest {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::SS00StatusRequest(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct SS01PingRequest {
|
||||
payload: i64,
|
||||
}
|
||||
impl Packet for SS01PingRequest {
|
||||
fn id() -> PacketId {
|
||||
0x01
|
||||
}
|
||||
fn client_state() -> crate::ClientState {
|
||||
crate::ClientState::Status
|
||||
}
|
||||
fn serverbound() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_body(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, payload) = nom::number::streaming::be_i64(data)?;
|
||||
Ok((data, SS01PingRequest { payload }))
|
||||
}
|
||||
fn serialize_body(&self) -> Vec<u8> {
|
||||
self.payload.to_be_bytes().to_vec()
|
||||
}
|
||||
}
|
||||
impl From<SS01PingRequest> for GenericPacket {
|
||||
fn from(value: SS01PingRequest) -> Self {
|
||||
GenericPacket::SS01PingRequest(value)
|
||||
}
|
||||
}
|
||||
impl TryFrom<GenericPacket> for SS01PingRequest {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: GenericPacket) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
GenericPacket::SS01PingRequest(packet) => Ok(packet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
190
crates/composition-protocol/src/util.rs
Normal file
190
crates/composition-protocol/src/util.rs
Normal file
@ -0,0 +1,190 @@
|
||||
use nom::error::FromExternalError;
|
||||
|
||||
pub fn parse_varint(mut data: &[u8]) -> nom::IResult<&[u8], i32> {
|
||||
let mut output = 0i32;
|
||||
let mut bytes_read = 0i32;
|
||||
|
||||
loop {
|
||||
let (d, next_byte) = nom::bytes::streaming::take(1usize)(data)?;
|
||||
data = d;
|
||||
|
||||
output |= ((next_byte[0] & 0x7f) as i32) << (bytes_read * 7);
|
||||
bytes_read += 1;
|
||||
if next_byte[0] & 0x80 != 0x80 {
|
||||
break;
|
||||
}
|
||||
if bytes_read >= 5 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
nom::IResult::Ok((data, output))
|
||||
}
|
||||
pub fn serialize_varint(value: i32) -> Vec<u8> {
|
||||
let mut value = value as u32;
|
||||
let mut output = vec![];
|
||||
loop {
|
||||
let data = (value & 0x7f) as u8;
|
||||
value >>= 7;
|
||||
|
||||
if value == 0 {
|
||||
output.push(data);
|
||||
break;
|
||||
} else {
|
||||
output.push(data | 0x80);
|
||||
}
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
pub fn parse_string(data: &[u8]) -> nom::IResult<&[u8], String> {
|
||||
let (data, len) = parse_varint(data)?;
|
||||
let (data, str_bytes) = nom::bytes::streaming::take(len as usize)(data)?;
|
||||
let s = String::from_utf8_lossy(str_bytes).to_string();
|
||||
nom::IResult::Ok((data, s))
|
||||
}
|
||||
pub fn serialize_string(value: &str) -> Vec<u8> {
|
||||
let mut output = vec![];
|
||||
output.extend_from_slice(&serialize_varint(value.len() as i32));
|
||||
output.extend_from_slice(value.as_bytes());
|
||||
output
|
||||
}
|
||||
|
||||
pub fn parse_json(data: &[u8]) -> nom::IResult<&[u8], crate::Json> {
|
||||
use nom::error::{Error, ErrorKind};
|
||||
let (data, json) = parse_string(data)?;
|
||||
let json = serde_json::from_str(&json)
|
||||
.map_err(|e| nom::Err::Error(Error::from_external_error(data, ErrorKind::Verify, e)))?;
|
||||
Ok((data, json))
|
||||
}
|
||||
pub fn serialize_json(value: &crate::Json) -> Vec<u8> {
|
||||
serialize_string(&serde_json::to_string(value).expect("valid json"))
|
||||
}
|
||||
|
||||
pub fn parse_chat(data: &[u8]) -> nom::IResult<&[u8], crate::Chat> {
|
||||
parse_json(data)
|
||||
}
|
||||
pub fn serialize_chat(value: &crate::Chat) -> Vec<u8> {
|
||||
serialize_json(value)
|
||||
}
|
||||
|
||||
pub fn parse_uuid(data: &[u8]) -> nom::IResult<&[u8], crate::Uuid> {
|
||||
nom::number::streaming::be_u128(data)
|
||||
}
|
||||
pub fn serialize_uuid(value: &crate::Uuid) -> Vec<u8> {
|
||||
value.to_be_bytes().to_vec()
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct Position {
|
||||
x: i32,
|
||||
y: i32,
|
||||
z: i32,
|
||||
}
|
||||
impl Position {
|
||||
pub fn new(x: i32, y: i32, z: i32) -> Self {
|
||||
Position { x, y, z }
|
||||
}
|
||||
pub fn parse(data: &[u8]) -> nom::IResult<&[u8], Self> {
|
||||
let (data, i) = nom::number::streaming::be_i64(data)?;
|
||||
|
||||
// x: i26, z: i26, y: i12
|
||||
let x = i >> 38;
|
||||
let mut y = i & 0xFFF;
|
||||
if y >= 0x800 {
|
||||
y -= 0x1000;
|
||||
}
|
||||
let z = i << 26 >> 38;
|
||||
|
||||
Ok((data, Position::new(x as i32, y as i32, z as i32)))
|
||||
}
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
let i: i64 = ((self.x as i64 & 0x3FF_FFFF) << 38)
|
||||
| ((self.z as i64 & 0x3FF_FFFF) << 12)
|
||||
| (self.y as i64 & 0xFFF);
|
||||
i.to_be_bytes().to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn get_varints() -> Vec<(i32, Vec<u8>)> {
|
||||
vec![
|
||||
(0, vec![0x00]),
|
||||
(1, vec![0x01]),
|
||||
(2, vec![0x02]),
|
||||
(127, vec![0x7f]),
|
||||
(128, vec![0x80, 0x01]),
|
||||
(255, vec![0xff, 0x01]),
|
||||
(25565, vec![0xdd, 0xc7, 0x01]),
|
||||
(2097151, vec![0xff, 0xff, 0x7f]),
|
||||
(2147483647, vec![0xff, 0xff, 0xff, 0xff, 0x07]),
|
||||
(-1, vec![0xff, 0xff, 0xff, 0xff, 0x0f]),
|
||||
(-2147483648, vec![0x80, 0x80, 0x80, 0x80, 0x08]),
|
||||
]
|
||||
}
|
||||
#[test]
|
||||
fn parse_varint_works() {
|
||||
for (value, bytes) in get_varints() {
|
||||
assert_eq!(value, parse_varint(&bytes).unwrap().1);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn serialize_varint_works() {
|
||||
for (value, bytes) in get_varints() {
|
||||
assert_eq!(bytes, serialize_varint(value));
|
||||
}
|
||||
}
|
||||
|
||||
fn get_strings() -> Vec<(&'static str, Vec<u8>)> {
|
||||
let s_127 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456";
|
||||
vec![
|
||||
("", vec![0x00]),
|
||||
("A", vec![0x01, 0x41]),
|
||||
("AB", vec![0x02, 0x41, 0x42]),
|
||||
(s_127, {
|
||||
let mut v = vec![0x7f];
|
||||
v.extend_from_slice(s_127.as_bytes());
|
||||
v
|
||||
}),
|
||||
]
|
||||
}
|
||||
#[test]
|
||||
fn parse_string_works() {
|
||||
for (value, bytes) in get_strings() {
|
||||
assert_eq!(value, parse_string(&bytes).unwrap().1);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn serialize_string_works() {
|
||||
for (value, bytes) in get_strings() {
|
||||
assert_eq!(bytes, serialize_string(value));
|
||||
}
|
||||
}
|
||||
|
||||
fn get_positions() -> Vec<(Position, Vec<u8>)> {
|
||||
vec![
|
||||
// x: 01000110000001110110001100 z: 10110000010101101101001000 y: 001100111111
|
||||
(
|
||||
Position::new(18357644, 831, -20882616),
|
||||
vec![
|
||||
0b01000110, 0b00000111, 0b01100011, 0b00101100, 0b00010101, 0b10110100,
|
||||
0b10000011, 0b00111111,
|
||||
],
|
||||
),
|
||||
]
|
||||
}
|
||||
#[test]
|
||||
fn parse_position_works() {
|
||||
for (value, bytes) in get_positions() {
|
||||
assert_eq!(value, Position::parse(&bytes).unwrap().1);
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn serialize_position_works() {
|
||||
for (value, bytes) in get_positions() {
|
||||
assert_eq!(bytes, value.serialize());
|
||||
}
|
||||
}
|
||||
}
|
9
output.log
Normal file
9
output.log
Normal file
@ -0,0 +1,9 @@
|
||||
[2023-03-14 17:09:13][composition_core::config][WARN] Server icon file does not exist, creating server-icon.png
|
||||
[2023-03-14 17:09:13][composition][INFO] Starting composition/0.1.0 (cc68d3a9) on port 25565
|
||||
[2023-03-14 17:09:13][composition][INFO] Done! Start took 709.336µs
|
||||
[2023-03-14 17:09:31][composition][INFO] Starting composition/0.1.0 (cc68d3a9) on port 25565
|
||||
[2023-03-14 17:09:31][composition][INFO] Done! Start took 487.541µs
|
||||
[2023-03-14 17:09:53][composition][INFO] Starting composition/0.1.0 (cc68d3a9) on port 25565
|
||||
[2023-03-14 17:09:53][composition][INFO] Done! Start took 567.591µs
|
||||
[2023-03-14 17:10:08][composition][INFO] Starting composition/0.1.0 (cc68d3a9) on port 25565
|
||||
[2023-03-14 17:10:08][composition][INFO] Done! Start took 2.56877ms
|
15
src/main.rs
15
src/main.rs
@ -1,17 +1,20 @@
|
||||
use log::*;
|
||||
use log::info;
|
||||
use std::sync::mpsc::TryRecvError;
|
||||
use std::time::Duration;
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() {
|
||||
let ctrlc_rx = composition::init();
|
||||
let ctrlc_rx = composition_core::init();
|
||||
info!(
|
||||
"Starting {} on port {}",
|
||||
composition::CONFIG.server_version,
|
||||
composition::CONFIG.port
|
||||
composition_core::CONFIG.server_version,
|
||||
composition_core::CONFIG.port
|
||||
);
|
||||
let mut server = composition_core::start_server().await;
|
||||
info!(
|
||||
"Done! Start took {:?}",
|
||||
composition_core::START_TIME.elapsed()
|
||||
);
|
||||
let mut server = composition::start_server().await;
|
||||
info!("Done! Start took {:?}", composition::START_TIME.elapsed());
|
||||
|
||||
// The main server loop.
|
||||
loop {
|
||||
|
Loading…
x
Reference in New Issue
Block a user