diff --git a/Cargo.lock b/Cargo.lock index dccb4f4..1454396 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "async-trait" -version = "0.1.48" +version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf" +checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" dependencies = [ "proc-macro2", "quote", @@ -32,15 +32,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "byteorder" @@ -50,15 +50,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] name = "cc" -version = "1.0.67" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "cesu8" @@ -124,9 +124,9 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.1.8" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15b8ec3b5755a188c141c1f6a98e76de31b936209bf066b647979e2a84764a9" +checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf" dependencies = [ "nix", "winapi", @@ -134,20 +134,21 @@ dependencies = [ [[package]] name = "fastnbt" -version = "1.3.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a5f728dc3e8c3154312f657d6cc9afd081b8c1becddc62ed67448e0a19adfd" +checksum = "adbc536576ecb712740a53d5bf4c64f38ee0ceb221f3f90980919e7506e38cb7" dependencies = [ "byteorder", "cesu8", "serde", + "serde_bytes", ] [[package]] name = "fern" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9a4820f0ccc8a7afd67c39a0f1a0f4b07ca1725164271a64939d7aeb9af065" +checksum = "3bdd7b0849075e79ee9a1836df22c717d1eba30451796fdc631b04565dd11e2a" dependencies = [ "colored", "log", @@ -155,9 +156,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.13" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ "futures-channel", "futures-core", @@ -170,9 +171,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.13" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", "futures-sink", @@ -180,15 +181,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.13" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-executor" -version = "0.3.13" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ "futures-core", "futures-task", @@ -197,17 +198,16 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.13" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-macro" -version = "0.3.13" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ - "proc-macro-hack", "proc-macro2", "quote", "syn", @@ -215,21 +215,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.13" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.13" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-util" -version = "0.3.13" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures-channel", "futures-core", @@ -240,34 +240,23 @@ dependencies = [ "memchr", "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] -[[package]] -name = "instant" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" -dependencies = [ - "cfg-if 1.0.0", -] - [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "lazy_static" @@ -277,74 +266,85 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.86" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" +checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" [[package]] name = "lock_api" -version = "0.4.2" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] [[package]] name = "mio" -version = "0.7.9" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" dependencies = [ "libc", "log", "miow", "ntapi", + "wasi 0.11.0+wasi-snapshot-preview1", "winapi", ] [[package]] name = "miow" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "socket2", "winapi", ] [[package]] name = "nix" -version = "0.20.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ "bitflags", "cc", "cfg-if 1.0.0", "libc", + "memoffset", ] [[package]] name = "ntapi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" dependencies = [ "winapi", ] @@ -370,9 +370,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -380,40 +380,38 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10acf907b94fc1b1a152d08ef97e7759650268cf986bf127f387e602b02c7e5a" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" dependencies = [ - "instant", "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" dependencies = [ "cfg-if 1.0.0", - "instant", "libc", "redox_syscall", "smallvec", - "winapi", + "windows-sys", ] [[package]] name = "pin-project-lite" -version = "0.2.4" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pin-utils" @@ -421,41 +419,29 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] [[package]] name = "radix64" -version = "0.3.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22a338c2456e0b6ca64681985cbc1b60a50473474f224899b0ee932e244893e" +checksum = "999718fa65c3be3a74f3f6dae5a98526ff436ea58a82a574f0de89eecd342bee" dependencies = [ "arrayref", "cfg-if 0.1.10", @@ -463,18 +449,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.5" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "scopeguard" @@ -484,18 +470,27 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.123" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] -name = "serde_derive" -version = "1.0.123" +name = "serde_bytes" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31" +checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -504,9 +499,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" dependencies = [ "itoa", "ryu", @@ -515,41 +510,40 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" dependencies = [ "libc", ] [[package]] name = "slab" -version = "0.4.2" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" [[package]] name = "smallvec" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "socket2" -version = "0.3.19" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ - "cfg-if 1.0.0", "libc", "winapi", ] [[package]] name = "syn" -version = "1.0.64" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd9d1e9976102a03c542daa2eff1b43f9d72306342f3f8b3ed5fb8908195d6f" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" dependencies = [ "proc-macro2", "quote", @@ -563,17 +557,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", - "wasi", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi", ] [[package]] name = "tokio" -version = "1.2.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a" +checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" dependencies = [ - "autocfg", "bytes", "libc", "memchr", @@ -583,15 +576,16 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", + "socket2", "tokio-macros", "winapi", ] [[package]] name = "tokio-macros" -version = "1.1.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" dependencies = [ "proc-macro2", "quote", @@ -600,18 +594,18 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ "serde", ] [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "uuid" @@ -625,6 +619,12 @@ version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "winapi" version = "0.3.9" @@ -646,3 +646,46 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" + +[[package]] +name = "windows_i686_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" + +[[package]] +name = "windows_i686_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" diff --git a/Cargo.toml b/Cargo.toml index e1fa9a9..d5db07c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,26 +1,26 @@ [package] +authors = ["Garen Tyler "] +description = "An extremely fast Minecraft server" +edition = "2021" +license = "MIT" name = "composition" version = "0.1.0" -authors = ["Garen Tyler "] -edition = "2018" -description = "An extremely fast 1.8.9 Minecraft server" -license = "MIT" [dependencies] -log = "0.4" -fern = { version = "0.6", features = ["colored"] } -chrono = "0.4.13" -serde = { version = "1.0.114", features = ["serde_derive"]} -serde_json = "1.0.59" -toml = "0.5" -radix64 = "0.3.0" -tokio = { version = "1", features = ["full"] } async-trait = "0.1.48" -lazy_static = "1.4.0" +chrono = "0.4.13" ctrlc = "3.1.8" -futures = "0.3.13" -uuid = "0.8.2" fastnbt = "*" +fern = {version = "0.6", features = ["colored"]} +futures = "0.3.13" +lazy_static = "1.4.0" +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" # colorful = "0.2.1" # ozelot = "0.9.0" # Ozelot 0.9.0 supports protocol version 578 (1.15.2) diff --git a/LICENSE b/LICENSE index f7297e7..2c8b763 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Garen Tyler +Copyright (c) 2020-2022 Garen Tyler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index e86e04b..1c92894 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ The main goal is to get a working server, then optimize for speed. ## Development Resources - - [Normal Login Sequence](https://wiki.vg/Protocol_FAQ#What.27s_the_normal_login_sequence_for_a_client.3F) - - [Protocol Specification](https://wiki.vg/Protocol) - - [Server Ping](https://wiki.vg/Server_List_Ping) - - [Map Format](https://wiki.vg/Map_Format) - - [Rust TcpStream Docs](https://doc.rust-lang.org/std/net/struct.TcpStream.html) - - [Rust Channel Docs](https://doc.rust-lang.org/std/sync/mpsc/index.html) +- [Normal Login Sequence](https://wiki.vg/Protocol_FAQ#What.27s_the_normal_login_sequence_for_a_client.3F) +- [Protocol Specification](https://wiki.vg/Protocol) +- [Server Ping](https://wiki.vg/Server_List_Ping) +- [Map Format](https://wiki.vg/Map_Format) +- [Rust TcpStream Docs](https://doc.rust-lang.org/std/net/struct.TcpStream.html) +- [Rust Channel Docs](https://doc.rust-lang.org/std/sync/mpsc/index.html) diff --git a/composition.toml b/composition.toml index ef69dbb..a294d84 100644 --- a/composition.toml +++ b/composition.toml @@ -1,4 +1,4 @@ -port = 25565 +favicon = "server-icon.png" max_players = 20 motd = "Composition MOTD" -favicon = "server-icon.png" +port = 25565 diff --git a/src/lib.rs b/src/lib.rs index 0be38f1..5598efc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,7 @@ pub struct Config { pub favicon: String, } +pub static PROTOCOL_VERSION: i32 = 757; lazy_static! { pub static ref CONFIG: Config = { let config_from_file = || -> std::io::Result { @@ -89,16 +90,18 @@ pub fn init() -> Receiver<()> { /// Start the server. pub async fn start_server() -> server::Server { - server::Server::new(format!("0.0.0.0:{}", CONFIG.port)) + server::Server::new(format!("0.0.0.0:{}", CONFIG.port)).await } pub mod prelude { - pub use crate::{mctypes::*, CONFIG, FAVICON}; + pub use crate::{mctypes::*, CONFIG, FAVICON, PROTOCOL_VERSION, START_TIME}; pub use log::*; pub use serde::{Deserialize, Serialize}; + pub use serde_json::json; pub type JSON = serde_json::Value; pub type NBT = fastnbt::Value; pub use std::collections::VecDeque; + pub use tokio::io::{AsyncReadExt, AsyncWriteExt}; #[derive(Clone, Debug, PartialEq)] pub enum ParseError { NotEnoughData, diff --git a/src/main.rs b/src/main.rs index fd16e2d..e7b3b7c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,7 +13,7 @@ pub async fn main() { loop { match ctrlc_rx.try_recv() { Ok(_) => { - server.shutdown().await; + let _ = server.shutdown().await; break; // Exit the loop. } Err(TryRecvError::Empty) => {} // Doesn't matter if there's nothing for us. diff --git a/src/mctypes/numbers.rs b/src/mctypes/numbers.rs index 38624c7..be72a62 100644 --- a/src/mctypes/numbers.rs +++ b/src/mctypes/numbers.rs @@ -74,13 +74,11 @@ pub fn parse_varint(data: &[u8]) -> ParseResult { Ok((output, bytes_read as usize)) } pub fn serialize_varint(value: i32) -> Vec { - println!("serializing {}", value); let mut value = value as u32; let mut output = vec![]; loop { let data = (value & 0x7f) as u8; value >>= 7; - println!("\tvalue: {}", value); if value == 0 { output.push(data); diff --git a/src/mctypes/other.rs b/src/mctypes/other.rs index 0952e0b..64ae9c1 100644 --- a/src/mctypes/other.rs +++ b/src/mctypes/other.rs @@ -36,8 +36,13 @@ pub fn serialize_string(value: &str) -> Vec { } pub fn parse_json(data: &[u8]) -> ParseResult { - unimplemented!() + let (value_string, offset) = parse_string(data)?; + if let Ok(value) = serde_json::from_str(&value_string) { + Ok((value, offset)) + } else { + Err(ParseError::InvalidData) + } } pub fn serialize_json(value: JSON) -> Vec { - unimplemented!() + serialize_string(&serde_json::to_string(&value).expect("Could not serialize JSON")) } diff --git a/src/net/mod.rs b/src/net/mod.rs index 6b73a97..126c03b 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -1,6 +1,8 @@ pub mod packets; use crate::prelude::*; +pub use packets::Packet; +use std::time::{Duration, Instant}; use tokio::net::TcpStream; #[derive(PartialEq, Copy, Clone, Debug)] @@ -13,12 +15,82 @@ pub enum NetworkClientState { } pub struct NetworkClient { - pub status: NetworkClientState, + pub id: u128, + pub state: NetworkClientState, pub stream: TcpStream, pub buffer: VecDeque, + pub packet_queue: VecDeque, + pub last_data_time: Instant, } impl NetworkClient { - pub async fn read_bytes(&mut self) -> Result<(), ()> { - unimplemented!() + pub fn new(id: u128, stream: TcpStream) -> NetworkClient { + NetworkClient { + id, + state: NetworkClientState::Handshake, + stream, + buffer: VecDeque::new(), + packet_queue: VecDeque::new(), + last_data_time: Instant::now(), + } + } + pub async fn read_data(&mut self) -> Result<(), tokio::io::Error> { + trace!("NetworkClient.read_data()"); + // Try to read 4kb at a time until there is no more data. + loop { + let mut buf = [0; 4096]; + match self.stream.try_read(&mut buf) { + // There is no data available. + Ok(0) => break, + // Data was read. + Ok(n) => { + self.last_data_time = Instant::now(); + self.buffer.extend(&buf[0..n]); + debug!("Read {} bytes from client {}", n, self.id); + } + Err(ref e) if e.kind() == tokio::io::ErrorKind::WouldBlock => break, + Err(e) => { + return Err(e.into()); + } + } + } + Ok(()) + } + pub fn read_packet(&mut self) -> Result<(), ParseError> { + trace!("NetworkClient.read_packet()"); + self.buffer.make_contiguous(); + if let (data, &[]) = self.buffer.as_slices() { + let mut offset = 0; + let (packet_length, offset_delta) = parse_varint(&data[offset..])?; + offset += offset_delta; + let packet_length = packet_length as usize; + let (packet_id, offset_delta) = parse_varint(&data[offset..])?; + offset += offset_delta; + let packet_id = packet_id as usize; + let (packet, offset_delta) = + Packet::parse_body(&data[offset..], packet_length, packet_id, self.state, true)?; + debug!("Got packet {:?} from client {}", packet, self.id); + offset += offset_delta; + self.packet_queue.push_back(packet); + let remaining_data = self.buffer.split_off(offset); + self.buffer = remaining_data; + } + Ok(()) + } + pub async fn send_packet(&mut self, packet: Packet) -> Result<(), tokio::io::Error> { + let bytes = packet.serialize(); + self.stream.write(&bytes).await?; + Ok(()) + } + pub async fn update(&mut self) { + // if self.state == NetworkClientState::Disconnected { + // return Err(tokio::io::Error::from(tokio::io::ErrorKind::BrokenPipe)); + // } else if self.last_data_time.elapsed() > Duration::from_secs(10) { + // return self.disconnect(tokio::io::ErrorKind::TimedOut); + // } + let _ = self.read_data().await; + let _ = self.read_packet(); + } + pub fn disconnect(&mut self) { + self.state = NetworkClientState::Disconnected; } } diff --git a/src/net/packets.rs b/src/net/packets.rs index 90b3577..bbb52e8 100644 --- a/src/net/packets.rs +++ b/src/net/packets.rs @@ -13,7 +13,11 @@ pub enum Packet { // Status CS00Response { - json_response: JSON, + version_name: String, + protocol_version: i32, + max_players: usize, + current_players: usize, + description: JSON, }, CS01Pong { payload: i64, @@ -50,12 +54,12 @@ impl Packet { let (next_state, offset_delta) = parse_varint(&data[offset..])?; offset += offset_delta; let next_state = match next_state { - 0 => NetworkClientState::Status, - 1 => NetworkClientState::Login, + 1 => NetworkClientState::Status, + 2 => NetworkClientState::Login, _ => return Err(ParseError::InvalidData), }; Ok(( - Packet::SH00Handshake { + SH00Handshake { protocol_version, server_address, server_port, @@ -70,14 +74,16 @@ impl Packet { Status => match id { 0x00 => { if serverbound { - unimplemented!("Parse SS00Request") + Ok((SS00Request, offset)) } else { unimplemented!("Parse CS00Response") } } 0x01 => { if serverbound { - unimplemented!("Parse SS01Ping") + let (payload, offset_delta) = parse_long(&data[offset..])?; + offset += offset_delta; + Ok((SS01Ping { payload }, offset)) } else { unimplemented!("Parse CS01Pong") } @@ -91,7 +97,28 @@ impl Packet { pub fn serialize(&self) -> Vec { use Packet::*; let (id, mut body): (usize, Vec) = match self { - CS00Response { json_response } => (0x00, serialize_json(json_response.clone())), + CS00Response { + version_name, + protocol_version, + max_players, + current_players, + description, + } => ( + 0x00, + serialize_json(serde_json::json!({ + "version": { + "name": version_name, + "protocol": protocol_version, + }, + "players": { + "max": max_players, + "online": current_players, + }, + "description": description, + // TODO: Add base64 favicon + "favicon": format!("data:image/png;base64,{}", radix64::STD_NO_PAD.encode(FAVICON.as_ref().unwrap())), + })), + ), CS01Pong { payload } => (0x01, serialize_long(payload.clone()).to_vec()), _ => unimplemented!(), }; diff --git a/src/server/mod.rs b/src/server/mod.rs index 17648c5..96d1428 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,18 +1,141 @@ -use crate::prelude::*; -use tokio::net::ToSocketAddrs; +use crate::{net::*, prelude::*}; +use tokio::{ + net::{TcpListener, ToSocketAddrs}, + sync::mpsc::{self, error::TryRecvError, UnboundedReceiver}, +}; #[derive(Clone, Debug, PartialEq)] pub enum ServerError {} -pub struct Server {} +pub struct Server { + network_client_receiver: UnboundedReceiver, + clients: Vec, +} impl Server { - pub fn new(bind_address: A) -> Server { - unimplemented!() + pub async fn new(bind_address: A) -> Server { + let (client_tx, client_rx) = mpsc::unbounded_channel(); + tokio::task::spawn(async move { + let listener = TcpListener::bind(bind_address) + .await + .expect("Could not bind to given address"); + let mut id = 0u128; + loop { + trace!("Server accepting new client"); + match listener.accept().await { + Ok((socket, addr)) => { + let _ = client_tx.send(NetworkClient::new(id, socket)); + debug!("Connected client {} at {:?}", id, addr); + id += 1; + } + Err(_) => break, + } + } + }); + Server { + network_client_receiver: client_rx, + clients: vec![], + } } pub async fn update(&mut self) -> Result<(), ServerError> { - unimplemented!() + trace!("Server.update()"); + // Read new clients from the receiver + loop { + match self.network_client_receiver.try_recv() { + Ok(client) => self.clients.push(client), + Err(TryRecvError::Empty) => break, + Err(TryRecvError::Disconnected) => panic!("Client sender disconnected"), + } + } + // Remove disconnected clients. + let mut i = 0; + while i < self.clients.len() { + if self.clients[i].state == NetworkClientState::Disconnected { + debug!("Removed client {}", self.clients[i].id); + self.clients.remove(i); + } else { + i += 1; + } + } + // Read data and try to parse packets from each client. + for client in self.clients.iter_mut() { + if client.state == NetworkClientState::Disconnected { + continue; + } + let _ = client.read_data().await; + 'packet: loop { + match client.read_packet() { + Ok(_) => {} + Err(ParseError::NotEnoughData) => break 'packet, + Err(e) => {} + } + } + } + // Handle each packet for each player. + 'client: for i in 0..self.clients.len() { + while let Some(packet) = self.clients[i].packet_queue.pop_front() { + if self.handle_packet(i, packet).await.is_err() { + continue 'client; + } + } + } + // Handle general world updates. + // Send out packets to each client. + + Ok(()) } - pub async fn shutdown(&mut self) -> Result<(), ServerError> { - unimplemented!() + pub async fn handle_packet(&mut self, client_index: usize, packet: Packet) -> Result<(), ()> { + use Packet::*; + trace!("Server.handle_packet()"); + debug!("Handling packet {:?}", packet); + let mut current_players = 0; + for client in &self.clients { + if client.state == NetworkClientState::Play { + current_players += 1; + } + } + // TODO: Make this count the number in the play state. + let client = &mut self.clients[client_index]; + match packet { + SH00Handshake { + protocol_version, + server_address: _, + server_port: _, + next_state, + } => { + if protocol_version != PROTOCOL_VERSION { + debug!( + "Disconnecting client {} for mismatched protocols: {} (expected {})", + client.id, protocol_version, PROTOCOL_VERSION + ); + client.disconnect(); + return Err(()); + } + client.state = next_state; + } + SS00Request => { + let _ = client + .send_packet(CS00Response { + version_name: "1.18.1".to_owned(), + protocol_version: PROTOCOL_VERSION, + max_players: CONFIG.max_players, + current_players, + description: json!({ + "text": "Hello world!" + }), + }) + .await; + } + SS01Ping { payload } => { + let _ = client.send_packet(CS01Pong { payload }).await; + debug!("Disconnecting client {}, SLP completed", client.id); + client.disconnect(); + } + _ => unimplemented!("Handling unknown packet"), + } + Ok(()) + } + pub async fn shutdown(self) -> Result<(), ServerError> { + trace!("Server.shutdown()"); + Ok(()) } }