generated from tipragot/rust
Co-authored-by: CoCoSol <CoCoSol007@users.noreply.github.com>
This commit is contained in:
parent
95c1890a1e
commit
d15bb20183
320
Cargo.lock
generated
320
Cargo.lock
generated
|
@ -18,29 +18,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
name = "ascon"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
checksum = "9fe9a0cff241855e9166670d259192aacf1e9a81b865dc9905afbbab31a9d2c1"
|
||||
|
||||
[[package]]
|
||||
name = "ascon-hash"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d629b6e580029d416158998cf0ae2d355d68cde3ed25715549533b0de9fd90b6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"const-random",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
"ascon",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.79"
|
||||
version = "0.1.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681"
|
||||
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -55,9 +52,9 @@ checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba"
|
|||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
|
@ -119,9 +116,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.69"
|
||||
version = "0.3.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
|
||||
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
|
@ -147,12 +144,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
|
@ -170,18 +161,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.5.0"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -189,26 +177,6 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "const-random"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
|
||||
dependencies = [
|
||||
"const-random-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-random-macro"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.12"
|
||||
|
@ -218,12 +186,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
|
@ -234,19 +196,6 @@ dependencies = [
|
|||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.5.0"
|
||||
|
@ -263,18 +212,6 @@ dependencies = [
|
|||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flurry"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7874ce5eeafa5e546227f7c62911e586387bf03d6c9a45ac78aa1c3bc2fedb61"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"num_cpus",
|
||||
"parking_lot",
|
||||
"seize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
@ -406,12 +343,6 @@ version = "0.28.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
|
@ -466,9 +397,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
|||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "1.2.0"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a"
|
||||
checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
|
@ -511,9 +442,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.10"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
|
@ -527,16 +458,6 @@ version = "0.2.153"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
|
@ -551,9 +472,9 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.1"
|
||||
version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
|
@ -572,9 +493,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.10"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
|
@ -606,29 +527,6 @@ version = "1.19.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
|
@ -657,9 +555,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
|
@ -721,15 +619,6 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
|
@ -744,31 +633,9 @@ checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47"
|
|||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.16"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||
|
||||
[[package]]
|
||||
name = "scc"
|
||||
version = "2.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4c10d60d2fd9faf0e8b6540623f5e502343bde2ac585a7d158b3db24d93fcbe"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "seize"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e5739de653b129b0a59da381599cf17caf24bc586f6a797c52d3d6147c5b85a"
|
||||
dependencies = [
|
||||
"num_cpus",
|
||||
"once_cell",
|
||||
]
|
||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
|
@ -792,9 +659,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.113"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
|
||||
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -827,18 +694,13 @@ dependencies = [
|
|||
name = "server"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ascon-hash",
|
||||
"axum",
|
||||
"bincode",
|
||||
"dashmap",
|
||||
"flurry",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"rand",
|
||||
"scc",
|
||||
"serde",
|
||||
"slotmap",
|
||||
"tokio",
|
||||
"uuid",
|
||||
]
|
||||
|
@ -863,21 +725,11 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slotmap"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.1"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
|
@ -914,33 +766,24 @@ checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.56"
|
||||
version = "1.0.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
|
||||
checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.56"
|
||||
version = "1.0.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
|
||||
checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-keccak"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
||||
dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
|
@ -1083,9 +926,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.22"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
@ -1145,7 +988,7 @@ version = "0.52.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.0",
|
||||
"windows-targets 0.52.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1165,17 +1008,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.0"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.0",
|
||||
"windows_aarch64_msvc 0.52.0",
|
||||
"windows_i686_gnu 0.52.0",
|
||||
"windows_i686_msvc 0.52.0",
|
||||
"windows_x86_64_gnu 0.52.0",
|
||||
"windows_x86_64_gnullvm 0.52.0",
|
||||
"windows_x86_64_msvc 0.52.0",
|
||||
"windows_aarch64_gnullvm 0.52.5",
|
||||
"windows_aarch64_msvc 0.52.5",
|
||||
"windows_i686_gnu 0.52.5",
|
||||
"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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1186,9 +1030,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.0"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
|
@ -1198,9 +1042,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.0"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
|
@ -1210,9 +1054,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
|||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.0"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
|
@ -1222,9 +1072,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
|||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.0"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
|
@ -1234,9 +1084,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.0"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
|
@ -1246,9 +1096,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.0"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
|
@ -1258,26 +1108,6 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
|||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.0"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
|
|
|
@ -7,20 +7,15 @@ description = "The server of Border Wars"
|
|||
repository = "https://git.tipragot.fr/corentin/border-wars.git"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.81"
|
||||
axum = { version = "0.7.5", features = ["ws"] }
|
||||
bincode = "1.3.3"
|
||||
dashmap = "5.5.3"
|
||||
flurry = "0.5.0"
|
||||
futures = "0.3.30"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.21"
|
||||
rand = "0.8.5"
|
||||
scc = "2.0.19"
|
||||
tokio = { version = "1.37.0", features = ["rt-multi-thread"] }
|
||||
uuid = { version = "1.8.0", features = ["serde", "v7"] }
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
slotmap = { version = "1.0.7", features = ["serde"] }
|
||||
tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread"] }
|
||||
uuid = { version = "1.8.0", features = ["v4", "serde", "v7"] }
|
||||
axum = { version = "0.7.5", features = ["ws"] }
|
||||
ascon-hash = "0.2.0"
|
||||
rand = "0.8.5"
|
||||
futures = "0.3.30"
|
||||
bincode = "1.3.3"
|
||||
lazy_static = "1.4.0"
|
||||
|
||||
# [lints]
|
||||
# workspace = true
|
||||
|
|
5
crates/server/save src/lib.rs
Normal file
5
crates/server/save src/lib.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct JoinRequest(pub String, pub Option<Uuid>);
|
13
crates/server/save src/lobby.rs
Normal file
13
crates/server/save src/lobby.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use uuid::Uuid;
|
||||
|
||||
pub struct LobbyManager {
|
||||
connections: HashMap<Uuid, Uuid>,
|
||||
lobbies: HashMap<Uuid, Lobby>,
|
||||
}
|
||||
|
||||
pub struct Lobby {
|
||||
id: Uuid,
|
||||
connections: HashMap<Uuid, Uuid>,
|
||||
}
|
112
crates/server/save src/main.rs
Normal file
112
crates/server/save src/main.rs
Normal file
|
@ -0,0 +1,112 @@
|
|||
use std::collections::hash_map::Entry;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::Infallible;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use ascon_hash::{AsconXof, ExtendableOutput, Update, XofReader};
|
||||
use axum::extract::ws::{Message, WebSocket};
|
||||
use axum::extract::{State, WebSocketUpgrade};
|
||||
use axum::http::HeaderMap;
|
||||
use axum::response::sse::{Event, KeepAlive};
|
||||
use axum::response::{IntoResponse, Sse};
|
||||
use axum::routing::get;
|
||||
use axum::Router;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use server::JoinRequest;
|
||||
use tokio::sync::mpsc::{channel, Sender};
|
||||
use tokio::sync::RwLock;
|
||||
use uuid::Uuid;
|
||||
|
||||
mod lobby;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct GameManager {
|
||||
lobbies: Arc<RwLock<HashMap<Uuid, HashMap<Uuid, Sender<Vec<u8>>>>>>,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let app = Router::new()
|
||||
.route("/ws", get(ws_handler))
|
||||
.with_state(GameManager::default());
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:80").await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn ws_handler(
|
||||
State(manager): State<GameManager>,
|
||||
headers: HeaderMap,
|
||||
ws: WebSocketUpgrade,
|
||||
) -> impl IntoResponse {
|
||||
ws.on_upgrade(|mut socket| async move {
|
||||
// Handle authentication
|
||||
let Some(Ok(message)) = socket.recv().await else {
|
||||
return;
|
||||
};
|
||||
let mut reader = AsconXof::default()
|
||||
.chain(message.into_data())
|
||||
.finalize_xof();
|
||||
let mut hash = [0u8; 16];
|
||||
reader.read(&mut hash);
|
||||
let id = Uuid::from_bytes(hash);
|
||||
|
||||
// Get client request
|
||||
let Some(Ok(message)) = socket.recv().await else {
|
||||
return;
|
||||
};
|
||||
let Ok(JoinRequest(username, lobby_id)) = bincode::deserialize(&message.into_data()) else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Check if the client is in a game, if so, connect him to the game
|
||||
todo!();
|
||||
|
||||
// Check if the client is already in a lobby, if so, refuse the connection
|
||||
let mut lobbies = manager.lobbies.write().await;
|
||||
for lobby in lobbies.values() {
|
||||
if lobby.contains_key(&id) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Find or create the lobby
|
||||
let (lobby_id, lobby) = match lobby_id {
|
||||
Some(id) if id == Uuid::nil() => lobbies
|
||||
.iter_mut()
|
||||
.min_by_key(|(_, lobby)| lobby.len())
|
||||
.map(|(&id, lobby)| (id, lobby))
|
||||
.unwrap_or_else(|| {
|
||||
let id = Uuid::now_v7();
|
||||
(id, lobbies.entry(id).or_default())
|
||||
}),
|
||||
Some(id) => {
|
||||
let Some(lobby) = lobbies.get_mut(&id) else {
|
||||
return;
|
||||
};
|
||||
(id, lobby)
|
||||
}
|
||||
None => {
|
||||
let id = Uuid::now_v7();
|
||||
(id, lobbies.entry(id).or_default())
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize the sending loop
|
||||
let (sender, mut receiver) = channel(1);
|
||||
tokio::spawn(async move {
|
||||
while let Some(message) = receiver.recv().await {
|
||||
socket.send(Message::Binary(message)).await.ok();
|
||||
}
|
||||
});
|
||||
|
||||
// Insert the client in the lobby
|
||||
lobby.insert(id, sender);
|
||||
drop(lobbies);
|
||||
|
||||
// Wait for the client to be ready
|
||||
let Some(Ok(message)) = socket.recv().await else {
|
||||
return;
|
||||
};
|
||||
})
|
||||
}
|
38
crates/server/src save/lib.rs
Normal file
38
crates/server/src save/lib.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum ClientPacket {
|
||||
Disconnect,
|
||||
CreateLobby {
|
||||
username: String,
|
||||
public: bool,
|
||||
},
|
||||
JoinLobby {
|
||||
lobby_id: Option<Uuid>,
|
||||
username: String,
|
||||
},
|
||||
IAmReady,
|
||||
IAmNotReady,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum ServerPacket {
|
||||
Refused(String),
|
||||
LobbyJoined(Uuid),
|
||||
LobbyUpdated(Lobby),
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Lobby {
|
||||
pub public: bool,
|
||||
pub players: HashMap<Uuid, LobbyPlayer>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct LobbyPlayer {
|
||||
pub username: String,
|
||||
pub ready: bool,
|
||||
}
|
202
crates/server/src save/main.rs
Normal file
202
crates/server/src save/main.rs
Normal file
|
@ -0,0 +1,202 @@
|
|||
use std::borrow::{Borrow, Cow};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use axum::extract::ws::{Message, WebSocket};
|
||||
use axum::extract::WebSocketUpgrade;
|
||||
use axum::routing::get;
|
||||
use axum::Router;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use lazy_static::lazy_static;
|
||||
use log::warn;
|
||||
use server::{ClientPacket, Lobby, LobbyPlayer, ServerPacket};
|
||||
use tokio::sync::mpsc::{channel, Sender};
|
||||
use tokio::sync::RwLock;
|
||||
use uuid::Uuid;
|
||||
|
||||
struct Client {
|
||||
status: ClientStatus,
|
||||
sender: Sender<Vec<u8>>,
|
||||
}
|
||||
|
||||
enum ClientStatus {
|
||||
Unauthenticated,
|
||||
InLobby(Uuid),
|
||||
InGame(Uuid),
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref CLIENTS: RwLock<HashMap<Uuid, Client>> = RwLock::new(HashMap::new());
|
||||
static ref LOBBIES: RwLock<HashMap<Uuid, Lobby>> = RwLock::new(HashMap::new());
|
||||
}
|
||||
|
||||
pub async fn send_message<'a>(client_id: Uuid, message: impl Into<Cow<'a, [u8]>>) {
|
||||
if let Some(client) = CLIENTS.read().await.get(&client_id) {
|
||||
client.sender.send(message.into().into_owned()).await.ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_packet(client_id: Uuid, packet: impl Borrow<ServerPacket>) {
|
||||
let message = match bincode::serialize(packet.borrow()) {
|
||||
Ok(message) => message,
|
||||
Err(error) => {
|
||||
warn!("failed to serialize packet for {}: {}", client_id, error);
|
||||
return;
|
||||
}
|
||||
};
|
||||
send_message(client_id, message).await;
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
get(|ws: WebSocketUpgrade| async { ws.on_upgrade(handle_client) }),
|
||||
);
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:80")
|
||||
.await
|
||||
.expect("failed to bind");
|
||||
axum::serve(listener, app).await.expect("failed to serve");
|
||||
}
|
||||
|
||||
async fn handle_client(socket: WebSocket) {
|
||||
let client_id = Uuid::now_v7();
|
||||
|
||||
let (mut sender, mut receiver) = socket.split();
|
||||
let (send_tx, mut send_rx) = channel(16);
|
||||
tokio::spawn(async move {
|
||||
while let Some(message) = send_rx.recv().await {
|
||||
sender.send(Message::Binary(message)).await?;
|
||||
}
|
||||
Ok::<(), axum::Error>(())
|
||||
});
|
||||
|
||||
CLIENTS.write().await.insert(
|
||||
client_id,
|
||||
Client {
|
||||
status: ClientStatus::Unauthenticated,
|
||||
sender: send_tx,
|
||||
},
|
||||
);
|
||||
|
||||
while let Some(Ok(message)) = receiver.next().await {
|
||||
let Message::Binary(message) = message else {
|
||||
continue;
|
||||
};
|
||||
let Ok(packet) = bincode::deserialize::<ClientPacket>(&message) else {
|
||||
warn!("failed to deserialize packet from {}", client_id);
|
||||
continue;
|
||||
};
|
||||
packet_received(client_id, packet).await;
|
||||
}
|
||||
|
||||
packet_received(client_id, ClientPacket::Disconnect).await;
|
||||
CLIENTS.write().await.remove(&client_id);
|
||||
}
|
||||
|
||||
async fn packet_received(client_id: Uuid, packet: ClientPacket) {
|
||||
let client = &CLIENTS.read().await[&client_id];
|
||||
match client.status {
|
||||
ClientStatus::Unauthenticated => handle_unauthenticated(client_id, packet).await,
|
||||
ClientStatus::InLobby(lobby_id) => handle_in_lobby(client_id, lobby_id, packet).await,
|
||||
ClientStatus::InGame(game_id) => handle_in_game(client_id, game_id, packet).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_unauthenticated(client_id: Uuid, packet: ClientPacket) {
|
||||
match packet {
|
||||
ClientPacket::CreateLobby { username, public } => {
|
||||
let lobby_id = Uuid::now_v7();
|
||||
let lobby = Lobby {
|
||||
public,
|
||||
players: HashMap::from_iter([(
|
||||
client_id,
|
||||
LobbyPlayer {
|
||||
username,
|
||||
ready: false,
|
||||
},
|
||||
)]),
|
||||
};
|
||||
let message = bincode::serialize(&ServerPacket::LobbyUpdated(lobby.clone()))
|
||||
.expect("failed to serialize lobby");
|
||||
let mut lobbies = LOBBIES.write().await;
|
||||
lobbies.insert(lobby_id, lobby);
|
||||
CLIENTS
|
||||
.write()
|
||||
.await
|
||||
.get_mut(&client_id)
|
||||
.expect("client not found")
|
||||
.status = ClientStatus::InLobby(lobby_id);
|
||||
send_packet(client_id, ServerPacket::LobbyJoined(lobby_id)).await;
|
||||
send_message(client_id, message).await;
|
||||
}
|
||||
ClientPacket::JoinLobby { lobby_id, username } => {
|
||||
let mut lobbies = LOBBIES.write().await;
|
||||
|
||||
let (lobby_id, lobby) = match lobby_id {
|
||||
Some(id) => {
|
||||
let Some(lobby) = lobbies.get_mut(&id) else {
|
||||
return send_packet(
|
||||
client_id,
|
||||
ServerPacket::Refused("lobby not found".to_string()),
|
||||
)
|
||||
.await;
|
||||
};
|
||||
(id, lobby)
|
||||
}
|
||||
None => {
|
||||
let random_lobby = lobbies
|
||||
.iter_mut()
|
||||
.filter(|(_, lobby)| lobby.public)
|
||||
.min_by_key(|(_, lobby)| lobby.players.len());
|
||||
match random_lobby {
|
||||
Some((&id, lobby)) => (id, lobby),
|
||||
None => {
|
||||
let id = Uuid::now_v7();
|
||||
(
|
||||
id,
|
||||
lobbies.entry(id).or_insert(Lobby {
|
||||
public: true,
|
||||
players: HashMap::new(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
lobby.players.insert(
|
||||
client_id,
|
||||
LobbyPlayer {
|
||||
username,
|
||||
ready: false,
|
||||
},
|
||||
);
|
||||
|
||||
CLIENTS
|
||||
.write()
|
||||
.await
|
||||
.get_mut(&client_id)
|
||||
.expect("client not found")
|
||||
.status = ClientStatus::InLobby(lobby_id);
|
||||
send_packet(client_id, ServerPacket::LobbyJoined(lobby_id)).await;
|
||||
|
||||
let message = bincode::serialize(&ServerPacket::LobbyUpdated(lobby.clone()))
|
||||
.expect("failed to serialize lobby"); // PAS BON
|
||||
for player_id in lobby.players.keys() {
|
||||
send_message(*player_id, &message).await;
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_in_lobby(client_id: Uuid, lobby_id: Uuid, packet: ClientPacket) {
|
||||
match packet {
|
||||
ClientPacket::Disconnect => todo!(),
|
||||
ClientPacket::IAmReady => todo!(),
|
||||
ClientPacket::IAmNotReady => todo!(),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_in_game(client_id: Uuid, game_id: Uuid, packet: ClientPacket) {}
|
|
@ -4,35 +4,34 @@ use serde::{Deserialize, Serialize};
|
|||
use uuid::Uuid;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum ClientPacket {
|
||||
Disconnect,
|
||||
pub enum ClientMessage {
|
||||
CreateLobby {
|
||||
username: String,
|
||||
public: bool,
|
||||
},
|
||||
JoinLobby {
|
||||
lobby_id: Option<Uuid>,
|
||||
username: String,
|
||||
lobby_id: Option<Uuid>,
|
||||
},
|
||||
IAmReady,
|
||||
IAmNotReady,
|
||||
Ready(bool),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum ServerPacket {
|
||||
pub enum ServerMessage {
|
||||
Refused(String),
|
||||
LobbyJoined(Uuid),
|
||||
LobbyUpdated(Lobby),
|
||||
LobbyUpdate(Lobby),
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Lobby {
|
||||
pub id: Uuid,
|
||||
pub public: bool,
|
||||
pub players: HashMap<Uuid, LobbyPlayer>,
|
||||
pub players: HashMap<Uuid, Player>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct LobbyPlayer {
|
||||
pub struct Player {
|
||||
pub id: Uuid,
|
||||
pub username: String,
|
||||
pub ready: bool,
|
||||
}
|
||||
|
|
|
@ -1,202 +1,102 @@
|
|||
use std::borrow::{Borrow, Cow};
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::extract::ws::{Message, WebSocket};
|
||||
use axum::extract::WebSocketUpgrade;
|
||||
use ascon_hash::{AsconXof, ExtendableOutput, Update, XofReader};
|
||||
use axum::extract::ws::Message;
|
||||
use axum::extract::{State, WebSocketUpgrade};
|
||||
use axum::response::IntoResponse;
|
||||
use axum::routing::get;
|
||||
use axum::Router;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use lazy_static::lazy_static;
|
||||
use log::warn;
|
||||
use server::{ClientPacket, Lobby, LobbyPlayer, ServerPacket};
|
||||
use manager::handle_event;
|
||||
use server::{ClientMessage, ServerMessage};
|
||||
use tokio::sync::mpsc::{channel, Sender};
|
||||
use tokio::sync::RwLock;
|
||||
use uuid::Uuid;
|
||||
|
||||
struct Client {
|
||||
status: ClientStatus,
|
||||
sender: Sender<Vec<u8>>,
|
||||
}
|
||||
|
||||
enum ClientStatus {
|
||||
Unauthenticated,
|
||||
InLobby(Uuid),
|
||||
InGame(Uuid),
|
||||
}
|
||||
mod manager;
|
||||
|
||||
lazy_static! {
|
||||
static ref CLIENTS: RwLock<HashMap<Uuid, Client>> = RwLock::new(HashMap::new());
|
||||
static ref LOBBIES: RwLock<HashMap<Uuid, Lobby>> = RwLock::new(HashMap::new());
|
||||
pub static ref CONNECTIONS: ConnectionManager = ConnectionManager::default();
|
||||
}
|
||||
|
||||
pub async fn send_message<'a>(client_id: Uuid, message: impl Into<Cow<'a, [u8]>>) {
|
||||
if let Some(client) = CLIENTS.read().await.get(&client_id) {
|
||||
client.sender.send(message.into().into_owned()).await.ok();
|
||||
}
|
||||
}
|
||||
#[derive(Default)]
|
||||
pub struct ConnectionManager(RwLock<HashMap<Uuid, Sender<Vec<u8>>>>);
|
||||
|
||||
pub async fn send_packet(client_id: Uuid, packet: impl Borrow<ServerPacket>) {
|
||||
let message = match bincode::serialize(packet.borrow()) {
|
||||
Ok(message) => message,
|
||||
Err(error) => {
|
||||
warn!("failed to serialize packet for {}: {}", client_id, error);
|
||||
impl ConnectionManager {
|
||||
pub async fn send(&self, id: Uuid, message: impl Borrow<ServerMessage>) {
|
||||
if let Some(sender) = self.0.read().await.get(&id) {
|
||||
let Ok(message) = bincode::serialize(message.borrow()) else {
|
||||
eprintln!("failed to serialize message");
|
||||
return;
|
||||
}
|
||||
};
|
||||
send_message(client_id, message).await;
|
||||
sender.send(message).await.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ClientEvent {
|
||||
Connected,
|
||||
Message(ClientMessage),
|
||||
Disconnected,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
get(|ws: WebSocketUpgrade| async { ws.on_upgrade(handle_client) }),
|
||||
);
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:80")
|
||||
.await
|
||||
.expect("failed to bind");
|
||||
axum::serve(listener, app).await.expect("failed to serve");
|
||||
let app = Router::new().route("/ws", get(ws_handler));
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:80").await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
||||
|
||||
async fn handle_client(socket: WebSocket) {
|
||||
let client_id = Uuid::now_v7();
|
||||
async fn ws_handler(ws: WebSocketUpgrade) -> impl IntoResponse {
|
||||
ws.on_upgrade(|mut socket| async move {
|
||||
// Handle authentication
|
||||
let Some(Ok(message)) = socket.recv().await else {
|
||||
return;
|
||||
};
|
||||
let mut reader = AsconXof::default()
|
||||
.chain(message.into_data())
|
||||
.finalize_xof();
|
||||
let mut hash = [0u8; 16];
|
||||
reader.read(&mut hash);
|
||||
let id = Uuid::from_bytes(hash);
|
||||
|
||||
let (mut sender, mut receiver) = socket.split();
|
||||
let (send_tx, mut send_rx) = channel(16);
|
||||
// Start the sending loop
|
||||
let (mut writer, mut reader) = socket.split();
|
||||
let (sender, mut receiver) = channel(1);
|
||||
tokio::spawn(async move {
|
||||
while let Some(message) = send_rx.recv().await {
|
||||
sender.send(Message::Binary(message)).await?;
|
||||
while let Some(message) = receiver.recv().await {
|
||||
writer.send(Message::Binary(message)).await?;
|
||||
}
|
||||
Ok::<(), axum::Error>(())
|
||||
});
|
||||
|
||||
CLIENTS.write().await.insert(
|
||||
client_id,
|
||||
Client {
|
||||
status: ClientStatus::Unauthenticated,
|
||||
sender: send_tx,
|
||||
},
|
||||
);
|
||||
// Register the client
|
||||
match CONNECTIONS.0.write().await.entry(id) {
|
||||
Entry::Occupied(_) => return,
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(sender);
|
||||
}
|
||||
}
|
||||
|
||||
while let Some(Ok(message)) = receiver.next().await {
|
||||
let Message::Binary(message) = message else {
|
||||
// Send the connection event
|
||||
handle_event(id, ClientEvent::Connected).await;
|
||||
|
||||
// Handle incoming messages
|
||||
while let Some(Ok(message)) = reader.next().await {
|
||||
let Ok(message) = bincode::deserialize(&message.into_data()) else {
|
||||
continue;
|
||||
};
|
||||
let Ok(packet) = bincode::deserialize::<ClientPacket>(&message) else {
|
||||
warn!("failed to deserialize packet from {}", client_id);
|
||||
continue;
|
||||
};
|
||||
packet_received(client_id, packet).await;
|
||||
handle_event(id, ClientEvent::Message(message)).await;
|
||||
}
|
||||
|
||||
packet_received(client_id, ClientPacket::Disconnect).await;
|
||||
CLIENTS.write().await.remove(&client_id);
|
||||
// Send the disconnection event
|
||||
handle_event(id, ClientEvent::Disconnected).await;
|
||||
|
||||
// Unregister the client
|
||||
CONNECTIONS.0.write().await.remove(&id);
|
||||
})
|
||||
}
|
||||
|
||||
async fn packet_received(client_id: Uuid, packet: ClientPacket) {
|
||||
let client = &CLIENTS.read().await[&client_id];
|
||||
match client.status {
|
||||
ClientStatus::Unauthenticated => handle_unauthenticated(client_id, packet).await,
|
||||
ClientStatus::InLobby(lobby_id) => handle_in_lobby(client_id, lobby_id, packet).await,
|
||||
ClientStatus::InGame(game_id) => handle_in_game(client_id, game_id, packet).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_unauthenticated(client_id: Uuid, packet: ClientPacket) {
|
||||
match packet {
|
||||
ClientPacket::CreateLobby { username, public } => {
|
||||
let lobby_id = Uuid::now_v7();
|
||||
let lobby = Lobby {
|
||||
public,
|
||||
players: HashMap::from_iter([(
|
||||
client_id,
|
||||
LobbyPlayer {
|
||||
username,
|
||||
ready: false,
|
||||
},
|
||||
)]),
|
||||
};
|
||||
let message = bincode::serialize(&ServerPacket::LobbyUpdated(lobby.clone()))
|
||||
.expect("failed to serialize lobby");
|
||||
let mut lobbies = LOBBIES.write().await;
|
||||
lobbies.insert(lobby_id, lobby);
|
||||
CLIENTS
|
||||
.write()
|
||||
.await
|
||||
.get_mut(&client_id)
|
||||
.expect("client not found")
|
||||
.status = ClientStatus::InLobby(lobby_id);
|
||||
send_packet(client_id, ServerPacket::LobbyJoined(lobby_id)).await;
|
||||
send_message(client_id, message).await;
|
||||
}
|
||||
ClientPacket::JoinLobby { lobby_id, username } => {
|
||||
let mut lobbies = LOBBIES.write().await;
|
||||
|
||||
let (lobby_id, lobby) = match lobby_id {
|
||||
Some(id) => {
|
||||
let Some(lobby) = lobbies.get_mut(&id) else {
|
||||
return send_packet(
|
||||
client_id,
|
||||
ServerPacket::Refused("lobby not found".to_string()),
|
||||
)
|
||||
.await;
|
||||
};
|
||||
(id, lobby)
|
||||
}
|
||||
None => {
|
||||
let random_lobby = lobbies
|
||||
.iter_mut()
|
||||
.filter(|(_, lobby)| lobby.public)
|
||||
.min_by_key(|(_, lobby)| lobby.players.len());
|
||||
match random_lobby {
|
||||
Some((&id, lobby)) => (id, lobby),
|
||||
None => {
|
||||
let id = Uuid::now_v7();
|
||||
(
|
||||
id,
|
||||
lobbies.entry(id).or_insert(Lobby {
|
||||
public: true,
|
||||
players: HashMap::new(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
lobby.players.insert(
|
||||
client_id,
|
||||
LobbyPlayer {
|
||||
username,
|
||||
ready: false,
|
||||
},
|
||||
);
|
||||
|
||||
CLIENTS
|
||||
.write()
|
||||
.await
|
||||
.get_mut(&client_id)
|
||||
.expect("client not found")
|
||||
.status = ClientStatus::InLobby(lobby_id);
|
||||
send_packet(client_id, ServerPacket::LobbyJoined(lobby_id)).await;
|
||||
|
||||
let message = bincode::serialize(&ServerPacket::LobbyUpdated(lobby.clone()))
|
||||
.expect("failed to serialize lobby"); // PAS BON
|
||||
for player_id in lobby.players.keys() {
|
||||
send_message(*player_id, &message).await;
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_in_lobby(client_id: Uuid, lobby_id: Uuid, packet: ClientPacket) {
|
||||
match packet {
|
||||
ClientPacket::Disconnect => todo!(),
|
||||
ClientPacket::IAmReady => todo!(),
|
||||
ClientPacket::IAmNotReady => todo!(),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_in_game(client_id: Uuid, game_id: Uuid, packet: ClientPacket) {}
|
||||
|
|
182
crates/server/src/manager.rs
Normal file
182
crates/server/src/manager.rs
Normal file
|
@ -0,0 +1,182 @@
|
|||
use std::collections::hash_map::{Entry, VacantEntry};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use server::{Lobby, Player, ServerMessage};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
use tokio::sync::{RwLock, RwLockWriteGuard};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{ClientEvent, ClientMessage, CONNECTIONS};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum ClientStatus {
|
||||
InLobby(Uuid),
|
||||
InGame(Uuid),
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref CLIENT_STATUS: RwLock<HashMap<Uuid, ClientStatus>> = RwLock::new(HashMap::new());
|
||||
pub static ref LOBBIES: RwLock<HashMap<Uuid, Lobby>> = RwLock::new(HashMap::new());
|
||||
}
|
||||
|
||||
pub async fn handle_event(id: Uuid, event: ClientEvent) {
|
||||
let status = CLIENT_STATUS.read().await.get(&id).copied();
|
||||
match status {
|
||||
None => handle_unauthenticated_event(id, event).await,
|
||||
Some(ClientStatus::InLobby(lobby_id)) => handle_lobby_event(lobby_id, id, event).await,
|
||||
Some(ClientStatus::InGame(game_id)) => handle_game_event(game_id, id, event).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_unauthenticated_event(id: Uuid, event: ClientEvent) {
|
||||
match event {
|
||||
ClientEvent::Message(ClientMessage::CreateLobby { username, public }) => {
|
||||
// Create the lobby
|
||||
let mut lobbies = LOBBIES.write().await;
|
||||
let lobby_id = Uuid::now_v7();
|
||||
let lobby = lobbies.entry(lobby_id).or_insert(Lobby {
|
||||
id: lobby_id,
|
||||
public,
|
||||
players: HashMap::from_iter([(
|
||||
id,
|
||||
Player {
|
||||
id,
|
||||
username,
|
||||
ready: false,
|
||||
},
|
||||
)]),
|
||||
});
|
||||
|
||||
// Change the client status
|
||||
CLIENT_STATUS
|
||||
.write()
|
||||
.await
|
||||
.insert(id, ClientStatus::InLobby(lobby.id));
|
||||
|
||||
// Send the lobby update
|
||||
CONNECTIONS
|
||||
.send(id, ServerMessage::LobbyUpdate(lobby.clone()))
|
||||
.await;
|
||||
}
|
||||
ClientEvent::Message(ClientMessage::JoinLobby { username, lobby_id }) => {
|
||||
// Find or create the lobby
|
||||
let mut lobbies = LOBBIES.write().await;
|
||||
let lobby = match lobby_id {
|
||||
Some(lobby_id) => {
|
||||
let Some(lobby) = lobbies.get_mut(&lobby_id) else {
|
||||
CONNECTIONS
|
||||
.send(id, ServerMessage::Refused("Lobby not found".to_string()))
|
||||
.await;
|
||||
return;
|
||||
};
|
||||
lobby
|
||||
}
|
||||
None => {
|
||||
if let Some((_, lobby)) = lobbies
|
||||
.iter_mut()
|
||||
.min_by_key(|(_, value)| value.players.len())
|
||||
{
|
||||
lobby
|
||||
} else {
|
||||
let lobby_id = Uuid::now_v7();
|
||||
lobbies.entry(lobby_id).or_insert(Lobby {
|
||||
id: lobby_id,
|
||||
public: true,
|
||||
players: HashMap::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Change the client status
|
||||
CLIENT_STATUS
|
||||
.write()
|
||||
.await
|
||||
.insert(id, ClientStatus::InLobby(lobby.id));
|
||||
|
||||
// Add the player to the lobby
|
||||
lobby.players.insert(
|
||||
id,
|
||||
Player {
|
||||
id,
|
||||
username,
|
||||
ready: false,
|
||||
},
|
||||
);
|
||||
|
||||
// Send the lobby update to all players
|
||||
let message = ServerMessage::LobbyUpdate(lobby.clone());
|
||||
for player_id in lobby.players.keys() {
|
||||
CONNECTIONS.send(*player_id, &message).await;
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
|
||||
async fn handle_lobby_event(lobby_id: Uuid, id: Uuid, event: ClientEvent) {
|
||||
match event {
|
||||
ClientEvent::Message(ClientMessage::Ready(ready)) => {
|
||||
// Get the lobby
|
||||
let mut lobbies = LOBBIES.write().await;
|
||||
let Some(lobby) = lobbies.get_mut(&lobby_id) else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Get the lobby player
|
||||
let Some(player) = lobby.players.get_mut(&id) else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Update the player ready status
|
||||
player.ready = ready;
|
||||
|
||||
// If everyone is ready, start the game
|
||||
if lobby.players.len() >= 2 && lobby.players.values().all(|p| p.ready) {
|
||||
todo!("start the game");
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the lobby update to all players
|
||||
let message = ServerMessage::LobbyUpdate(lobby.clone());
|
||||
for player_id in lobby.players.keys() {
|
||||
CONNECTIONS.send(*player_id, &message).await;
|
||||
}
|
||||
}
|
||||
ClientEvent::Disconnected => {
|
||||
// Remove the client status
|
||||
CLIENT_STATUS.write().await.remove(&id);
|
||||
|
||||
// Remove the client from the lobby
|
||||
let mut lobbies = LOBBIES.write().await;
|
||||
let Some(lobby) = lobbies.get_mut(&lobby_id) else {
|
||||
return;
|
||||
};
|
||||
lobby.players.remove(&id);
|
||||
|
||||
// If the lobby is empty, remove it
|
||||
if lobby.players.is_empty() {
|
||||
lobbies.remove(&lobby_id);
|
||||
return;
|
||||
}
|
||||
|
||||
// If everyone is ready, start the game
|
||||
if lobby.players.len() >= 2 && lobby.players.values().all(|p| p.ready) {
|
||||
todo!("start the game");
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the lobby update to all players
|
||||
let message = ServerMessage::LobbyUpdate(lobby.clone());
|
||||
for player_id in lobby.players.keys() {
|
||||
CONNECTIONS.send(*player_id, &message).await;
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_game_event(game_id: Uuid, id: Uuid, event: ClientEvent) {
|
||||
todo!()
|
||||
}
|
Loading…
Reference in a new issue