diff --git a/.gitignore b/.gitignore index 6abfe1b..a6db884 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /target /.direnv +*.pem +*.p12 diff --git a/Cargo.lock b/Cargo.lock index e68c668..6553e46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,11 +26,77 @@ dependencies = [ "memchr", ] +[[package]] +name = "almost" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3aa2999eb46af81abb65c2d30d446778d7e613b60bbf4e174a027e80f90a3c14" + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + [[package]] name = "anyhow" version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +dependencies = [ + "backtrace", +] + +[[package]] +name = "array-init" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" + +[[package]] +name = "asn1-rs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" @@ -47,6 +113,63 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "binrw" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d4bca59c20d6f40c2cc0802afbe1e788b89096f61bdf7aeea6bf00f10c2909b" +dependencies = [ + "array-init", + "binrw_derive", + "bytemuck", +] + +[[package]] +name = "binrw_derive" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ba42866ce5bced2645bfa15e97eef2c62d2bdb530510538de8dd3d04efff3c" +dependencies = [ + "either", + "owo-colors", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" + [[package]] name = "byteorder" version = "1.5.0" @@ -68,12 +191,222 @@ dependencies = [ "spin", ] +[[package]] +name = "cc" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "clap" +version = "4.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +dependencies = [ + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cxx" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5a32d755fe20281b46118ee4b507233311fb7a48a0cfd42f554b93640521a2f" +dependencies = [ + "cc", + "cxxbridge-cmd", + "cxxbridge-flags", + "cxxbridge-macro", + "foldhash", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11645536ada5d1c8804312cbffc9ab950f2216154de431de930da47ca6955199" +dependencies = [ + "cc", + "codespan-reporting", + "proc-macro2", + "quote", + "scratch", + "syn 2.0.90", +] + +[[package]] +name = "cxxbridge-cmd" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcc9c78e3c7289665aab921a2b394eaffe8bdb369aa18d81ffc0f534fd49385" +dependencies = [ + "clap", + "codespan-reporting", + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a22a87bd9e78d7204d793261470a4c9d585154fddd251828d8aefbb5f74c3bf" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dfdb020ff8787c5daf6e0dca743005cc8782868faeadfbabb8824ede5cb1c72" +dependencies = [ + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.90", +] + +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + [[package]] name = "equivalent" version = "1.0.1" @@ -86,6 +419,21 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + [[package]] name = "futures-core" version = "0.3.31" @@ -110,12 +458,41 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + [[package]] name = "gimli" version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "glam" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677" + [[package]] name = "hash32" version = "0.3.1" @@ -141,6 +518,151 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "httlib-huffman" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9fcbcc408c5526c3ab80d534e5c86e7967c1fb7aa0a8c76abd1edc27deb877" + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "indexmap" version = "2.7.0" @@ -151,6 +673,28 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "join_str" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de046f45ca45d4526a5d340223c0e03cef1f06457bee78a523d5ce55894ac0a" + +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -163,6 +707,21 @@ version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" +[[package]] +name = "link-cplusplus" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" +dependencies = [ + "cc", +] + +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "log" version = "0.4.22" @@ -184,6 +743,12 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.0" @@ -201,7 +766,7 @@ checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", "wasi", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -223,6 +788,16 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -233,6 +808,40 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "object" version = "0.36.5" @@ -242,18 +851,61 @@ dependencies = [ "memchr", ] +[[package]] +name = "octets" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109983a091271ee8916076731ba5fdc9ee22fea871bc7c6ceab9bfd423eb1d99" + +[[package]] +name = "oid-registry" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" +dependencies = [ + "asn1-rs", +] + [[package]] name = "once_cell" version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + [[package]] name = "overload" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "pem" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +dependencies = [ + "base64", + "serde", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "pin-project-lite" version = "0.2.15" @@ -266,6 +918,21 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy 0.7.35", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -285,6 +952,58 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quinn" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.7", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +dependencies = [ + "bytes", + "getrandom", + "rand", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.7", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52cd4b1eff68bf27940dd39811292c49e007f4d0b4c357358dc9b0197be6b527" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "quote" version = "1.0.37" @@ -294,6 +1013,49 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rcgen" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54077e1872c46788540de1ea3d7f4ccb1983d12f9aa909b234468676c1a36779" +dependencies = [ + "pem", + "ring", + "rustls-pki-types", + "time", + "yasna", +] + [[package]] name = "regex" version = "1.11.1" @@ -338,12 +1100,227 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "roead" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa4e7e992638f39b4ecbde6f11e02dfbcf81dae42954ee5fba32111dd9e39ce" +dependencies = [ + "almost", + "binrw", + "cxx", + "cxx-build", + "indexmap", + "join_str", + "num-integer", + "num-traits", + "rustc-hash", + "rustc_version", + "serde", + "serde_json", + "smartstring", + "thiserror 1.0.69", +] + [[package]] name = "rustc-demangle" version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "rustls" +version = "0.23.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" +dependencies = [ + "web-time", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "scratch" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" + +[[package]] +name = "security-framework" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" + +[[package]] +name = "serde" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "serde_json" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -353,24 +1330,55 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + [[package]] name = "smo-server" version = "0.1.0" dependencies = [ "anyhow", + "crc32fast", + "glam", "heapless", "newtype-enum", + "roead", "tokio", "tracing", "tracing-subscriber", + "uuid", + "wtransport", "xtra", - "zerocopy", + "zerocopy 0.8.13", ] [[package]] @@ -380,7 +1388,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -395,6 +1403,24 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "1.0.109" @@ -417,6 +1443,66 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93605438cbd668185516ab499d589afb7ee1859ea3d5fc8f6b0755e1c7443767" +dependencies = [ + "thiserror-impl 2.0.7", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d8749b4531af2117677a5fcd12b1348a3fe2b81e36e61ffeac5c4aa3273e36" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -427,6 +1513,62 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.42.0" @@ -440,7 +1582,7 @@ dependencies = [ "pin-project-lite", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -532,24 +1674,144 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-ident" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +dependencies = [ + "getrandom", +] + [[package]] name = "valuable" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.90", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -566,6 +1828,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -581,6 +1852,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -654,6 +1934,72 @@ dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "wtransport" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93a724f65db90b6a1ffa92ea4966cf03cb7e2bcd3ef7135b84dfe4339640d1b9" +dependencies = [ + "bytes", + "pem", + "quinn", + "rcgen", + "rustls", + "rustls-native-certs", + "rustls-pemfile", + "rustls-pki-types", + "sha2", + "socket2", + "thiserror 1.0.69", + "time", + "tokio", + "tracing", + "url", + "wtransport-proto", + "x509-parser", +] + +[[package]] +name = "wtransport-proto" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14e4882c24a62f15024609b3688e6e29a4c2129634d27debc849ccd3f9b9690b" +dependencies = [ + "httlib-huffman", + "octets", + "thiserror 1.0.69", + "url", +] + +[[package]] +name = "x509-parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + [[package]] name = "xtra" version = "0.6.0" @@ -681,13 +2027,67 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive 0.7.35", +] + [[package]] name = "zerocopy" version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67914ab451f3bfd2e69e5e9d2ef3858484e7074d63f204fd166ec391b54de21d" dependencies = [ - "zerocopy-derive", + "zerocopy-derive 0.8.13", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -700,3 +2100,52 @@ dependencies = [ "quote", "syn 2.0.90", ] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] diff --git a/Cargo.toml b/Cargo.toml index a62d14b..fba54cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,11 +4,18 @@ version = "0.1.0" edition = "2021" [dependencies] -anyhow = "1.0.94" +anyhow = { version = "1.0.94", features = ["backtrace"] } +crc32fast = "1.4.2" +glam = "0.29.2" heapless = "0.8.0" newtype-enum = { git = "https://github.com/mgjm/newtype-enum", version = "0.1.0" } tokio = { version = "1.42.0", features = ["rt", "macros", "net", "sync", "rt-multi-thread", "io-util", "io-std"] } tracing = "0.1.41" tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } +uuid = { version = "1.11.0", features = ["v4"] } +wtransport = "0.5.0" xtra = { version = "0.6.0", features = ["macros", "tokio"] } zerocopy = { version = "0.8.13", features = ["derive"] } + +[dev-dependencies] +roead = "1.0.0" diff --git a/flake.nix b/flake.nix index e2d1263..572eb0a 100644 --- a/flake.nix +++ b/flake.nix @@ -21,6 +21,7 @@ devShells.default = mkShell { buildInputs = [ pkgs.fenix.stable.completeToolchain + cmake pkg-config openssl ]; diff --git a/src/main.rs b/src/main.rs index 7c89326..8edee84 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,38 +1,104 @@ +pub mod faker; +pub mod game; pub mod packet; pub mod player; +pub mod protocol; +pub mod server; -use std::{collections::HashMap, sync::LazyLock}; +use std::{ + collections::HashMap, + io::Cursor, + net::{SocketAddr, ToSocketAddrs}, + sync::{Arc, LazyLock}, +}; +use faker::Faker; +use packet::{rw::read_packet, Packet}; use player::PlayerActor; -use tokio::{net::TcpListener, sync::RwLock}; -use tracing::{error, info}; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; -use xtra::Address; +use server::web_main; +use tokio::{ + net::{TcpListener, UdpSocket}, + sync::RwLock, +}; +use tracing::{error, info, Level}; +use tracing_subscriber::{filter::FilterFn, layer::SubscriberExt, util::SubscriberInitExt, Layer}; +use xtra::{prelude::MessageChannel, Mailbox}; -pub fn clients() -> &'static RwLock>> { - static CLIENTS: LazyLock>>> = LazyLock::new(|| RwLock::default()); +type PacketChannel = MessageChannel; +pub fn clients() -> &'static RwLock> { + static CLIENTS: LazyLock>> = LazyLock::new(|| RwLock::default()); &CLIENTS } +pub async fn broadcast_packet(packet: Packet) { + for (id, (address, _)) in clients().read().await.iter() { + if *id != packet.user_id { + let _ = address.send(packet.clone()).detach().await.unwrap(); + } + } +} + #[tokio::main] async fn main() { - //.with(EnvFilter::from_default_env()) - tracing_subscriber::registry().with(tracing_subscriber::fmt::layer()).init(); + tracing_subscriber::registry() + .with(tracing_subscriber::fmt::layer().with_filter(FilterFn::new(|meta| { + *meta.level() < Level::INFO || meta.module_path().unwrap().contains("smo_server") + }))) + .init(); let tcp = TcpListener::bind("0.0.0.0:1027").await.unwrap(); + let manager = web_main(); + + { + let (address, mailbox) = Mailbox::unbounded(); + let address = xtra::spawn_tokio( + Faker { + address: address.clone(), + }, + (address, mailbox), + ); + clients().write().await.insert( + 1, + ( + MessageChannel::new(address), + "0.0.0.0:1027".to_socket_addrs().unwrap().next().unwrap(), + ), + ); + } + + let socket = Arc::new(UdpSocket::bind("0.0.0.0:1027").await.unwrap()); + tokio::spawn({ + let socket = socket.clone(); + async move { + loop { + let mut packet = [0u8; 256]; + let (size, _addr) = socket.recv_from(&mut packet).await.unwrap(); + // trace!("got packet from {_addr:?}"); + match read_packet(&mut Cursor::new(&mut packet[..size]), true).await { + Ok(packet) => { + // info!("packet from udp {packet:?}"); + if let Some(client) = clients().read().await.get(&packet.user_id) { + let _ = client.0.send(packet).detach().await; + } + } + Err(error) => { + error!("udp packet error: {error:?}"); + } + }; + } + } + }); + info!("listening on port 1027"); loop { match tcp.accept().await { Ok((stream, addr)) => { - PlayerActor::new_connection(stream, addr); + PlayerActor::new_connection(stream, addr, socket.clone(), manager.clone()); } Err(error) => { error!("failed to handle connection: {error:?}"); } } } - - // let socket = Arc::new(UdpSocket::bind("0.0.0.0:1027").await.unwrap()); - // let mut packet = [0u8; 1024]; } diff --git a/src/packet.rs b/src/packet.rs deleted file mode 100644 index 12b9b95..0000000 --- a/src/packet.rs +++ /dev/null @@ -1,213 +0,0 @@ -use core::str; -use std::{ - ffi::CStr, - fmt::{Debug, Display}, -}; - -use anyhow::{bail, Context}; -use newtype_enum::newtype_enum; -use zerocopy::{ - FromBytes, FromZeros, Immutable, IntoBytes, KnownLayout, Unaligned, -}; - -#[derive(Debug, Clone, Copy, FromZeros, IntoBytes, KnownLayout, Immutable)] -#[repr(C, packed)] -pub struct PacketHeader { - pub user_id: u128, - pub kind: PacketKind, - pub size: u16, -} - -#[derive(Debug, Clone, Copy, FromZeros, IntoBytes, KnownLayout, Immutable)] -#[repr(u16)] -pub enum PacketKind { - Unknown = 0, - Init = 1, - Player = 2, - Cap = 3, - Game = 4, - Tag = 5, - Connect = 6, - Disconnect = 7, - Costume = 8, - Shine = 9, - Capture = 10, - ChangeStage = 11, - Command = 12, - UdpInit = 13, - HolePunch = 14 -} - -const COSTUME_NAME_SIZE: usize = 0x20; -const CAP_ANIM_SIZE: usize = 0x30; -const STAGE_GAME_NAME_SIZE: usize = 0x40; -const STAGE_CHANGE_NAME_SIZE: usize = 0x30; -const STAGE_ID_SIZE: usize = 0x10; -const CLIENT_NAME_SIZE: usize = COSTUME_NAME_SIZE; - -#[derive(Debug)] -pub struct Packet { - pub user_id: u128, - pub data: PacketData, -} - -#[newtype_enum] -#[derive(Debug)] -pub enum PacketData { - Unknown(Vec), - #[derive(FromZeros, IntoBytes, KnownLayout, Immutable)] - #[repr(C, packed)] - Init { - pub max_players: u16, - }, - #[derive(FromZeros, IntoBytes, KnownLayout, Immutable)] - #[repr(C, packed)] - Player { - position: [f32; 3], - rotation: [f32; 4], - weights: [f32; 6], - action: u16, - subaction: u16, - }, - #[derive(FromZeros, IntoBytes, KnownLayout, Immutable)] - #[repr(C, packed)] - Cap { - position: [f32; 3], - rotation: [f32; 4], - out: Bool, - anim: String, - }, - #[derive(FromZeros, IntoBytes, KnownLayout, Immutable)] - #[repr(C, packed)] - Game { - is_2d: u8, - scenario_num: u8, - stage: String, - }, - #[derive(FromZeros, IntoBytes, KnownLayout, Immutable)] - #[repr(C, packed)] - Tag { - update_type: u8, - is_it: Bool, - seconds: u8, - minutes: u16, - }, - #[derive(FromZeros, IntoBytes, KnownLayout, Immutable)] - #[repr(C, packed)] - Connect { - kind: ConnectionKind, - max_player: u16, - client_name: String, - }, - Disconnect, - #[derive(FromZeros, IntoBytes, KnownLayout, Immutable)] - #[repr(C, packed)] - Costume { - body_name: String, - cap_name: String, - }, - #[derive(FromZeros, IntoBytes, KnownLayout, Immutable)] - #[repr(C, packed)] - Shine { - shine_id: i32, - is_grand: Bool, - }, - #[derive(FromZeros, IntoBytes, KnownLayout, Immutable)] - #[repr(C, packed)] - Capture { - model: String, - }, - #[derive(FromZeros, IntoBytes, KnownLayout, Immutable)] - #[repr(C, packed)] - ChangeStage { - stage: String, - id: String, - scenario: i8, - sub_scenario: u8, - }, - Command, - #[derive(FromZeros, IntoBytes, KnownLayout, Immutable)] - #[repr(C, packed)] - UdpInit { - port: u16 - }, - HolePunch -} - -pub enum TagUpdateBit { - Time = 0, - State = 1, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, FromZeros, IntoBytes, KnownLayout, Immutable)] -#[repr(u32)] -pub enum ConnectionKind { - New = 0, - Old = 1, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)] -#[repr(C)] -pub struct Bool(u8); - -impl Bool { - pub fn new(value: bool) -> Bool { - Bool(if value { 1 } else { 0 }) - } - pub fn get(&self) -> bool { - self.0 != 0 - } -} - -impl From for Bool { - fn from(value: bool) -> Self { - Bool::new(value) - } -} - -impl From for bool { - fn from(value: Bool) -> Self { - value.get() - } -} - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)] -#[repr(C)] -pub struct String([u8; N]); - -impl String { - pub fn to_str(&self) -> anyhow::Result<&str> { - let cstr = CStr::from_bytes_until_nul(&self.0).context("interpreting bytes as c-string")?; - cstr.to_str().context("verifying string has utf-8") - // let str = str::from_utf8(&self.0).context("verifying string has utf-8")?; - // Ok(str.trim_end_matches('\0')) - } - pub fn assert_valid(&self) -> anyhow::Result<()> { - self.to_str().map(drop) - } -} - -impl TryFrom<&str> for String { - type Error = anyhow::Error; - fn try_from(value: &str) -> Result { - let mut buf = [0; N]; - if value.len() > N { - bail!("seggs") - } - - value.write_to_prefix(&mut buf).unwrap(); - - Ok(Self(buf)) - } -} - -impl Display for String { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - Display::fmt(self.to_str().expect("failed to parse string"), f) - } -} -impl Debug for String { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - Debug::fmt(self.to_str().expect("failed to parse string"), f) - } -} diff --git a/src/player.rs b/src/player.rs index 3317b95..21e802a 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,183 +1,231 @@ -use std::{net::SocketAddr, time::Duration}; +use std::{io::Cursor, net::SocketAddr, sync::Arc}; -use anyhow::{bail, Context}; +use glam::Vec3; use tokio::{ - io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}, - net::{ - tcp::{OwnedReadHalf, OwnedWriteHalf}, - TcpStream, - }, sync::mpsc, time::Instant, + io::{BufReader, BufWriter}, + net::{TcpStream, UdpSocket}, + sync::mpsc, }; -use tracing::{info, info_span, trace, Instrument}; -use zerocopy::{IntoBytes, TryFromBytes}; +use tracing::{error, info, info_span, trace, Instrument}; +use xtra::{prelude::MessageChannel, scoped, Actor, Address, Handler, Mailbox}; -use crate::packet::{ - Packet, PacketData, - PacketData_variants::{Cap, Command, Connect, Disconnect, HolePunch, Init, Player}, - PacketHeader, PacketKind, String, +use crate::{ + broadcast_packet, clients, + packet::{ + rw::{read_packet, write_packet}, + ConnectionKind, Packet, PacketData, + PacketData_variants::{Connect, HolePunch, Init, UdpInit}, + CLIENT_NAME_SIZE, + }, + protocol::String, + server::{ChangedStage, Manager, PlayerConnected, PlayerMoved}, }; -// #[derive(Actor)] pub struct PlayerActor { - write_half: BufWriter, + id: u128, + connection_kind: ConnectionKind, + name: String, + write_sender: mpsc::UnboundedSender, + manager: Address, +} + +enum WriteMessage { + Data(Packet), + SetUdp(u16), } impl PlayerActor { - pub async fn read_packet(reader: &mut BufReader) -> anyhow::Result { - let mut header = [0; size_of::()]; - reader.read_exact(&mut header).await.context("reading data")?; - let Ok(header) = PacketHeader::try_read_from_bytes(&header) else { - bail!("parsing packet buffer") - }; - - macro_rules! read_data { - ($read: expr, $size: expr, $ty: ident $(, $field:ident => $assert: expr)*) => {{ - async fn read_data(reader: &mut BufReader, size: u16) -> anyhow::Result { - type T = crate::packet::PacketData_variants::$ty; - let size = size as usize; - if size < size_of::() { - bail!("buffer too small for packet: expected {}, got {size}", size_of::()) - } - let mut data = [0; u16::MAX as usize]; - reader.read_exact(&mut data[..size]).await.context("reading data")?; - let packet_data = match T::try_read_from_bytes(&data[..size_of::()]) { - Ok(data) => data, - Err(error) => { - bail!(concat!("interpreting ", stringify!($ty), ": {:?}"), error) - } - }; - - $( - { - let $field = packet_data.$field; - $assert - }?; - )* - Ok(PacketData::$ty(packet_data)) - } - type _FixIntellisense = crate::packet::PacketData_variants::$ty; - read_data($read, $size).await? - }}; - } - - let data: PacketData = match header.kind { - PacketKind::Unknown => { - let mut data = vec![0; header.size.into()]; - reader.read_exact(&mut data).await.context("reading unknown data")?; - PacketData::Unknown(data) - } - PacketKind::Init => read_data!(reader, header.size, Init), - PacketKind::Player => read_data!(reader, header.size, Player), - PacketKind::Cap => read_data!(reader, header.size, Cap, anim => anim.assert_valid()), - PacketKind::Game => read_data!(reader, header.size, Game, stage => stage.assert_valid()), - PacketKind::Tag => read_data!(reader, header.size, Tag), - PacketKind::Connect => read_data!(reader, header.size, Connect), - PacketKind::Disconnect => PacketData::Disconnect(Disconnect), - PacketKind::Costume => read_data!(reader, header.size, Costume), - PacketKind::Shine => read_data!(reader, header.size, Shine), - PacketKind::Capture => read_data!(reader, header.size, Capture), - PacketKind::ChangeStage => read_data!(reader, header.size, ChangeStage), - PacketKind::Command => PacketData::Command(Command), - PacketKind::UdpInit => read_data!(reader, header.size, UdpInit), - PacketKind::HolePunch => PacketData::HolePunch(HolePunch), - }; - - Ok(Packet { - user_id: header.user_id, - data, - }) - } - - pub async fn write_packet(writer: &mut BufWriter, id: u128, data: PacketData) -> anyhow::Result<()> { - let (kind, slice) = match &data { - PacketData::Unknown(vec) => { - if vec.len() >= (u16::MAX as usize) { - bail!("unknown packet vec too large") - } - (PacketKind::Unknown, vec.as_slice()) - } - PacketData::Init(init) => (PacketKind::Init, init.as_bytes()), - PacketData::Player(player) => (PacketKind::Player, player.as_bytes()), - PacketData::Cap(cap) => (PacketKind::Cap, cap.as_bytes()), - PacketData::Game(game) => (PacketKind::Game, game.as_bytes()), - PacketData::Tag(tag) => (PacketKind::Tag, tag.as_bytes()), - PacketData::Connect(connect) => (PacketKind::Connect, connect.as_bytes()), - PacketData::Disconnect(..) => (PacketKind::Disconnect, [].as_slice()), - PacketData::Costume(costume) => (PacketKind::Costume, costume.as_bytes()), - PacketData::Shine(shine) => (PacketKind::Shine, shine.as_bytes()), - PacketData::Capture(capture) => (PacketKind::Capture, capture.as_bytes()), - PacketData::ChangeStage(change_stage) => (PacketKind::ChangeStage, change_stage.as_bytes()), - PacketData::Command(..) => (PacketKind::Command, [].as_slice()), - PacketData::UdpInit(udp_init) => (PacketKind::UdpInit, udp_init.as_bytes()), - PacketData::HolePunch(..) => (PacketKind::HolePunch, [].as_slice()), - }; - - writer - .write_all( - PacketHeader { - kind, - size: slice.len() as u16, - user_id: id, - } - .as_bytes(), - ) - .await - .context("writing header")?; - writer.write_all(slice).await.context("writing data")?; - writer.flush().await.context("flushing writer") - } - - pub fn new_connection(stream: TcpStream, addr: SocketAddr) { + pub fn new_connection(stream: TcpStream, addr: SocketAddr, socket: Arc, manager: Address) { tokio::spawn(async move { info!("accepted connection from {addr}"); let (reader, writer) = stream.into_split(); let mut reader = BufReader::new(reader); let mut writer = BufWriter::new(writer); - let packet = Self::read_packet(&mut reader).await.unwrap(); + let packet = read_packet(&mut reader, false).await.unwrap(); let Packet { user_id, data: PacketData::Connect(connect), + .. } = packet else { tracing::error!("not a valid player!"); return; }; - let bot_id = user_id + 1; - Self::write_packet(&mut writer, user_id, PacketData::Init(Init { max_players: 8 })) - .await - .expect("msfrarausfhsdagsdgkog"); - Self::write_packet(&mut writer, bot_id, PacketData::Connect(Connect { kind: crate::packet::ConnectionKind::New, client_name: String::try_from("Bot").unwrap(), max_player: 8 })) + write_packet(&mut writer, user_id, PacketData::Init(Init { max_players: 8 })) .await .expect("msfrarausfhsdagsdgkog"); - let span = info_span!("", player = connect.client_name.to_string()); + let span = info_span!("Client", player = connect.client_name.to_string()); + let (address, mailbox) = Mailbox::bounded(512); let (sender, mut receiver) = mpsc::unbounded_channel(); - tokio::spawn(async move { - while let Some((instant, packet)) = receiver.recv().await { - tokio::time::sleep_until(instant).await; - Self::write_packet(&mut writer, bot_id, packet).await.unwrap(); - } - }.instrument(span.clone())); - - async move { - info!("connected {user_id}"); + tokio::spawn(scoped(&address.downgrade(), { + let address = address.downgrade(); + async move { + let ip = addr.ip(); + let mut addr = None; + while let Some(message) = receiver.recv().await { + match message { + WriteMessage::Data(Packet { user_id, udp, data }) => { + // trace!("writing packet {udp:?}, {data:?}"); + let res = if udp { + async { + let Some(addr) = addr else { + trace!("no address set yet"); + return Ok(()); + }; + // trace!("sending udp packet: {data:?}"); - loop { - let packet = Self::read_packet(&mut reader).await.unwrap(); - trace!("got packet {packet:?}"); - let sender = sender.clone(); - tokio::spawn(async move { - let _ = sender.send((Instant::now().checked_add(Duration::from_millis(200)).unwrap(), match packet.data { - PacketData::Player(player) => PacketData::Player(Player {position: [player.position[0], -20., player.position[2]], ..player}), - PacketData::Cap(cap) => PacketData::Cap(Cap {position: [cap.position[0], -20., cap.position[2]], ..cap}), - pass => pass, - })); - }); + let mut buf = [0; 256]; + let mut writer = Cursor::new(buf.as_mut_slice()); + write_packet(&mut writer, user_id, data).await?; + + socket.send_to(&buf, &addr).await.expect("kys"); + + Ok(()) + } + .await + } else { + write_packet(&mut writer, user_id, data).await + }; + + if let Err(error) = res { + error!("error while writing packet: {error:?}"); + let _ = address.send(StopError).detach().await; + return; + } + } + WriteMessage::SetUdp(port) => { + trace!("set udp port, connected on udp!"); + addr = Some(SocketAddr::new(ip, port)) + } + } + } } - } + .instrument(span.clone()) + })); + tokio::spawn(scoped( + &address.downgrade(), + { + let address = address.downgrade(); + async move { + info!("connected {user_id}"); + + loop { + match read_packet(&mut reader, false).await { + Ok(packet) => { + let _ = address.send(packet).detach().await; + } + Err(error) => { + error!("error while reading packet: {error:?}"); + let _ = address.send(StopError).detach().await; + break; + } + } + } + } + } + .instrument(span.clone()), + )); + clients().write().await.insert(user_id, (MessageChannel::new(address), addr)); + xtra::run( + mailbox, + PlayerActor { + id: user_id, + connection_kind: connect.kind, + name: connect.client_name, + write_sender: sender, + manager, + }, + ) .instrument(span) .await; }); } } + +impl Actor for PlayerActor { + type Stop = (); + + async fn started(&mut self, _: &Mailbox) -> Result<(), Self::Stop> { + broadcast_packet(Packet { + user_id: self.id, + udp: false, + data: PacketData::Connect(Connect { + kind: self.connection_kind, + max_player: 8, + client_name: self.name, + }), + }) + .await; + self + .write_sender + .send(WriteMessage::Data(Packet { + user_id: 0, + udp: false, + data: PacketData::UdpInit(UdpInit { port: 1027 }), + })) + .map_err(drop)?; + + self + .manager + .send(PlayerConnected { + id: self.id, + name: self.name, + }) + .await + .unwrap(); + Ok(()) + } + async fn stopped(self) -> Self::Stop {} +} +struct StopError; +impl Handler for PlayerActor { + type Return = (); + + async fn handle(&mut self, _: StopError, ctx: &mut xtra::Context) -> Self::Return { + ctx.stop_all(); + } +} + +impl Handler for PlayerActor { + type Return = (); + + async fn handle(&mut self, packet: Packet, _: &mut xtra::Context) { + if matches!(packet.data, PacketData::HolePunch(..)) { + trace!("hole puncher"); + return; + } + + if packet.user_id == self.id { + match packet.data { + PacketData::UdpInit(UdpInit { port }) => { + trace!("hole puncher"); + let _ = self.write_sender.send(WriteMessage::SetUdp(port)); + let _ = self.write_sender.send(WriteMessage::Data(Packet { + user_id: 0, + udp: true, + data: PacketData::HolePunch(HolePunch), + })); + return; + } + PacketData::Connect(..) | PacketData::Init(..) => { + trace!("suspicious packet sent: {packet:?}"); + return; + } + PacketData::Player(ref player) => { + let _ = self.manager.send(PlayerMoved { id: self.id, position: Vec3::from_array(player.position)}).detach().await.unwrap(); + } + PacketData::Game(ref game) => { + let _ = self.manager.send(ChangedStage { id: self.id, stage: game.stage}).detach().await.unwrap(); + } + + _ => {} + } + + broadcast_packet(packet).await; + } else { + let _ = self.write_sender.send(WriteMessage::Data(packet)); + } + } +}