diff --git a/Cargo.lock b/Cargo.lock index 66d25f5..7b153ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -17,35 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "allocator-api2" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" -[[package]] -name = "async-trait" -version = "0.1.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - [[package]] name = "atoi" version = "2.0.0" @@ -63,14 +40,14 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" -version = "0.7.7" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" dependencies = [ - "async-trait", "axum-core", "base64", "bytes", + "form_urlencoded", "futures-util", "http", "http-body", @@ -89,10 +66,10 @@ dependencies = [ "serde_path_to_error", "serde_urlencoded", "sha1", - "sync_wrapper 1.0.1", + "sync_wrapper", "tokio", "tokio-tungstenite", - "tower 0.5.1", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", @@ -100,20 +77,19 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.5" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" dependencies = [ - "async-trait", "bytes", - "futures-util", + "futures-core", "http", "http-body", "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.1", + "sync_wrapper", "tower-layer", "tower-service", "tracing", @@ -178,9 +154,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" @@ -333,7 +309,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", ] [[package]] @@ -357,16 +333,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "etcetera" version = "0.8.0" @@ -389,12 +355,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - [[package]] name = "flume" version = "0.11.0" @@ -412,6 +372,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -433,9 +399,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" @@ -461,38 +427,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-io", @@ -523,7 +489,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -537,18 +515,25 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" dependencies = [ - "ahash", "allocator-api2", + "equivalent", + "foldhash", ] [[package]] name = "hashlink" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown", + "hashbrown 0.15.4", ] [[package]] @@ -557,12 +542,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - [[package]] name = "hex" version = "0.4.3" @@ -793,7 +772,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", ] [[package]] @@ -821,7 +800,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -841,9 +820,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.173" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb" [[package]] name = "libm" @@ -862,12 +841,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - [[package]] name = "litemap" version = "0.7.3" @@ -876,9 +849,9 @@ checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -892,9 +865,9 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "matchit" -version = "0.7.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "md-5" @@ -918,12 +891,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[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.7.4" @@ -935,23 +902,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.59.0", ] [[package]] @@ -966,7 +923,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand", + "rand 0.8.5", "smallvec", "zeroize", ] @@ -1001,16 +958,6 @@ dependencies = [ "libm", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "object" version = "0.36.1" @@ -1033,7 +980,6 @@ dependencies = [ "axum", "base64", "futures-util", - "parking_lot", "serde", "serde_json", "sqlx", @@ -1049,9 +995,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -1059,23 +1005,17 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", "redox_syscall 0.5.1", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -1108,7 +1048,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", ] [[package]] @@ -1174,6 +1114,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -1181,8 +1127,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -1192,7 +1148,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -1201,7 +1167,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", ] [[package]] @@ -1235,7 +1210,7 @@ dependencies = [ "num-traits", "pkcs1", "pkcs8", - "rand_core", + "rand_core 0.6.4", "signature", "spki", "subtle", @@ -1248,19 +1223,6 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - [[package]] name = "rustversion" version = "1.0.17" @@ -1296,7 +1258,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", ] [[package]] @@ -1376,7 +1338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -1426,21 +1388,11 @@ dependencies = [ "der", ] -[[package]] -name = "sqlformat" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" -dependencies = [ - "nom", - "unicode_categories", -] - [[package]] name = "sqlx" -version = "0.8.2" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" dependencies = [ "sqlx-core", "sqlx-macros", @@ -1451,36 +1403,31 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.8.2" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ - "atoi", - "byteorder", + "base64", "bytes", "crc", "crossbeam-queue", "either", "event-listener", - "futures-channel", "futures-core", "futures-intrusive", "futures-io", "futures-util", - "hashbrown", + "hashbrown 0.15.4", "hashlink", - "hex", "indexmap", "log", "memchr", "once_cell", - "paste", "percent-encoding", "serde", "serde_json", "sha2", "smallvec", - "sqlformat", "thiserror", "tokio", "tokio-stream", @@ -1490,22 +1437,22 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.8.2" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" dependencies = [ "proc-macro2", "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.68", + "syn 2.0.87", ] [[package]] name = "sqlx-macros-core" -version = "0.8.2" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" dependencies = [ "dotenvy", "either", @@ -1521,17 +1468,16 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.68", - "tempfile", + "syn 2.0.87", "tokio", "url", ] [[package]] name = "sqlx-mysql" -version = "0.8.2" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a" +checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", "base64", @@ -1556,7 +1502,7 @@ dependencies = [ "memchr", "once_cell", "percent-encoding", - "rand", + "rand 0.8.5", "rsa", "serde", "sha1", @@ -1571,9 +1517,9 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.8.2" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8" +checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", "base64", @@ -1584,7 +1530,6 @@ dependencies = [ "etcetera", "futures-channel", "futures-core", - "futures-io", "futures-util", "hex", "hkdf", @@ -1595,7 +1540,7 @@ dependencies = [ "md-5", "memchr", "once_cell", - "rand", + "rand 0.8.5", "serde", "serde_json", "sha2", @@ -1609,9 +1554,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.8.2" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" dependencies = [ "atoi", "flume", @@ -1626,6 +1571,7 @@ dependencies = [ "serde", "serde_urlencoded", "sqlx-core", + "thiserror", "tracing", "url", ] @@ -1672,21 +1618,15 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.68" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "sync_wrapper" version = "1.0.1" @@ -1701,7 +1641,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", ] [[package]] @@ -1714,36 +1654,24 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", -] - [[package]] name = "thiserror" -version = "1.0.61" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", ] [[package]] @@ -1773,32 +1701,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", ] [[package]] @@ -1814,9 +1741,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.24.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" dependencies = [ "futures-util", "log", @@ -1841,14 +1768,14 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper 0.1.2", + "sync_wrapper", "tokio", "tower-layer", "tower-service", @@ -1887,7 +1814,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", ] [[package]] @@ -1901,17 +1828,16 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.24.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" dependencies = [ - "byteorder", "bytes", "data-encoding", "http", "httparse", "log", - "rand", + "rand 0.9.1", "sha1", "thiserror", "utf-8", @@ -1950,12 +1876,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - [[package]] name = "url" version = "2.5.1" @@ -2003,6 +1923,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasite" version = "0.1.0" @@ -2034,7 +1963,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -2054,18 +1992,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2076,9 +2014,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -2088,9 +2026,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -2100,15 +2038,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -2118,9 +2056,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -2130,9 +2068,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -2142,9 +2080,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -2154,9 +2092,18 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.6.0", +] [[package]] name = "write16" @@ -2190,30 +2137,10 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", "synstructure", ] -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "zerocopy-derive", -] - -[[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.68", -] - [[package]] name = "zerofrom" version = "0.1.4" @@ -2231,7 +2158,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", "synstructure", ] @@ -2260,5 +2187,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn 2.0.87", ] diff --git a/Cargo.toml b/Cargo.toml index feb4a0a..d6b1b0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,14 @@ [package] name = "open_tavern" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] -axum = { version = "0.7.7", features = ["ws"] } +axum = { version = "0.8.4", features = ["ws"] } serde = "1.*.*" serde_json = "1.*.*" tokio = { version = "1.*.*", features = ["full"] } -sqlx = { version = "0.8.2", features = ["runtime-tokio", "sqlite"] } +sqlx = { version = "0.8.6", features = ["runtime-tokio", "sqlite"] } tavern_macros = { version = "0.1.0", path = "tavern_macros" } -parking_lot = "0.12.3" -futures-util = "0.3.30" +futures-util = "0.3.31" base64 = "0.22.1" diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..dc04857 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,2 @@ +binop_separator = "Back" +max_width = 120 diff --git a/src/lib.rs b/src/lib.rs index a9ecffa..fe3363f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,11 @@ use std::collections::HashMap; use api::game_actions::SpawnToken; -use game::{chat_message::ChatMessage, entry::{ActionDefinition, DiceRoll}, Game, GameImpl}; +use game::{ + Game, GameImpl, + chat_message::ChatMessage, + entry::{ActionDefinition, DiceRoll}, +}; use serde::{Deserialize, Serialize}; use tokio::sync::{broadcast, mpsc}; @@ -14,35 +18,39 @@ pub mod user; pub struct GameServer { game: Game, chat: Vec<(String, ChatMessage)>, - #[serde(skip)] // we dont want to save the logged users as it will always be empty when the server restarts + // we dont want to save the logged users as it will always be empty when the server restarts + #[serde(skip)] + /// Logged in users, bool value used to know if the user is an admin or not users: HashMap, - // TODO: JEESH REPLACE THIS WITH A DATABASE AND PROPER SECURITY ONCE ITS DONE PLEASE GOD + // TODO: JEESH REPLACE THIS WITH A DATABASE AND PROPER SECURITY ONCE ITS DONE PLEASE GOD creds: HashMap, } impl GameServer { pub fn new() -> Self { let mut creds = HashMap::new(); - creds.insert("rusty".to_string(), String::new()); - creds.insert("artist".to_string(), "artist".to_string()); - creds.insert("dragonfly".to_string(), "cool".to_string()); + creds.insert("rusty".to_string(), "rusty".to_string()); + creds.insert("test".to_string(), "test".to_string()); + creds.insert("dragonfly".to_string(), "dragonfly".to_string()); Self { game: Game::new(), - chat: vec![ - ( - "Server".to_string(), - ChatMessage::new("a weapon description".to_string()) - .id(1) - .character(Some("Sword or something".to_string())) - .with_action( - ActionDefinition::new("weapon/attack".to_string()) + chat: vec![( + "Server".to_string(), + ChatMessage::new("a weapon description".to_string()) + .id(1) + .character(Some("Sword or something".to_string())) + .with_action( + ActionDefinition::new("weapon/attack".to_string()) .display_name(Some("Attack +7".to_string())) .with_roll(DiceRoll::new("Pierce".to_string(), 12, 1).constant(1)) - .with_roll(DiceRoll::new("Fire".to_string(), 4, 2)) - ) - .with_action(ActionDefinition::new("Attack +3".to_string()).with_roll(DiceRoll::new("Base".to_string(), 20, 1))) - .with_action(ActionDefinition::new("Attack -1".to_string())) - ) - ], + .with_roll(DiceRoll::new("Fire".to_string(), 4, 2)), + ) + .with_action(ActionDefinition::new("Attack +3".to_string()).with_roll(DiceRoll::new( + "Base".to_string(), + 20, + 1, + ))) + .with_action(ActionDefinition::new("Attack -1".to_string())), + )], users: HashMap::new(), creds, } @@ -63,20 +71,34 @@ impl GameServer { api::Request::Error => {} api::Request::Login(login) => { println!("login req from {}: {:?}", &id, &login); - if !self.users.contains_key(&login.username) && self.creds.get(&login.username).map(|p| p == &login.password).unwrap_or(false) { + if !self.users.contains_key(&login.username) && + self.creds + .get(&login.username) + .map(|p| p == &login.password) + .unwrap_or(false) + { self.users.insert(login.username.clone(), login.username == "rusty"); // rusty will be admin for now :) - _ = broadcast.send((Some(id), api::Response::Login(api::login::LoginResult { success: true, username: login.username }))); - } - else { - _ = broadcast.send((Some(id.clone()), api::Response::Login(api::login::LoginResult { success: false, username: login.username }))); + _ = broadcast.send(( + Some(id), + api::Response::Login(api::login::LoginResult { + success: true, + username: login.username, + }), + )); + } else { + _ = broadcast.send(( + Some(id.clone()), + api::Response::Login(api::login::LoginResult { + success: false, + username: login.username, + }), + )); } } api::Request::Message(mut msg) => { if msg.id == 0 || msg.id > self.chat.len() { msg.id = self.chat.len() + 1; // set the message id, 0 is invalid - } - // TODO: check if the editor is an admin as well - else if id == self.chat[msg.id - 1].0 { + } else if id == self.chat[msg.id - 1].0 || *self.users.get(&id).unwrap_or(&false) { self.chat[msg.id - 1] = (id.clone(), msg.clone()); } else { // if its an edit message and editor is not the owner, skip @@ -116,46 +138,65 @@ impl GameServer { } else { self.chat.len() - amount }; - let history: Vec = - self.chat.iter().skip(start).map(|m| m.1.clone()).collect(); + let history: Vec = self.chat.iter().skip(start).map(|m| m.1.clone()).collect(); _ = broadcast.send((Some(id), api::Response::GetChatHistory(history))); - }, + } api::Request::GetTokens { scene } => { for token_id in self.game.available_tokens(scene) { if let Some(ti) = self.game.token_info(0, token_id) { let bits = std::fs::read(&ti.img_source).expect("FAILED READING TOKEN IMAGE"); let img = base64::Engine::encode(&base64::prelude::BASE64_STANDARD, &bits); - _ = broadcast.send((Some(id.clone()), api::Response::SpawnToken(SpawnToken { token_id: token_id, x: ti.x, y: ti.y, img }))); + _ = broadcast.send(( + Some(id.clone()), + api::Response::SpawnToken(SpawnToken { + token_id: token_id, + x: ti.x, + y: ti.y, + img, + }), + )); } } - }, - api::Request::SpawnToken { map_id, character, x, y, img_path } => { + } + api::Request::SpawnToken { + map_id, + character, + x, + y, + img_path, + } => { let token_id = self.game.create_token(map_id, character, img_path.clone(), x, y); let bits = std::fs::read(&img_path).expect("FAILED READING TOKEN IMAGE"); let img = base64::Engine::encode(&base64::prelude::BASE64_STANDARD, &bits); - _ = broadcast.send((Some(id.clone()), api::Response::SpawnToken(SpawnToken { token_id, x, y, img }))); - }, + _ = broadcast.send(( + Some(id.clone()), + api::Response::SpawnToken(SpawnToken { token_id, x, y, img }), + )); + } api::Request::MoveToken { token_id, x, y } => { // TODO: add check to make sure the actor is authorized to move the token if self.game.move_token(0, token_id, x, y) { // TODO: maybe chage move_token to return optional x,y values if succeeded to make sure the token is where it was going to be _ = broadcast.send((None, api::Response::MoveToken { token_id, x, y })); } - }, + } api::Request::ActionResult(result) => { let msg = ChatMessage::new( - result.results.iter() + result + .results + .iter() // .map(|d| &d.result_text) - .fold(String::new(), |a,b| a + &format!("{}: {} = {}\n", &b.name, &b.result_text, b.result)) - ) - .character(Some(result.name)) - .source(id.clone()) - .targets(Some(result.targets)) - .id(self.chat.len() + 1); + .fold(String::new(), |a, b| { + a + &format!("{}: {} = {}\n", &b.name, &b.result_text, b.result) + }), + ) + .character(Some(result.name)) + .source(id.clone()) + .targets(Some(result.targets)) + .id(self.chat.len() + 1); self.chat.push((id, msg.clone())); _ = broadcast.send((None, api::Response::Message(msg))); - - }, + } api::Request::CreateCharacter => { // check if user is admin if self.users.get(&id).map(|a| *a).unwrap_or(false) { @@ -163,13 +204,13 @@ impl GameServer { // return the new id with the character i think _ = broadcast.send((Some(id), api::Response::CharacterCreated(new_id))); } - }, + } api::Request::Quit => { if self.users.contains_key(&id) { self.users.remove(&id); } _ = broadcast.send((None, api::Response::Quit { id })); - }, + } api::Request::Kick(id) => { if self.users.contains_key(&id) { self.users.remove(&id); diff --git a/src/main.rs b/src/main.rs index d1cb901..d5f3ed5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,150 +1,192 @@ use axum::{ - extract::ws::{self,Message}, response, routing, Router + Router, + extract::ws::{self, Message}, + response, routing, +}; +use futures_util::{ + SinkExt, StreamExt, + stream::{SplitSink, SplitStream}, }; -use futures_util::{stream::{SplitSink, SplitStream}, SinkExt, StreamExt}; use open_tavern::api::{Request, RequestError, Response}; use tokio::sync::{broadcast, mpsc}; #[tokio::main] async fn main() { - let (bsend, _) = broadcast::channel(10); - let (msend, mrecv) = mpsc::channel(50); - let bsend2 = bsend.clone(); - let app = Router::new() - .route("/", routing::get(root)) - .route("/tavern.js", routing::get(socket)) - .route("/app.js", routing::get(app_js)) - .route("/style.css", routing::get(style)) - .route("/ws", routing::get(move |w| ws_handler(w, msend, bsend2.clone().subscribe()))); + let (bsend, _) = broadcast::channel(10); + let (msend, mrecv) = mpsc::channel(50); + let bsend2 = bsend.clone(); + let app = Router::new() + .route("/", routing::get(root)) + .route("/tavern.js", routing::get(socket)) + .route("/app.js", routing::get(app_js)) + .route("/style.css", routing::get(style)) + .route( + "/ws", + routing::get(move |w| ws_handler(w, msend, bsend2.clone().subscribe())), + ); - let listener = tokio::net::TcpListener::bind("0.0.0.0:3001").await.unwrap(); - let game = open_tavern::GameServer::new(); - tokio::spawn(game.server_loop(mrecv, bsend)); + let listener = tokio::net::TcpListener::bind("0.0.0.0:3001").await.unwrap(); + let game = open_tavern::GameServer::new(); + tokio::spawn(game.server_loop(mrecv, bsend)); - axum::serve(listener, app).await.expect("axum server crashed, yaaaaay (unless i crashed him that yay)"); + axum::serve(listener, app) + .await + .expect("axum server crashed, yaaaaay (unless i crashed him that yay)"); } -async fn ws_handler(ws: ws::WebSocketUpgrade, msend: mpsc::Sender<(String, Request)>, brecv: broadcast::Receiver<(Option, Response)>) -> impl axum::response::IntoResponse { - ws.on_upgrade(|w| handle_socket(w, msend, brecv)) +/// Executes on a new WebSocket request, set update to [handle_socket] +async fn ws_handler( + ws: ws::WebSocketUpgrade, + msend: mpsc::Sender<(String, Request)>, + brecv: broadcast::Receiver<(Option, Response)>, +) -> impl axum::response::IntoResponse { + ws.on_upgrade(|w| handle_socket(w, msend, brecv)) } +/// Receiver of a websocket after [handle_socket] handle the login async fn socket_receiver(mut recv: SplitStream, msend: mpsc::Sender<(String, Request)>, id: String) { - while let Some(msg) = recv.next().await { - if let Ok(msg) = msg { - match msg { - Message::Text(t) => { - println!("Got message from {}: {}", &id, &t); - let req = serde_json::from_str::(&t).unwrap_or_default(); - let erred = msend.send((id.clone(), req)).await.is_err(); - if erred { - break; - } - } - ws::Message::Binary(_) => todo!(), - ws::Message::Ping(_) => todo!(), - ws::Message::Pong(_) => todo!(), - ws::Message::Close(_) => { - // dont care if we fail the send as we are quitting regardless - _ = msend.send((id.clone(), open_tavern::api::Request::Quit)).await; - break; - }, - } - } - } + while let Some(msg) = recv.next().await { + if let Ok(msg) = msg { + match msg { + Message::Text(t) => { + println!("Got message from {}: {}", &id, &t); + let req = serde_json::from_str::(&t).unwrap_or_default(); + let erred = msend.send((id.clone(), req)).await.is_err(); + if erred { + break; + } + } + ws::Message::Binary(_) => todo!(), + ws::Message::Ping(_) => todo!(), + ws::Message::Pong(_) => todo!(), + ws::Message::Close(_) => { + // dont care if we fail the send as we are quitting regardless + _ = msend.send((id.clone(), open_tavern::api::Request::Quit)).await; + break; + } + } + } + } } - -async fn socket_sender(id: String, mut send: SplitSink, mut brecv: broadcast::Receiver<(Option, Response)>) { - while let Ok((to_id, msg)) = brecv.recv().await { - if to_id.is_none() || to_id.map(|t| t == id).unwrap_or(false) { - println!("Sending a message to {}: {:?}", &id, &msg); - let err = send.send(ws::Message::Text(serde_json::to_string(&msg).unwrap())).await.is_err(); - if err || matches!(msg, Response::Shutdown) { - _ = send.close().await; - break; - } - } - } +/// Sender of a websocket after [handle_socket] handles the login +async fn socket_sender( + id: String, + mut send: SplitSink, + mut brecv: broadcast::Receiver<(Option, Response)>, +) { + while let Ok((to_id, msg)) = brecv.recv().await { + if to_id.is_none() || to_id.map(|t| t == id).unwrap_or(false) { + println!("Sending a message to {}: {:?}", &id, &msg); + let err = send + .send(ws::Message::Text(serde_json::to_string(&msg).unwrap().into())) + .await + .is_err(); + if err || matches!(msg, Response::Shutdown) { + _ = send.close().await; + break; + } + } + } } - -async fn handle_socket(mut socket: ws::WebSocket, msend: mpsc::Sender<(String, Request)>, mut brecv: broadcast::Receiver<(Option, Response)>) { - let mut id: Option = None; - // this is a temp id, and as long as 2 people dont try to connect to the socket at the same milisecond and to the same user it would be fine (i hope) - let temp_id = format!("temp_id_{}", std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH).map(|t| t.as_micros()).unwrap_or(0)); - let mut last_login_req = std::time::Instant::now(); - loop { - tokio::select! { - b = brecv.recv() => { - println!("{} trying to log in: {:?}", &temp_id, &b); - if let Ok((to_id, msg)) = b { - if let Response::Login(open_tavern::api::login::LoginResult { success, username }) = msg.clone() { - let to_id = to_id.map(|ti| ti == temp_id).unwrap_or(false); - if to_id && success && id.as_ref().map(|id| id == &username).unwrap_or(false) { - _ = socket.send(Message::Text(serde_json::to_string(&msg).unwrap_or_default())).await; - break; - } - else { - id = None; - _ = socket.send(Message::Text(serde_json::to_string(&msg).unwrap_or_default())).await; - } - } - } - }, - msg = socket.recv() => { - if let Some(msg) = msg.map(|m| m.ok()).flatten() { - match msg { - Message::Text(t) => { - let req = serde_json::from_str::(&t).unwrap_or_default(); - println!("{} trying to log in incoming: {:?}", &temp_id, t); - match req { - // TODO: Actual signing in mechanism with multiple ids :) - Request::Login(r) => { - // allow 1 login attempt every 3 seconds - if last_login_req.elapsed() > std::time::Duration::from_secs(1) { - last_login_req = std::time::Instant::now(); - id = Some(r.username.clone()); - _ = msend.send((temp_id.clone(), Request::Login(r))).await; - } - else { - println!("Failed too early"); - } - }, - _ => { - _ = socket.send(Message::Text(serde_json::to_string(&Response::Error(RequestError::InvalidRequest)).unwrap())).await; - }, - } - } - ws::Message::Close(_) => { - id = None; - break; - }, - _ => {}, - }; - } - } - }; - } - if let Some(id) = id { - // maybe i should not spawn 2 different routines and just have 1 routine that uses tokio::select! - println!("Got id for socket: {}", &id); - let (send, recv) = socket.split(); - tokio::spawn(socket_receiver(recv, msend, id.clone())); - tokio::spawn(socket_sender(id, send, brecv)); - } - println!("Done with so-cat"); +/// Socket login handler, upon a websocket upgrade it will check for login requests until a login +/// request succeeds, then launch [socket_sender] and [socket_receiver] to handle the actual gameplay part +async fn handle_socket( + mut socket: ws::WebSocket, + msend: mpsc::Sender<(String, Request)>, + mut brecv: broadcast::Receiver<(Option, Response)>, +) { + let mut id: Option = None; + // this is a temp id, and as long as 2 people dont try to connect to the socket at the same milisecond and to the same user it would be fine (i hope) + let temp_id = format!( + "temp_id_{}", + std::time::SystemTime::now() + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .map(|t| t.as_micros()) + .unwrap_or(0) + ); + let mut last_login_req = std::time::Instant::now(); + loop { + tokio::select! { + b = brecv.recv() => { + println!("{} trying to log in: {:?}", &temp_id, &b); + if let Ok((to_id, msg)) = b { + if let Response::Login(open_tavern::api::login::LoginResult { success, username }) = msg.clone() { + let to_id = to_id.map(|ti| ti == temp_id).unwrap_or(false); + if to_id && success && id.as_ref().map(|id| id == &username).unwrap_or(false) { + _ = socket.send(Message::Text(serde_json::to_string(&msg).unwrap_or_default().into())).await; + break; + } + else { + id = None; + _ = socket.send(Message::Text(serde_json::to_string(&msg).unwrap_or_default().into())).await; + } + } + } + }, + msg = socket.recv() => { + if let Some(msg) = msg.map(|m| m.ok()).flatten() { + match msg { + Message::Text(t) => { + let req = serde_json::from_str::(&t).unwrap_or_default(); + println!("{} trying to log in incoming: {:?}", &temp_id, t); + match req { + // TODO: Actual signing in mechanism with multiple ids :) + Request::Login(r) => { + // allow 1 login attempt every 3 seconds + if last_login_req.elapsed() > std::time::Duration::from_secs(1) { + last_login_req = std::time::Instant::now(); + id = Some(r.username.clone()); + _ = msend.send((temp_id.clone(), Request::Login(r))).await; + } + else { + println!("Failed too early"); + } + }, + _ => { + _ = socket.send(Message::Text(serde_json::to_string(&Response::Error(RequestError::InvalidRequest)).unwrap().into())).await; + }, + } + } + ws::Message::Close(_) => { + id = None; + break; + }, + _ => {}, + }; + } + } + }; + } + if let Some(id) = id { + // maybe i should not spawn 2 different routines and just have 1 routine that uses tokio::select! + println!("Got id for socket: {}", &id); + let (send, recv) = socket.split(); + tokio::spawn(socket_receiver(recv, msend, id.clone())); + tokio::spawn(socket_sender(id, send, brecv)); + } + println!("Done with so-cat"); } async fn root() -> axum::response::Html<&'static str> { - response::Html(include_str!("../assets/web/index.html")) + response::Html(include_str!("../assets/web/index.html")) } - async fn socket() -> impl response::IntoResponse { - ([(axum::http::header::CONTENT_TYPE, "text/javascript")], include_str!("../assets/web/tavern.js")) + ( + [(axum::http::header::CONTENT_TYPE, "text/javascript")], + include_str!("../assets/web/tavern.js"), + ) } async fn app_js() -> impl response::IntoResponse { - ([(axum::http::header::CONTENT_TYPE, "text/javascript")], include_str!("../assets/web/app.js")) + ( + [(axum::http::header::CONTENT_TYPE, "text/javascript")], + include_str!("../assets/web/app.js"), + ) } async fn style() -> impl response::IntoResponse { - ([(axum::http::header::CONTENT_TYPE, "text/css")], include_str!("../assets/web/style.css")) -} \ No newline at end of file + ( + [(axum::http::header::CONTENT_TYPE, "text/css")], + include_str!("../assets/web/style.css"), + ) +}