mirror of
https://github.com/GIKExe/rust_mc_serv.git
synced 2025-06-24 10:22:57 +03:00
не хуйня
This commit is contained in:
parent
8f07ea37e7
commit
dfd6f56f76
512
Cargo.lock
generated
512
Cargo.lock
generated
@ -17,6 +17,21 @@ version = "2.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android-tzdata"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@ -38,36 +53,250 @@ dependencies = [
|
|||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.22.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.9.0"
|
version = "2.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.2.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0"
|
||||||
|
dependencies = [
|
||||||
|
"shlex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
|
||||||
|
dependencies = [
|
||||||
|
"android-tzdata",
|
||||||
|
"iana-time-zone",
|
||||||
|
"num-traits",
|
||||||
|
"serde",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32fast"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"darling_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"ident_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"strsim",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deranged"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
|
||||||
|
dependencies = [
|
||||||
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flate2"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
|
||||||
|
dependencies = [
|
||||||
|
"crc32fast",
|
||||||
|
"libz-sys",
|
||||||
|
"miniz_oxide",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fnv"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.31.1"
|
version = "0.31.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.15.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.63"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ident_case"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown 0.12.3",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown 0.15.3",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.172"
|
version = "0.2.172"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libz-sys"
|
||||||
|
version = "1.1.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"pkg-config",
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
@ -78,6 +307,12 @@ dependencies = [
|
|||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.4"
|
version = "2.7.4"
|
||||||
@ -104,6 +339,21 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-conv"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.36.7"
|
version = "0.36.7"
|
||||||
@ -113,6 +363,12 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
@ -142,6 +398,18 @@ version = "0.2.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.95"
|
version = "1.0.95"
|
||||||
@ -173,6 +441,10 @@ dependencies = [
|
|||||||
name = "rust_mc_serv"
|
name = "rust_mc_serv"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"flate2",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_with",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -182,12 +454,92 @@ version = "0.1.24"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.140"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_with"
|
||||||
|
version = "3.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"chrono",
|
||||||
|
"hex",
|
||||||
|
"indexmap 1.9.3",
|
||||||
|
"indexmap 2.9.0",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"serde_with_macros",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_with_macros"
|
||||||
|
version = "3.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e"
|
||||||
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shlex"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "signal-hook-registry"
|
name = "signal-hook-registry"
|
||||||
version = "1.4.5"
|
version = "1.4.5"
|
||||||
@ -213,6 +565,12 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.101"
|
version = "2.0.101"
|
||||||
@ -224,6 +582,37 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"itoa",
|
||||||
|
"num-conv",
|
||||||
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
|
"time-core",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
|
||||||
|
dependencies = [
|
||||||
|
"num-conv",
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.45.0"
|
version = "1.45.0"
|
||||||
@ -259,12 +648,135 @@ version = "1.0.18"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vcpkg"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"rustversion",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.100"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.61.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link",
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.60.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.59.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
|
@ -4,8 +4,8 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# async-trait = {version = "0.1.88", optional = true}
|
|
||||||
tokio = {version = "1.45.0", features = ["full"]}
|
tokio = {version = "1.45.0", features = ["full"]}
|
||||||
|
flate2 = {version = "1.1.1", features = ["zlib"]}
|
||||||
# [features]
|
serde = {version = "1.0.219", features = ["derive"]}
|
||||||
# async = ["async-trait"]
|
serde_with = "3.12.0"
|
||||||
|
serde_json = "1.0.140"
|
||||||
|
123
src/cycle.rs
Normal file
123
src/cycle.rs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
use tokio::net::TcpStream;
|
||||||
|
|
||||||
|
use crate::data::{clientbound, serverbound, DataError, AsyncReader, DataWriter, Packet, TextComponentBuilder};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum PacketError {
|
||||||
|
WrongPacketID,
|
||||||
|
Data(DataError),
|
||||||
|
NextStateIncorrect,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<DataError> for PacketError {
|
||||||
|
fn from(err: DataError) -> Self {
|
||||||
|
PacketError::Data(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn main(mut stream: TcpStream) {
|
||||||
|
let Ok(addr) = stream.peer_addr() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
println!("Подключение: {addr}");
|
||||||
|
// читаем первый пакет
|
||||||
|
match read_first_packet(&mut stream).await {
|
||||||
|
Ok(_) => {}, Err(e) => println!("Ошибка во время обработки пакета: {e:?}")
|
||||||
|
}
|
||||||
|
println!("Отключение: {addr}");
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_first_packet(stream: &mut TcpStream) -> Result<(), PacketError> {
|
||||||
|
let mut packet = stream.read_packet(None).await?;
|
||||||
|
if packet.id() != 0 { return Err(PacketError::WrongPacketID);}
|
||||||
|
let version = packet.read_varint().await?;
|
||||||
|
let host = packet.read_string().await?;
|
||||||
|
let port = packet.read_short().await?;
|
||||||
|
let ns = packet.read_varint().await?;
|
||||||
|
|
||||||
|
if version != 770 {
|
||||||
|
let mut packet = Packet::empty(0x00);
|
||||||
|
let component =
|
||||||
|
TextComponentBuilder::new()
|
||||||
|
.text("Версия игры отличается от 1.21.5")
|
||||||
|
.color("red")
|
||||||
|
.build();
|
||||||
|
packet.write_string(&component.as_json()?).await?;
|
||||||
|
return Ok(stream.write_packet(packet, None).await?);
|
||||||
|
}
|
||||||
|
|
||||||
|
match ns {
|
||||||
|
1 => the_status(stream).await,
|
||||||
|
2 => the_login(stream, (version, host, port)).await,
|
||||||
|
_ => Err(PacketError::NextStateIncorrect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn the_status(stream: &mut TcpStream) -> Result<(), PacketError> {
|
||||||
|
let packet = stream.read_packet(None).await?;
|
||||||
|
if packet.id() != 0 { return Err(PacketError::WrongPacketID); }
|
||||||
|
let mut p = Packet::empty(clientbound::status::RESPONSE);
|
||||||
|
let status = "{
|
||||||
|
\"version\": {
|
||||||
|
\"name\": \"1.21.5\",
|
||||||
|
\"protocol\": 770
|
||||||
|
},
|
||||||
|
\"players\": {
|
||||||
|
\"max\": 0,
|
||||||
|
\"online\": 1
|
||||||
|
}
|
||||||
|
}";
|
||||||
|
p.write_string(status).await?;
|
||||||
|
stream.write_packet(p, None).await?;
|
||||||
|
|
||||||
|
let mut packet = stream.read_packet(None).await?;
|
||||||
|
if packet.id() != 1 { return Err(PacketError::WrongPacketID); }
|
||||||
|
let mut p = Packet::empty(clientbound::status::PONG_RESPONSE);
|
||||||
|
p.write_long(packet.read_long().await?).await?;
|
||||||
|
stream.write_packet(p, None).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn the_login(stream: &mut TcpStream, data: (i32, String, u16)) -> Result<(), PacketError> {
|
||||||
|
|
||||||
|
if data.0 != 770 {
|
||||||
|
let mut packet = Packet::empty(clientbound::login::DISCONNECT);
|
||||||
|
let component =
|
||||||
|
TextComponentBuilder::new()
|
||||||
|
.text("Версия игры отличается от 1.21.5")
|
||||||
|
.color("red")
|
||||||
|
.build();
|
||||||
|
packet.write_string(&component.as_json()?).await?;
|
||||||
|
return Ok(stream.write_packet(packet, None).await?);
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("Версия протокола: {}", data.0);
|
||||||
|
// println!("Адрес сервера: {}:{}", data.1, data.2);
|
||||||
|
|
||||||
|
// let mut packet = Packet::empty(clientbound::login::DISCONNECT);
|
||||||
|
// let component =
|
||||||
|
// TextComponentBuilder::new()
|
||||||
|
// .text("Вы кто такие? Я вас не звал. Идите нахуй.")
|
||||||
|
// .color("red")
|
||||||
|
// .build();
|
||||||
|
// packet.write_string(&component.as_json()?).await?;
|
||||||
|
// return Ok(stream.write_packet(packet, None).await?);
|
||||||
|
|
||||||
|
let mut packet = stream.read_packet(None).await?;
|
||||||
|
if packet.id() != serverbound::login::START { return Err(PacketError::WrongPacketID); }
|
||||||
|
let username = packet.read_string().await?;
|
||||||
|
let uuid = packet.read_uuid().await?;
|
||||||
|
|
||||||
|
println!("Адрес клиента: {:?}", stream.peer_addr());
|
||||||
|
println!("Адрес сервера: {}:{}", data.1, data.2);
|
||||||
|
println!("Username: {username}\n UUID: {:X}", uuid);
|
||||||
|
|
||||||
|
let mut packet = Packet::empty(clientbound::login::SET_COMPRESSION);
|
||||||
|
packet.write_varint(512).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
82
src/data.rs
82
src/data.rs
@ -1,82 +0,0 @@
|
|||||||
use std::io::{Cursor, Read, Write};
|
|
||||||
|
|
||||||
use tokio::io::{AsyncRead, AsyncReadExt};
|
|
||||||
|
|
||||||
use crate::inet::InetError;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum DataError {
|
|
||||||
ReadError,
|
|
||||||
WriteError,
|
|
||||||
VarIntIsSoBig,
|
|
||||||
StringDecodeError,
|
|
||||||
Inet(InetError),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait DataReader {
|
|
||||||
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError>;
|
|
||||||
|
|
||||||
async fn read_byte(&mut self) -> Result<u8, DataError> {
|
|
||||||
Ok(self.read_bytes(1).await?[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_signed_byte(&mut self) -> Result<i8, DataError> {
|
|
||||||
Ok(self.read_byte().await? as i8)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_short(&mut self) -> Result<u16, DataError> {
|
|
||||||
Ok(u16::from_be_bytes(
|
|
||||||
self.read_bytes(2).await?.try_into().unwrap(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_signed_short(&mut self) -> Result<i16, DataError> {
|
|
||||||
Ok(self.read_short().await? as i16)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_varint_size(&mut self) -> Result<(i32, usize), DataError> {
|
|
||||||
let mut value = 0;
|
|
||||||
let mut position = 0;
|
|
||||||
loop {
|
|
||||||
let byte = self.read_byte().await?;
|
|
||||||
value |= ((byte & 0x7F) as i32) << (position * 7);
|
|
||||||
if (byte & 0x80) == 0 {
|
|
||||||
return Ok((value, position as usize));
|
|
||||||
};
|
|
||||||
position += 1;
|
|
||||||
if position >= 5 {
|
|
||||||
return Err(DataError::VarIntIsSoBig);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_varint(&mut self) -> Result<i32, DataError> {
|
|
||||||
Ok(self.read_varint_size().await?.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// async fn read_packet(&mut self, threshold: Option<usize>) -> Result<Cursor<Vec<u8>>, DataError> {
|
|
||||||
// let size = self.read_varint().await?;
|
|
||||||
// let mut buf = self.read_bytes(size).await?;
|
|
||||||
// }
|
|
||||||
|
|
||||||
async fn read_string(&mut self) -> Result<String, DataError> {
|
|
||||||
let size = self.read_varint().await?;
|
|
||||||
let vec = self.read_bytes(size as usize).await?;
|
|
||||||
String::from_utf8(vec).map_err(|_| DataError::StringDecodeError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<R: AsyncRead + Unpin> DataReader for R {
|
|
||||||
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
|
|
||||||
let mut buf = vec![0; size];
|
|
||||||
let mut read = 0;
|
|
||||||
while read < size {
|
|
||||||
match AsyncReadExt::read(self, &mut buf[read..]).await {
|
|
||||||
Ok(0) => return Err(DataError::Inet(InetError::ConnectionClosed)),
|
|
||||||
Ok(n) => read += n,
|
|
||||||
Err(_) => return Err(DataError::ReadError),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(buf)
|
|
||||||
}
|
|
||||||
}
|
|
106
src/data/async_reader.rs
Normal file
106
src/data/async_reader.rs
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
use std::io::{Cursor, ErrorKind, Read};
|
||||||
|
|
||||||
|
use tokio::io::{AsyncRead, AsyncReadExt};
|
||||||
|
|
||||||
|
use crate::inet::InetError;
|
||||||
|
|
||||||
|
use super::{decompress, packet::Packet, DataError};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub trait AsyncReader {
|
||||||
|
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError>;
|
||||||
|
|
||||||
|
async fn read_byte(&mut self) -> Result<u8, DataError> {
|
||||||
|
Ok(self.read_bytes(1).await?[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_signed_byte(&mut self) -> Result<i8, DataError> {
|
||||||
|
Ok(self.read_byte().await? as i8)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_varint_size(&mut self) -> Result<(i32, usize), DataError> {
|
||||||
|
let mut value = 0;
|
||||||
|
let mut position = 0;
|
||||||
|
loop {
|
||||||
|
let byte = self.read_byte().await?;
|
||||||
|
value |= ((byte & 0x7F) as i32) << (position * 7);
|
||||||
|
if (byte & 0x80) == 0 {
|
||||||
|
return Ok((value, position as usize));
|
||||||
|
};
|
||||||
|
position += 1;
|
||||||
|
if position >= 5 {
|
||||||
|
return Err(DataError::VarIntIsSoBig);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_varint(&mut self) -> Result<i32, DataError> {
|
||||||
|
Ok(self.read_varint_size().await?.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_packet(&mut self, threshold: Option<usize>)
|
||||||
|
-> Result<Packet, DataError> {
|
||||||
|
let mut data: Vec<u8>;
|
||||||
|
let packet_lenght = self.read_varint().await? as usize;
|
||||||
|
if threshold.is_some() {
|
||||||
|
let data_lenght = self.read_varint_size().await?;
|
||||||
|
data = self.read_bytes(packet_lenght - data_lenght.1).await?;
|
||||||
|
if data_lenght.0 != 0 { data = decompress(&data)?; }
|
||||||
|
} else {
|
||||||
|
data = self.read_bytes(packet_lenght).await?;
|
||||||
|
}
|
||||||
|
let mut cursor = Cursor::new(data);
|
||||||
|
let id = cursor.read_varint().await?;
|
||||||
|
Ok(Packet::new(id as u8, cursor))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_short(&mut self) -> Result<u16, DataError> {
|
||||||
|
Ok(u16::from_be_bytes(
|
||||||
|
self.read_bytes(2).await?.try_into().unwrap()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_signed_short(&mut self) -> Result<i16, DataError> {
|
||||||
|
Ok(self.read_short().await? as i16)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_string(&mut self) -> Result<String, DataError> {
|
||||||
|
let size = self.read_varint().await?;
|
||||||
|
let vec = self.read_bytes(size as usize).await?;
|
||||||
|
String::from_utf8(vec).or( Err(DataError::StringDecodeError))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_long(&mut self) -> Result<u64, DataError> {
|
||||||
|
Ok(u64::from_be_bytes(
|
||||||
|
self.read_bytes(8).await?.try_into().unwrap()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_signed_long(&mut self) -> Result<i64, DataError> {
|
||||||
|
Ok(self.read_long().await? as i64)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_uuid(&mut self) -> Result<u128, DataError> {
|
||||||
|
Ok(u128::from_be_bytes(
|
||||||
|
self.read_bytes(16).await?.try_into().unwrap()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: AsyncRead + Unpin> AsyncReader for R {
|
||||||
|
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
|
||||||
|
let mut buf = vec![0; size];
|
||||||
|
match AsyncReadExt::read_exact(self, &mut buf).await {
|
||||||
|
Ok(_) => Ok(buf),
|
||||||
|
Err(e) => match e.kind() {
|
||||||
|
ErrorKind::UnexpectedEof | ErrorKind::BrokenPipe | ErrorKind::ConnectionReset => {
|
||||||
|
Err(DataError::Inet(InetError::ConnectionClosed))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
Err(DataError::ReadError)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
212
src/data/component.rs
Normal file
212
src/data/component.rs
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_with::skip_serializing_none;
|
||||||
|
|
||||||
|
use super::DataError;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
#[skip_serializing_none]
|
||||||
|
pub struct TextComponent {
|
||||||
|
pub text: String,
|
||||||
|
pub color: Option<String>,
|
||||||
|
pub bold: Option<bool>,
|
||||||
|
pub italic: Option<bool>,
|
||||||
|
pub underlined: Option<bool>,
|
||||||
|
pub strikethrough: Option<bool>,
|
||||||
|
pub obfuscated: Option<bool>,
|
||||||
|
pub extra: Option<Vec<TextComponent>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TextComponent {
|
||||||
|
pub fn new(text: String) -> Self {
|
||||||
|
Self {
|
||||||
|
text,
|
||||||
|
color: None,
|
||||||
|
bold: None,
|
||||||
|
italic: None,
|
||||||
|
underlined: None,
|
||||||
|
strikethrough: None,
|
||||||
|
obfuscated: None,
|
||||||
|
extra: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn rainbow_offset(text: String, offset: i64) -> TextComponent {
|
||||||
|
// if text.is_empty() {
|
||||||
|
// return TextComponent::new(text);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let children = text
|
||||||
|
// .char_indices()
|
||||||
|
// .map(|(i, c)| {
|
||||||
|
// let hue = (((i as i64 + offset) % text.chars().count() as i64) as f32)
|
||||||
|
// / (text.chars().count() as f32)
|
||||||
|
// * 360.0;
|
||||||
|
// let hsl = Hsl::new(hue, 1.0, 0.5);
|
||||||
|
// let rgb: Srgb = hsl.into_color();
|
||||||
|
// let r = (rgb.red * 255.0).round() as u8;
|
||||||
|
// let g = (rgb.green * 255.0).round() as u8;
|
||||||
|
// let b = (rgb.blue * 255.0).round() as u8;
|
||||||
|
// let mut component = TextComponent::new(c.to_string());
|
||||||
|
// component.color = Some(format!("#{:02X}{:02X}{:02X}", r, g, b));
|
||||||
|
// component
|
||||||
|
// })
|
||||||
|
// .collect::<Vec<TextComponent>>();
|
||||||
|
|
||||||
|
// let mut parent = children[0].clone();
|
||||||
|
// if children.len() > 1 {
|
||||||
|
// parent.extra = Some(children[1..].to_vec());
|
||||||
|
// }
|
||||||
|
// parent
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub fn rainbow(text: String) -> TextComponent {
|
||||||
|
// if text.is_empty() {
|
||||||
|
// return TextComponent::new(text);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let children = text
|
||||||
|
// .char_indices()
|
||||||
|
// .map(|(i, c)| {
|
||||||
|
// let hue = (i as f32) / (text.chars().count() as f32) * 360.0;
|
||||||
|
// let hsl = Hsl::new(hue, 1.0, 0.5);
|
||||||
|
// let rgb: Srgb = hsl.into_color();
|
||||||
|
// let r = (rgb.red * 255.0).round() as u8;
|
||||||
|
// let g = (rgb.green * 255.0).round() as u8;
|
||||||
|
// let b = (rgb.blue * 255.0).round() as u8;
|
||||||
|
// let mut component = TextComponent::new(c.to_string());
|
||||||
|
// component.color = Some(format!("#{:02X}{:02X}{:02X}", r, g, b));
|
||||||
|
// component
|
||||||
|
// })
|
||||||
|
// .collect::<Vec<TextComponent>>();
|
||||||
|
|
||||||
|
// let mut parent = children[0].clone();
|
||||||
|
// if children.len() > 1 {
|
||||||
|
// parent.extra = Some(children[1..].to_vec());
|
||||||
|
// }
|
||||||
|
// parent
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub fn builder() -> TextComponentBuilder {
|
||||||
|
TextComponentBuilder::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_json(self) -> Result<String, DataError> {
|
||||||
|
serde_json::to_string(&self).or( Err(DataError::SerializationError))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_json(text: &str) -> Result<TextComponent, DataError> {
|
||||||
|
serde_json::from_str(text).or( Err(DataError::DeSerializationError))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TextComponent {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new(String::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TextComponentBuilder {
|
||||||
|
text: String,
|
||||||
|
color: Option<String>,
|
||||||
|
bold: Option<bool>,
|
||||||
|
italic: Option<bool>,
|
||||||
|
underlined: Option<bool>,
|
||||||
|
strikethrough: Option<bool>,
|
||||||
|
obfuscated: Option<bool>,
|
||||||
|
extra: Option<Vec<TextComponent>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TextComponentBuilder {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
text: String::new(),
|
||||||
|
color: None,
|
||||||
|
bold: None,
|
||||||
|
italic: None,
|
||||||
|
underlined: None,
|
||||||
|
strikethrough: None,
|
||||||
|
obfuscated: None,
|
||||||
|
extra: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn text(mut self, text: &str) -> Self {
|
||||||
|
self.text = text.to_string();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn color(mut self, color: &str) -> Self {
|
||||||
|
self.color = Some(color.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bold(mut self, bold: bool) -> Self {
|
||||||
|
self.bold = Some(bold);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn italic(mut self, italic: bool) -> Self {
|
||||||
|
self.italic = Some(italic);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn underlined(mut self, underlined: bool) -> Self {
|
||||||
|
self.underlined = Some(underlined);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn strikethrough(mut self, strikethrough: bool) -> Self {
|
||||||
|
self.strikethrough = Some(strikethrough);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn obfuscated(mut self, obfuscated: bool) -> Self {
|
||||||
|
self.obfuscated = Some(obfuscated);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extra(mut self, extra: Vec<TextComponent>) -> Self {
|
||||||
|
self.extra = Some(extra);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(self) -> TextComponent {
|
||||||
|
TextComponent {
|
||||||
|
text: self.text,
|
||||||
|
color: self.color,
|
||||||
|
bold: self.bold,
|
||||||
|
italic: self.italic,
|
||||||
|
underlined: self.underlined,
|
||||||
|
strikethrough: self.strikethrough,
|
||||||
|
obfuscated: self.obfuscated,
|
||||||
|
extra: self.extra,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Реализуем читалку-записывалку текст-компонентов для пакета
|
||||||
|
// impl ReadWriteNBT<TextComponent> for Packet {
|
||||||
|
// fn read_nbt(&mut self) -> Result<TextComponent, ServerError> {
|
||||||
|
// let mut data = Vec::new();
|
||||||
|
// let pos = self.get_ref().position();
|
||||||
|
// self
|
||||||
|
// .get_mut()
|
||||||
|
// .read_to_end(&mut data)
|
||||||
|
// .map_err(|_| ServerError::DeTextComponent)?;
|
||||||
|
// let (remaining, value) =
|
||||||
|
// craftflow_nbt::from_slice(&data).map_err(|_| ServerError::DeTextComponent)?;
|
||||||
|
// self
|
||||||
|
// .get_mut()
|
||||||
|
// .set_position(pos + (data.len() - remaining.len()) as u64);
|
||||||
|
// Ok(value)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn write_nbt(&mut self, val: &TextComponent) -> Result<(), ServerError> {
|
||||||
|
// craftflow_nbt::to_writer(self.get_mut(), val).map_err(|_| ServerError::SerTextComponent)?;
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
// }
|
37
src/data/mod.rs
Normal file
37
src/data/mod.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
use crate::inet::InetError;
|
||||||
|
|
||||||
|
mod async_reader;
|
||||||
|
mod reader;
|
||||||
|
mod writer;
|
||||||
|
mod packet;
|
||||||
|
mod packet_id;
|
||||||
|
mod component;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum DataError {
|
||||||
|
ReadError,
|
||||||
|
WriteError,
|
||||||
|
VarIntIsSoBig,
|
||||||
|
StringDecodeError,
|
||||||
|
Inet(InetError),
|
||||||
|
SerializationError,
|
||||||
|
DeSerializationError,
|
||||||
|
ZlibError,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decompress(bytes: &[u8]) -> Result<Vec<u8>, DataError> {
|
||||||
|
let mut decoder = ZlibDecoder::new(bytes);
|
||||||
|
let mut output = Vec::new();
|
||||||
|
decoder.read_to_end(&mut output).or(Err(DataError::ZlibError))?;
|
||||||
|
Ok(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use async_reader::*;
|
||||||
|
pub use reader::*;
|
||||||
|
use flate2::bufread::ZlibDecoder;
|
||||||
|
pub use writer::*;
|
||||||
|
pub use packet::*;
|
||||||
|
pub use packet_id::{clientbound, serverbound};
|
||||||
|
pub use component::*;
|
97
src/data/packet.rs
Normal file
97
src/data/packet.rs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
use std::io::Cursor;
|
||||||
|
|
||||||
|
use super::{DataError, async_reader::AsyncReader, writer::DataWriter};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Packet {
|
||||||
|
id: u8,
|
||||||
|
cursor: Cursor<Vec<u8>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Packet {
|
||||||
|
/// Create new packet from id and buffer
|
||||||
|
pub fn new(id: u8, cursor: Cursor<Vec<u8>>) -> Packet {
|
||||||
|
Packet { id, cursor }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create new packet with id and empty buffer
|
||||||
|
pub fn empty(id: u8) -> Packet {
|
||||||
|
Packet {
|
||||||
|
id,
|
||||||
|
cursor: Cursor::new(Vec::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build packet with lambda
|
||||||
|
pub fn build<F>(id: u8, builder: F) -> Result<Packet, DataError>
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut Packet) -> Result<(), DataError>,
|
||||||
|
{
|
||||||
|
let mut packet = Self::empty(id);
|
||||||
|
builder(&mut packet)?;
|
||||||
|
Ok(packet)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get packet id
|
||||||
|
pub fn id(&self) -> u8 {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set packet id
|
||||||
|
pub fn set_id(&mut self, id: u8) {
|
||||||
|
self.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set packet cursor
|
||||||
|
pub fn set_cursor(&mut self, cursor: Cursor<Vec<u8>>) {
|
||||||
|
self.cursor = cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get cursor length
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.get_bytes().len() - self.cursor.position() as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Is cursor empty
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.len() == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get cursor remaining bytes
|
||||||
|
pub fn get_bytes(&self) -> &[u8] {
|
||||||
|
self.cursor.get_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get mutable reference to cursor
|
||||||
|
pub fn get_mut(&mut self) -> &mut Cursor<Vec<u8>> {
|
||||||
|
&mut self.cursor
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get immutable reference to cursor
|
||||||
|
pub fn get_ref(&self) -> &Cursor<Vec<u8>> {
|
||||||
|
&self.cursor
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get inner cursor
|
||||||
|
pub fn into_inner(self) -> Cursor<Vec<u8>> {
|
||||||
|
self.cursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Packet> for Cursor<Vec<u8>> {
|
||||||
|
fn from(val: Packet) -> Self {
|
||||||
|
val.cursor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncReader for Packet {
|
||||||
|
async fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
|
||||||
|
self.cursor.read_bytes(size).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DataWriter for Packet {
|
||||||
|
async fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError> {
|
||||||
|
self.cursor.write_bytes(bytes).await
|
||||||
|
}
|
||||||
|
}
|
272
src/data/packet_id.rs
Normal file
272
src/data/packet_id.rs
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Generated with parse_ids.py
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub mod clientbound {
|
||||||
|
pub mod status {
|
||||||
|
pub const RESPONSE: u8 = 0x00;
|
||||||
|
pub const PONG_RESPONSE: u8 = 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod login {
|
||||||
|
pub const DISCONNECT: u8 = 0x00;
|
||||||
|
pub const ENCRYPTION_REQUEST: u8 = 0x01;
|
||||||
|
pub const SUCCESS: u8 = 0x02;
|
||||||
|
pub const SET_COMPRESSION: u8 = 0x03;
|
||||||
|
pub const PLUGIN_REQUEST: u8 = 0x04;
|
||||||
|
pub const COOKIE_REQUEST: u8 = 0x05;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod configuration {
|
||||||
|
pub const COOKIE_REQUEST: u8 = 0x00;
|
||||||
|
pub const PLUGIN_MESSAGE: u8 = 0x01;
|
||||||
|
pub const DISCONNECT: u8 = 0x02;
|
||||||
|
pub const FINISH: u8 = 0x03;
|
||||||
|
pub const KEEP_ALIVE: u8 = 0x04;
|
||||||
|
pub const PING: u8 = 0x05;
|
||||||
|
pub const RESET_CHAT: u8 = 0x06;
|
||||||
|
pub const REGISTRY_DATA: u8 = 0x07;
|
||||||
|
pub const REMOVE_RESOURCE_PACK: u8 = 0x08;
|
||||||
|
pub const ADD_RESOURCE_PACK: u8 = 0x09;
|
||||||
|
pub const STORE_COOKIE: u8 = 0x0A;
|
||||||
|
pub const TRANSFER: u8 = 0x0B;
|
||||||
|
pub const FEATURE_FLAGS: u8 = 0x0C;
|
||||||
|
pub const UPDATE_TAGS: u8 = 0x0D;
|
||||||
|
pub const KNOWN_PACKS: u8 = 0x0E;
|
||||||
|
pub const CUSTOM_REPORT_DETAILS: u8 = 0x0F;
|
||||||
|
pub const SERVER_LINKS: u8 = 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod play {
|
||||||
|
pub const BUNDLE_DELIMITER: u8 = 0x00;
|
||||||
|
pub const SPAWN_ENTITY: u8 = 0x01;
|
||||||
|
pub const ENTITY_ANIMATION: u8 = 0x02;
|
||||||
|
pub const AWARD_STATISTICS: u8 = 0x03;
|
||||||
|
pub const ACKNOWLEDGE_BLOCK_CHANGE: u8 = 0x04;
|
||||||
|
pub const SET_BLOCK_DESTROY_STAGE: u8 = 0x05;
|
||||||
|
pub const BLOCK_ENTITY_DATA: u8 = 0x06;
|
||||||
|
pub const BLOCK_ACTION: u8 = 0x07;
|
||||||
|
pub const BLOCK_UPDATE: u8 = 0x08;
|
||||||
|
pub const BOSS_BAR: u8 = 0x09;
|
||||||
|
pub const CHANGE_DIFFICULTY: u8 = 0x0A;
|
||||||
|
pub const CHUNK_BATCH_FINISHED: u8 = 0x0B;
|
||||||
|
pub const CHUNK_BATCH_START: u8 = 0x0C;
|
||||||
|
pub const CHUNK_BIOMES: u8 = 0x0D;
|
||||||
|
pub const CLEAR_TITLES: u8 = 0x0E;
|
||||||
|
pub const COMMAND_SUGGESTIONS_RESPONSE: u8 = 0x0F;
|
||||||
|
pub const COMMANDS: u8 = 0x10;
|
||||||
|
pub const CLOSE_CONTAINER: u8 = 0x11;
|
||||||
|
pub const SET_CONTAINER_CONTENT: u8 = 0x12;
|
||||||
|
pub const SET_CONTAINER_PROPERTY: u8 = 0x13;
|
||||||
|
pub const SET_CONTAINER_SLOT: u8 = 0x14;
|
||||||
|
pub const COOKIE_REQUEST: u8 = 0x15;
|
||||||
|
pub const SET_COOLDOWN: u8 = 0x16;
|
||||||
|
pub const CHAT_SUGGESTIONS: u8 = 0x17;
|
||||||
|
pub const PLUGIN_MESSAGE: u8 = 0x18;
|
||||||
|
pub const DAMAGE_EVENT: u8 = 0x19;
|
||||||
|
pub const DEBUG_SAMPLE: u8 = 0x1A;
|
||||||
|
pub const DELETE_MESSAGE: u8 = 0x1B;
|
||||||
|
pub const DISCONNECT: u8 = 0x1C;
|
||||||
|
pub const DISGUISED_CHAT_MESSAGE: u8 = 0x1D;
|
||||||
|
pub const ENTITY_EVENT: u8 = 0x1E;
|
||||||
|
pub const TELEPORT_ENTITY: u8 = 0x1F;
|
||||||
|
pub const EXPLOSION: u8 = 0x20;
|
||||||
|
pub const UNLOAD_CHUNK: u8 = 0x21;
|
||||||
|
pub const GAME_EVENT: u8 = 0x22;
|
||||||
|
pub const OPEN_HORSE_SCREEN: u8 = 0x23;
|
||||||
|
pub const HURT_ANIMATION: u8 = 0x24;
|
||||||
|
pub const INITIALIZE_WORLD_BORDER: u8 = 0x25;
|
||||||
|
pub const KEEP_ALIVE: u8 = 0x26;
|
||||||
|
pub const CHUNK_DATA_AND_UPDATE_LIGHT: u8 = 0x27;
|
||||||
|
pub const WORLD_EVENT: u8 = 0x28;
|
||||||
|
pub const PARTICLE: u8 = 0x29;
|
||||||
|
pub const UPDATE_LIGHT: u8 = 0x2A;
|
||||||
|
pub const LOGIN: u8 = 0x2B;
|
||||||
|
pub const MAP_DATA: u8 = 0x2C;
|
||||||
|
pub const MERCHANT_OFFERS: u8 = 0x2D;
|
||||||
|
pub const UPDATE_ENTITY_POSITION: u8 = 0x2E;
|
||||||
|
pub const UPDATE_ENTITY_POSITION_AND_ROTATION: u8 = 0x2F;
|
||||||
|
pub const MOVE_MINECART_ALONG_TRACK: u8 = 0x30;
|
||||||
|
pub const UPDATE_ENTITY_ROTATION: u8 = 0x31;
|
||||||
|
pub const MOVE_VEHICLE: u8 = 0x32;
|
||||||
|
pub const OPEN_BOOK: u8 = 0x33;
|
||||||
|
pub const OPEN_SCREEN: u8 = 0x34;
|
||||||
|
pub const OPEN_SIGN_EDITOR: u8 = 0x35;
|
||||||
|
pub const PING: u8 = 0x36;
|
||||||
|
pub const PING_RESPONSE: u8 = 0x37;
|
||||||
|
pub const PLACE_GHOST_RECIPE: u8 = 0x38;
|
||||||
|
pub const PLAYER_ABILITIES: u8 = 0x39;
|
||||||
|
pub const PLAYER_CHAT_MESSAGE: u8 = 0x3A;
|
||||||
|
pub const END_COMBAT: u8 = 0x3B;
|
||||||
|
pub const ENTER_COMBAT: u8 = 0x3C;
|
||||||
|
pub const COMBAT_DEATH: u8 = 0x3D;
|
||||||
|
pub const PLAYER_INFO_REMOVE: u8 = 0x3E;
|
||||||
|
pub const PLAYER_INFO_UPDATE: u8 = 0x3F;
|
||||||
|
pub const LOOK_AT: u8 = 0x40;
|
||||||
|
pub const SYNCHRONIZE_PLAYER_POSITION: u8 = 0x41;
|
||||||
|
pub const PLAYER_ROTATION: u8 = 0x42;
|
||||||
|
pub const RECIPE_BOOK_ADD: u8 = 0x43;
|
||||||
|
pub const RECIPE_BOOK_REMOVE: u8 = 0x44;
|
||||||
|
pub const RECIPE_BOOK_SETTINGS: u8 = 0x45;
|
||||||
|
pub const REMOVE_ENTITIES: u8 = 0x46;
|
||||||
|
pub const REMOVE_ENTITY_EFFECT: u8 = 0x47;
|
||||||
|
pub const RESET_SCORE: u8 = 0x48;
|
||||||
|
pub const REMOVE_RESOURCE_PACK: u8 = 0x49;
|
||||||
|
pub const ADD_RESOURCE_PACK: u8 = 0x4A;
|
||||||
|
pub const RESPAWN: u8 = 0x4B;
|
||||||
|
pub const SET_HEAD_ROTATION: u8 = 0x4C;
|
||||||
|
pub const UPDATE_SECTION_BLOCKS: u8 = 0x4D;
|
||||||
|
pub const SELECT_ADVANCEMENTS_TAB: u8 = 0x4E;
|
||||||
|
pub const SERVER_DATA: u8 = 0x4F;
|
||||||
|
pub const SET_ACTION_BAR_TEXT: u8 = 0x50;
|
||||||
|
pub const SET_BORDER_CENTER: u8 = 0x51;
|
||||||
|
pub const SET_BORDER_LERP_SIZE: u8 = 0x52;
|
||||||
|
pub const SET_BORDER_SIZE: u8 = 0x53;
|
||||||
|
pub const SET_BORDER_WARNING_DELAY: u8 = 0x54;
|
||||||
|
pub const SET_BORDER_WARNING_DISTANCE: u8 = 0x55;
|
||||||
|
pub const SET_CAMERA: u8 = 0x56;
|
||||||
|
pub const SET_CENTER_CHUNK: u8 = 0x57;
|
||||||
|
pub const SET_RENDER_DISTANCE: u8 = 0x58;
|
||||||
|
pub const SET_CURSOR_ITEM: u8 = 0x59;
|
||||||
|
pub const SET_DEFAULT_SPAWN_POSITION: u8 = 0x5A;
|
||||||
|
pub const DISPLAY_OBJECTIVE: u8 = 0x5B;
|
||||||
|
pub const SET_ENTITY_METADATA: u8 = 0x5C;
|
||||||
|
pub const LINK_ENTITIES: u8 = 0x5D;
|
||||||
|
pub const SET_ENTITY_VELOCITY: u8 = 0x5E;
|
||||||
|
pub const SET_EQUIPMENT: u8 = 0x5F;
|
||||||
|
pub const SET_EXPERIENCE: u8 = 0x60;
|
||||||
|
pub const SET_HEALTH: u8 = 0x61;
|
||||||
|
pub const SET_HELD_ITEM: u8 = 0x62;
|
||||||
|
pub const UPDATE_OBJECTIVES: u8 = 0x63;
|
||||||
|
pub const SET_PASSENGERS: u8 = 0x64;
|
||||||
|
pub const SET_PLAYER_INVENTORY_SLOT: u8 = 0x65;
|
||||||
|
pub const UPDATE_TEAMS: u8 = 0x66;
|
||||||
|
pub const UPDATE_SCORE: u8 = 0x67;
|
||||||
|
pub const SET_SIMULATION_DISTANCE: u8 = 0x68;
|
||||||
|
pub const SET_SUBTITLE_TEXT: u8 = 0x69;
|
||||||
|
pub const UPDATE_TIME: u8 = 0x6A;
|
||||||
|
pub const SET_TITLE_TEXT: u8 = 0x6B;
|
||||||
|
pub const SET_TITLE_ANIMATION_TIMES: u8 = 0x6C;
|
||||||
|
pub const ENTITY_SOUND_EFFECT: u8 = 0x6D;
|
||||||
|
pub const SOUND_EFFECT: u8 = 0x6E;
|
||||||
|
pub const START_CONFIGURATION: u8 = 0x6F;
|
||||||
|
pub const STOP_SOUND: u8 = 0x70;
|
||||||
|
pub const STORE_COOKIE: u8 = 0x71;
|
||||||
|
pub const SYSTEM_CHAT_MESSAGE: u8 = 0x72;
|
||||||
|
pub const SET_TAB_LIST_HEADER_AND_FOOTER: u8 = 0x73;
|
||||||
|
pub const TAG_QUERY_RESPONSE: u8 = 0x74;
|
||||||
|
pub const PICKUP_ITEM: u8 = 0x75;
|
||||||
|
pub const SYNCHRONIZE_VEHICLE_POSITION: u8 = 0x76;
|
||||||
|
pub const TEST_INSTANCE_BLOCK_STATUS: u8 = 0x77;
|
||||||
|
pub const SET_TICKING_STATE: u8 = 0x78;
|
||||||
|
pub const STEP_TICK: u8 = 0x79;
|
||||||
|
pub const TRANSFER: u8 = 0x7A;
|
||||||
|
pub const UPDATE_ADVANCEMENTS: u8 = 0x7B;
|
||||||
|
pub const UPDATE_ATTRIBUTES: u8 = 0x7C;
|
||||||
|
pub const ENTITY_EFFECT: u8 = 0x7D;
|
||||||
|
pub const UPDATE_RECIPES: u8 = 0x7E;
|
||||||
|
pub const UPDATE_TAGS: u8 = 0x7F;
|
||||||
|
pub const PROJECTILE_POWER: u8 = 0x80;
|
||||||
|
pub const CUSTOM_REPORT_DETAILS: u8 = 0x81;
|
||||||
|
pub const SERVER_LINKS: u8 = 0x82;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod serverbound {
|
||||||
|
pub mod handshake {
|
||||||
|
pub const HANDSHAKE: u8 = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod status {
|
||||||
|
pub const REQUEST: u8 = 0x00;
|
||||||
|
pub const PING_REQUEST: u8 = 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod login {
|
||||||
|
pub const START: u8 = 0x00;
|
||||||
|
pub const ENCRYPTION_RESPONSE: u8 = 0x01;
|
||||||
|
pub const PLUGIN_RESPONSE: u8 = 0x02;
|
||||||
|
pub const ACKNOWLEDGED: u8 = 0x03;
|
||||||
|
pub const COOKIE_RESPONSE: u8 = 0x04;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod configuration {
|
||||||
|
pub const CLIENT_INFORMATION: u8 = 0x00;
|
||||||
|
pub const COOKIE_RESPONSE: u8 = 0x01;
|
||||||
|
pub const PLUGIN_MESSAGE: u8 = 0x02;
|
||||||
|
pub const ACKNOWLEDGE_FINISH: u8 = 0x03;
|
||||||
|
pub const KEEP_ALIVE: u8 = 0x04;
|
||||||
|
pub const PONG: u8 = 0x05;
|
||||||
|
pub const RESOURCE_PACK_RESPONSE: u8 = 0x06;
|
||||||
|
pub const KNOWN_PACKS: u8 = 0x07;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod play {
|
||||||
|
pub const CONFIRM_TELEPORTATION: u8 = 0x00;
|
||||||
|
pub const QUERY_BLOCK_ENTITY_TAG: u8 = 0x01;
|
||||||
|
pub const BUNDLE_ITEM_SELECTED: u8 = 0x02;
|
||||||
|
pub const CHANGE_DIFFICULTY: u8 = 0x03;
|
||||||
|
pub const ACKNOWLEDGE_MESSAGE: u8 = 0x04;
|
||||||
|
pub const CHAT_COMMAND: u8 = 0x05;
|
||||||
|
pub const SIGNED_CHAT_COMMAND: u8 = 0x06;
|
||||||
|
pub const CHAT_MESSAGE: u8 = 0x07;
|
||||||
|
pub const PLAYER_SESSION: u8 = 0x08;
|
||||||
|
pub const CHUNK_BATCH_RECEIVED: u8 = 0x09;
|
||||||
|
pub const CLIENT_STATUS: u8 = 0x0A;
|
||||||
|
pub const CLIENT_TICK_END: u8 = 0x0B;
|
||||||
|
pub const CLIENT_INFORMATION: u8 = 0x0C;
|
||||||
|
pub const COMMAND_SUGGESTIONS_REQUEST: u8 = 0x0D;
|
||||||
|
pub const ACKNOWLEDGE_CONFIGURATION: u8 = 0x0E;
|
||||||
|
pub const CLICK_CONTAINER_BUTTON: u8 = 0x0F;
|
||||||
|
pub const CLICK_CONTAINER: u8 = 0x10;
|
||||||
|
pub const CLOSE_CONTAINER: u8 = 0x11;
|
||||||
|
pub const CHANGE_CONTAINER_SLOT_STATE: u8 = 0x12;
|
||||||
|
pub const COOKIE_RESPONSE: u8 = 0x13;
|
||||||
|
pub const PLUGIN_MESSAGE: u8 = 0x14;
|
||||||
|
pub const DEBUG_SAMPLE_SUBSCRIPTION: u8 = 0x15;
|
||||||
|
pub const EDIT_BOOK: u8 = 0x16;
|
||||||
|
pub const QUERY_ENTITY_TAG: u8 = 0x17;
|
||||||
|
pub const INTERACT: u8 = 0x18;
|
||||||
|
pub const JIGSAW_GENERATE: u8 = 0x19;
|
||||||
|
pub const KEEP_ALIVE: u8 = 0x1A;
|
||||||
|
pub const LOCK_DIFFICULTY: u8 = 0x1B;
|
||||||
|
pub const SET_PLAYER_POSITION: u8 = 0x1C;
|
||||||
|
pub const SET_PLAYER_POSITION_AND_ROTATION: u8 = 0x1D;
|
||||||
|
pub const SET_PLAYER_ROTATION: u8 = 0x1E;
|
||||||
|
pub const SET_PLAYER_MOVEMENT_FLAGS: u8 = 0x1F;
|
||||||
|
pub const MOVE_VEHICLE: u8 = 0x20;
|
||||||
|
pub const PADDLE_BOAT: u8 = 0x21;
|
||||||
|
pub const PICK_ITEM_FROM_BLOCK: u8 = 0x22;
|
||||||
|
pub const PICK_ITEM_FROM_ENTITY: u8 = 0x23;
|
||||||
|
pub const PING_REQUEST: u8 = 0x24;
|
||||||
|
pub const PLACE_RECIPE: u8 = 0x25;
|
||||||
|
pub const PLAYER_ABILITIES: u8 = 0x26;
|
||||||
|
pub const PLAYER_ACTION: u8 = 0x27;
|
||||||
|
pub const PLAYER_COMMAND: u8 = 0x28;
|
||||||
|
pub const PLAYER_INPUT: u8 = 0x29;
|
||||||
|
pub const PLAYER_LOADED: u8 = 0x2A;
|
||||||
|
pub const PONG: u8 = 0x2B;
|
||||||
|
pub const CHANGE_RECIPE_BOOK_SETTINGS: u8 = 0x2C;
|
||||||
|
pub const SET_SEEN_RECIPE: u8 = 0x2D;
|
||||||
|
pub const RENAME_ITEM: u8 = 0x2E;
|
||||||
|
pub const RESOURCE_PACK_RESPONSE: u8 = 0x2F;
|
||||||
|
pub const SEEN_ADVANCEMENTS: u8 = 0x30;
|
||||||
|
pub const SELECT_TRADE: u8 = 0x31;
|
||||||
|
pub const SET_BEACON_EFFECT: u8 = 0x32;
|
||||||
|
pub const SET_HELD_ITEM: u8 = 0x33;
|
||||||
|
pub const PROGRAM_COMMAND_BLOCK: u8 = 0x34;
|
||||||
|
pub const PROGRAM_COMMAND_BLOCK_MINECART: u8 = 0x35;
|
||||||
|
pub const SET_CREATIVE_MODE_SLOT: u8 = 0x36;
|
||||||
|
pub const PROGRAM_JIGSAW_BLOCK: u8 = 0x37;
|
||||||
|
pub const PROGRAM_STRUCTURE_BLOCK: u8 = 0x38;
|
||||||
|
pub const SET_TEST_BLOCK: u8 = 0x39;
|
||||||
|
pub const UPDATE_SIGN: u8 = 0x3A;
|
||||||
|
pub const SWING_ARM: u8 = 0x3B;
|
||||||
|
pub const TELEPORT_TO_ENTITY: u8 = 0x3C;
|
||||||
|
pub const TEST_INSTANCE_BLOCK_ACTION: u8 = 0x3D;
|
||||||
|
pub const USE_ITEM_ON: u8 = 0x3E;
|
||||||
|
pub const USE_ITEM: u8 = 0x3F;
|
||||||
|
}
|
||||||
|
}
|
20
src/data/reader.rs
Normal file
20
src/data/reader.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
use super::DataError;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub trait Reader {
|
||||||
|
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Read> Reader for R {
|
||||||
|
fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, DataError> {
|
||||||
|
let mut buf = vec![0; size];
|
||||||
|
match self.read_exact(&mut buf) {
|
||||||
|
Ok(_) => Ok(buf),
|
||||||
|
Err(_) => Err(DataError::ReadError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
103
src/data/writer.rs
Normal file
103
src/data/writer.rs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
use std::io::{Cursor, Seek, SeekFrom, Write};
|
||||||
|
|
||||||
|
use flate2::{write::ZlibEncoder, Compression};
|
||||||
|
use tokio::io::{AsyncWrite, AsyncWriteExt};
|
||||||
|
|
||||||
|
use super::{packet::{self, Packet}, DataError};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub fn compress(bytes: &[u8], compression: u32) -> Result<Vec<u8>, DataError> {
|
||||||
|
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::new(compression));
|
||||||
|
encoder.write_all(bytes).or(Err(DataError::ZlibError))?;
|
||||||
|
encoder.finish().or(Err(DataError::ZlibError))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait DataWriter {
|
||||||
|
async fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError>;
|
||||||
|
|
||||||
|
async fn write_byte(&mut self, value: u8) -> Result<(), DataError> {
|
||||||
|
self.write_bytes(&[value]).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn write_signed_byte(&mut self, value: i8) -> Result<(), DataError> {
|
||||||
|
self.write_byte(value as u8).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn write_varint_size(&mut self, value: i32) -> Result<usize, DataError> {
|
||||||
|
let mut _value = value as u32;
|
||||||
|
let mut position = 0;
|
||||||
|
loop {
|
||||||
|
let mut byte = (_value & 127) as u8;
|
||||||
|
position += 1; _value >>= 7;
|
||||||
|
if _value != 0 { byte += 128; };
|
||||||
|
self.write_byte(byte).await?;
|
||||||
|
if _value == 0 { return Ok(position) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn write_varint(&mut self, value: i32) -> Result<(), DataError> {
|
||||||
|
self.write_varint_size(value).await?; Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn write_packet(&mut self, packet: Packet, threshold: Option<usize>)
|
||||||
|
-> Result<(), DataError> {
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
|
||||||
|
let mut data_buf = Vec::new();
|
||||||
|
data_buf.write_varint((packet.id() as u32) as i32).await?;
|
||||||
|
data_buf.write_bytes(packet.get_bytes()).await?;
|
||||||
|
|
||||||
|
if let Some(threshold) = threshold {
|
||||||
|
let mut packet_buf = Vec::new();
|
||||||
|
|
||||||
|
if data_buf.len() > threshold {
|
||||||
|
packet_buf.write_varint(data_buf.len() as i32).await?;
|
||||||
|
let compressed_data = compress(&data_buf, 5)?;
|
||||||
|
Write::write_all(&mut packet_buf, &compressed_data).or(Err(DataError::WriteError))?;
|
||||||
|
} else {
|
||||||
|
packet_buf.write_varint(0).await?;
|
||||||
|
packet_buf.write_bytes(&data_buf).await?;
|
||||||
|
}
|
||||||
|
buf.write_varint(packet_buf.len() as i32).await?;
|
||||||
|
buf.write_bytes(&packet_buf).await?;
|
||||||
|
} else {
|
||||||
|
buf.write_varint(data_buf.len() as i32).await?;
|
||||||
|
buf.write_bytes(&data_buf).await?;
|
||||||
|
}
|
||||||
|
self.write_bytes(&buf).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn write_short(&mut self, value: u16) -> Result<(), DataError> {
|
||||||
|
self.write_bytes(&value.to_be_bytes()).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn write_signed_short(&mut self, value: i16) -> Result<(), DataError> {
|
||||||
|
self.write_short(value as u16).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn write_string(&mut self, value: &str) -> Result<(), DataError> {
|
||||||
|
self.write_varint(value.len() as i32).await?;
|
||||||
|
self.write_bytes(value.as_bytes()).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn write_long(&mut self, value: u64) -> Result<(), DataError> {
|
||||||
|
self.write_bytes(&value.to_be_bytes()).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn write_signed_long(&mut self, value: i64) -> Result<(), DataError> {
|
||||||
|
self.write_long(value as u64).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn write_uuid(&mut self, value: u128) -> Result<(), DataError> {
|
||||||
|
self.write_bytes(&value.to_be_bytes()).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: AsyncWrite + Unpin> DataWriter for W {
|
||||||
|
async fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), DataError> {
|
||||||
|
AsyncWriteExt::write_all(self, bytes).await.or(Err(DataError::WriteError))
|
||||||
|
}
|
||||||
|
}
|
34
src/main.rs
34
src/main.rs
@ -1,12 +1,11 @@
|
|||||||
|
|
||||||
use std::{io::Cursor, net::Shutdown};
|
|
||||||
|
|
||||||
use data::{DataError, DataReader};
|
|
||||||
use inet::Server;
|
use inet::Server;
|
||||||
use tokio::{io::AsyncWriteExt, net::TcpStream};
|
|
||||||
|
|
||||||
mod data;
|
mod data;
|
||||||
mod inet;
|
mod inet;
|
||||||
|
mod cycle;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
@ -17,34 +16,7 @@ async fn main() {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
let stream = server.accept().await;
|
let stream = server.accept().await;
|
||||||
tokio::spawn(test(stream));
|
tokio::spawn(cycle::main(stream));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn test(mut stream: TcpStream) {
|
|
||||||
let Ok(addr) = stream.peer_addr() else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
println!("Подключение: {addr}");
|
|
||||||
// читаем первый пакет
|
|
||||||
match read_first_packet(&mut stream).await {
|
|
||||||
Ok(_) => {}, Err(e) => println!("Ошибка во время обработки пакета: {e:?}")
|
|
||||||
}
|
|
||||||
println!("Отключение: {addr}");
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_first_packet(stream: &mut TcpStream) -> Result<(), DataError> {
|
|
||||||
let size = stream.read_varint().await?;
|
|
||||||
let mut buf = Cursor::new(stream.read_bytes(size as usize).await?);
|
|
||||||
let id = buf.read_varint().await?;
|
|
||||||
let version = buf.read_varint().await?;
|
|
||||||
let host = buf.read_string().await?;
|
|
||||||
let port = buf.read_short().await?;
|
|
||||||
let ns = buf.read_varint().await?;
|
|
||||||
println!("Айди пакета: {id}");
|
|
||||||
println!("Версия протокола: {version}");
|
|
||||||
println!("Адрес сервера: {host}:{port}");
|
|
||||||
println!("Следующее состояние: {ns}");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user