From 1058048a12a5746a50f6d62b999fab8bc91ed3bc Mon Sep 17 00:00:00 2001 From: Maple Date: Thu, 31 Jul 2025 22:00:48 +0200 Subject: [PATCH 001/203] fix memory leak --- macros/src/protos.rs | 7 +------ src/nex/matchmake.rs | 4 +++- src/nex/user.rs | 6 ++++++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/macros/src/protos.rs b/macros/src/protos.rs index 14ec2f6..fdf8b62 100644 --- a/macros/src/protos.rs +++ b/macros/src/protos.rs @@ -325,10 +325,5 @@ impl ToTokens for RmcProtocolData{ self.generate_raw_trait(tokens); self.generate_raw_info(tokens); self.generate_raw_remote_trait(tokens); - - - - } -} - +} \ No newline at end of file diff --git a/src/nex/matchmake.rs b/src/nex/matchmake.rs index bba55f5..c01c9a7 100644 --- a/src/nex/matchmake.rs +++ b/src/nex/matchmake.rs @@ -50,7 +50,7 @@ impl MatchmakeManager{ async fn garbage_collect(&self){ info!("running rnex garbage collector over all sessions and users"); - let idx = 0; + let mut idx = 0; let mut to_be_deleted_gids = Vec::new(); @@ -69,6 +69,8 @@ impl MatchmakeManager{ if !session.is_reachable(){ to_be_deleted_gids.push(gid); } + + idx += 1; } let mut sessions = self.sessions.write().await; diff --git a/src/nex/user.rs b/src/nex/user.rs index e166a80..d77c289 100644 --- a/src/nex/user.rs +++ b/src/nex/user.rs @@ -269,6 +269,12 @@ impl MatchmakeExtension for User { let session = self.matchmake_manager.get_session(join_session_param.gid).await?; let mut session = session.lock().await; + + if session.session.user_password_enabled{ + if join_session_param.user_password != session.session.user_password{ + return Err(ErrorCode::RendezVous_InvalidPassword) + } + } session.connected_players.retain(|v| v.upgrade().is_some_and(|v| v.pid != self.pid)); From a4ccc96ed01688e2f4cecbc2d6b423385b763776 Mon Sep 17 00:00:00 2001 From: Maple Date: Thu, 31 Jul 2025 23:39:26 +0200 Subject: [PATCH 002/203] update readme --- README.md | 2 +- macros/Cargo.lock | 113 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4900bd8..f0526a0 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,4 @@ - Pretendo team for the rest of the Servers and Reverse engineering efforts - Kinnay for his huge work on reversing nex servers and documentation(https://github.com/Kinnay/NintendoClients/) - Splatfestival testing team for helping us test our messes of code -- The SPFN team(Andrea and DJMrTV) \ No newline at end of file +- The SPFN team(Bloxer, Ceantix and Maple(aka TV)) \ No newline at end of file diff --git a/macros/Cargo.lock b/macros/Cargo.lock index a82b7df..acad79d 100644 --- a/macros/Cargo.lock +++ b/macros/Cargo.lock @@ -2,15 +2,55 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[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", +] + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + [[package]] name = "macros" version = "0.0.0" dependencies = [ "proc-macro2", "quote", + "rand", "syn", ] +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro2" version = "1.0.93" @@ -29,6 +69,41 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[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", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", +] + [[package]] name = "syn" version = "2.0.98" @@ -45,3 +120,41 @@ name = "unicode-ident" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" + +[[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 = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] From aab441490410122526da8df684ae9a3c77b67a0e Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 21 Sep 2025 15:59:27 +0200 Subject: [PATCH 003/203] refactor --- Cargo.lock | 3712 ----------------- Cargo.toml | 98 +- bu | 12 + macros/src/lib.rs | 30 +- macros/src/protos.rs | 30 +- prudpv1/src/executables/common.rs | 18 + {src => prudpv1/src}/executables/mod.rs | 0 .../src}/executables/proxy_insecure.rs | 40 +- .../src}/executables/proxy_secure.rs | 46 +- {src => prudpv1/src}/prudp/auth_module.rs | 0 {src => prudpv1/src}/prudp/mod.rs | 2 - {src => prudpv1/src}/prudp/packet.rs | 54 +- {src => prudpv1/src}/prudp/router.rs | 3 +- {src => prudpv1/src}/prudp/secure.rs | 8 +- {src => prudpv1/src}/prudp/socket.rs | 5 +- {src => prudpv1/src}/prudp/unsecure.rs | 0 {src => rnex-core/src}/common.rs | 0 .../executables/backend_server_insecure.rs | 38 +- .../src}/executables/backend_server_secure.rs | 24 +- {src => rnex-core/src}/executables/common.rs | 18 +- .../executables/edge_node_holder_server.rs | 14 +- rnex-core/src/executables/mod.rs | 1 + {src => rnex-core/src}/grpc/account.rs | 0 {src => rnex-core/src}/grpc/mod.rs | 1 - {src => rnex-core/src}/kerberos/mod.rs | 2 +- {src => rnex-core/src}/lib.rs | 4 +- {src => rnex-core/src}/main.rs | 6 - {src => rnex-core/src}/nex/account.rs | 0 {src => rnex-core/src}/nex/auth_handler.rs | 28 +- {src => rnex-core/src}/nex/matchmake.rs | 14 +- {src => rnex-core/src}/nex/mod.rs | 0 {src => rnex-core/src}/nex/remote_console.rs | 0 {src => rnex-core/src}/nex/user.rs | 24 +- rnex-core/src/prudp/mod.rs | 3 + .../src/prudp/socket_addr.rs | 7 +- {src => rnex-core/src}/prudp/station_url.rs | 2 +- rnex-core/src/prudp/virtual_port.rs | 49 + {src => rnex-core/src}/reggie.rs | 4 +- {src => rnex-core/src}/result.rs | 0 {src => rnex-core/src}/rmc/message.rs | 2 +- {src => rnex-core/src}/rmc/mod.rs | 0 {src => rnex-core/src}/rmc/protocols/auth.rs | 6 +- .../src}/rmc/protocols/matchmake.rs | 4 +- .../src}/rmc/protocols/matchmake_ext.rs | 2 +- .../src}/rmc/protocols/matchmake_extension.rs | 4 +- {src => rnex-core/src}/rmc/protocols/mod.rs | 12 +- .../src}/rmc/protocols/nat_traversal.rs | 2 +- .../src}/rmc/protocols/notifications.rs | 0 .../src}/rmc/protocols/ranking.rs | 0 .../src}/rmc/protocols/secure.rs | 6 +- {src => rnex-core/src}/rmc/response.rs | 4 +- {src => rnex-core/src}/rmc/structures/any.rs | 2 +- .../src}/rmc/structures/buffer.rs | 0 .../src}/rmc/structures/connection_data.rs | 3 +- {src => rnex-core/src}/rmc/structures/list.rs | 2 +- .../src}/rmc/structures/matchmake.rs | 4 +- {src => rnex-core/src}/rmc/structures/mod.rs | 0 .../src}/rmc/structures/networking.rs | 2 +- .../src}/rmc/structures/primitives.rs | 2 +- .../src}/rmc/structures/qbuffer.rs | 2 +- .../src}/rmc/structures/qresult.rs | 4 +- .../src}/rmc/structures/ranking.rs | 4 +- .../src}/rmc/structures/rmc_struct.rs | 2 +- .../src}/rmc/structures/string.rs | 2 +- .../src}/rmc/structures/variant.rs | 0 {src => rnex-core/src}/rnex_proxy_common.rs | 2 +- {src => rnex-core/src}/util.rs | 2 +- {src => rnex-core/src}/versions.rs | 0 {src => rnex-core/src}/web/mod.rs | 0 src/endianness.rs | 230 - src/grpc/protobufs.rs | 5 - 71 files changed, 292 insertions(+), 4315 deletions(-) delete mode 100644 Cargo.lock create mode 100644 bu create mode 100644 prudpv1/src/executables/common.rs rename {src => prudpv1/src}/executables/mod.rs (100%) rename {src => prudpv1/src}/executables/proxy_insecure.rs (70%) rename {src => prudpv1/src}/executables/proxy_secure.rs (71%) rename {src => prudpv1/src}/prudp/auth_module.rs (100%) rename {src => prudpv1/src}/prudp/mod.rs (71%) rename {src => prudpv1/src}/prudp/packet.rs (91%) rename {src => prudpv1/src}/prudp/router.rs (98%) rename {src => prudpv1/src}/prudp/secure.rs (96%) rename {src => prudpv1/src}/prudp/socket.rs (99%) rename {src => prudpv1/src}/prudp/unsecure.rs (100%) rename {src => rnex-core/src}/common.rs (100%) rename {src => rnex-core/src}/executables/backend_server_insecure.rs (70%) rename {src => rnex-core/src}/executables/backend_server_secure.rs (74%) rename {src => rnex-core/src}/executables/common.rs (69%) rename {src => rnex-core/src}/executables/edge_node_holder_server.rs (85%) create mode 100644 rnex-core/src/executables/mod.rs rename {src => rnex-core/src}/grpc/account.rs (100%) rename {src => rnex-core/src}/grpc/mod.rs (95%) rename {src => rnex-core/src}/kerberos/mod.rs (98%) rename {src => rnex-core/src}/lib.rs (90%) rename {src => rnex-core/src}/main.rs (98%) rename {src => rnex-core/src}/nex/account.rs (100%) rename {src => rnex-core/src}/nex/auth_handler.rs (89%) rename {src => rnex-core/src}/nex/matchmake.rs (95%) rename {src => rnex-core/src}/nex/mod.rs (100%) rename {src => rnex-core/src}/nex/remote_console.rs (100%) rename {src => rnex-core/src}/nex/user.rs (95%) create mode 100644 rnex-core/src/prudp/mod.rs rename src/prudp/sockaddr.rs => rnex-core/src/prudp/socket_addr.rs (85%) rename {src => rnex-core/src}/prudp/station_url.rs (99%) create mode 100644 rnex-core/src/prudp/virtual_port.rs rename {src => rnex-core/src}/reggie.rs (97%) rename {src => rnex-core/src}/result.rs (100%) rename {src => rnex-core/src}/rmc/message.rs (97%) rename {src => rnex-core/src}/rmc/mod.rs (100%) rename {src => rnex-core/src}/rmc/protocols/auth.rs (93%) rename {src => rnex-core/src}/rmc/protocols/matchmake.rs (86%) rename {src => rnex-core/src}/rmc/protocols/matchmake_ext.rs (82%) rename {src => rnex-core/src}/rmc/protocols/matchmake_extension.rs (87%) rename {src => rnex-core/src}/rmc/protocols/mod.rs (94%) rename {src => rnex-core/src}/rmc/protocols/nat_traversal.rs (94%) rename {src => rnex-core/src}/rmc/protocols/notifications.rs (100%) rename {src => rnex-core/src}/rmc/protocols/ranking.rs (100%) rename {src => rnex-core/src}/rmc/protocols/secure.rs (69%) rename {src => rnex-core/src}/rmc/response.rs (99%) rename {src => rnex-core/src}/rmc/structures/any.rs (94%) rename {src => rnex-core/src}/rmc/structures/buffer.rs (100%) rename {src => rnex-core/src}/rmc/structures/connection_data.rs (75%) rename {src => rnex-core/src}/rmc/structures/list.rs (96%) rename {src => rnex-core/src}/rmc/structures/matchmake.rs (97%) rename {src => rnex-core/src}/rmc/structures/mod.rs (100%) rename {src => rnex-core/src}/rmc/structures/networking.rs (94%) rename {src => rnex-core/src}/rmc/structures/primitives.rs (99%) rename {src => rnex-core/src}/rmc/structures/qbuffer.rs (91%) rename {src => rnex-core/src}/rmc/structures/qresult.rs (90%) rename {src => rnex-core/src}/rmc/structures/ranking.rs (96%) rename {src => rnex-core/src}/rmc/structures/rmc_struct.rs (95%) rename {src => rnex-core/src}/rmc/structures/string.rs (94%) rename {src => rnex-core/src}/rmc/structures/variant.rs (100%) rename {src => rnex-core/src}/rnex_proxy_common.rs (78%) rename {src => rnex-core/src}/util.rs (98%) rename {src => rnex-core/src}/versions.rs (100%) rename {src => rnex-core/src}/web/mod.rs (100%) delete mode 100644 src/endianness.rs delete mode 100644 src/grpc/protobufs.rs diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index fcc53fc..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,3712 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anyhow" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" - -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "async-trait" -version = "0.1.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "atomic" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" - -[[package]] -name = "atomic" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "aws-lc-rs" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fcc8f365936c834db5514fc45aee5b1202d677e6b40e48468aaaa8183ca8c7" -dependencies = [ - "aws-lc-sys", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b1d86e7705efe1be1b569bab41d4fa1e14e220b60a160f78de2db687add079" -dependencies = [ - "bindgen", - "cc", - "cmake", - "dunce", - "fs_extra", -] - -[[package]] -name = "axum" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" -dependencies = [ - "async-trait", - "axum-core", - "bytes", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower 0.5.2", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "mime", - "pin-project-lite", - "rustversion", - "sync_wrapper", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "base64ct" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" - -[[package]] -name = "binascii" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" - -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.102", - "which", -] - -[[package]] -name = "bitflags" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bumpalo" -version = "3.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" - -[[package]] -name = "bytemuck" -version = "1.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "cc" -version = "1.2.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac" -dependencies = [ - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "chrono" -version = "0.4.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-link", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "cmake" -version = "0.1.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" -dependencies = [ - "cc", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "cookie" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ctrlc" -version = "3.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73" -dependencies = [ - "nix", - "windows-sys 0.59.0", -] - -[[package]] -name = "data-encoding" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" - -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "devise" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1d90b0c4c777a2cad215e3c7be59ac7c15adf45cf76317009b7d096d46f651d" -dependencies = [ - "devise_codegen", - "devise_core", -] - -[[package]] -name = "devise_codegen" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71b28680d8be17a570a2334922518be6adc3f58ecc880cbb404eaeb8624fd867" -dependencies = [ - "devise_core", - "quote", -] - -[[package]] -name = "devise_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b035a542cf7abf01f2e3c4d5a7acbaebfefe120ae4efc7bde3df98186e4b8af7" -dependencies = [ - "bitflags", - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "figment" -version = "0.10.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" -dependencies = [ - "atomic 0.6.0", - "pear", - "serde", - "toml", - "uncased", - "version_check", -] - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generator" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" -dependencies = [ - "cc", - "libc", - "log", - "rustversion", - "windows", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.1+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]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "glob" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.9.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "h2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http 1.3.1", - "indexmap 2.9.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http 1.3.1", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http 1.3.1", - "http-body 1.0.1", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "0.14.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "h2 0.4.10", - "http 1.3.1", - "http-body 1.0.1", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http 1.3.1", - "hyper 1.6.0", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", -] - -[[package]] -name = "hyper-timeout" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" -dependencies = [ - "hyper 1.6.0", - "hyper-util", - "pin-project-lite", - "tokio", - "tower-service", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper 1.6.0", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb" -dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "hyper 1.6.0", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2", - "system-configuration", - "tokio", - "tower-service", - "tracing", - "windows-registry", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "icu_collections" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" - -[[package]] -name = "icu_provider" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" -dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" -dependencies = [ - "equivalent", - "hashbrown 0.15.4", - "serde", -] - -[[package]] -name = "inlinable_string" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" - -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "generic-array", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "is-terminal" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "jobserver" -version = "0.1.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" -dependencies = [ - "getrandom 0.3.3", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "json" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libc" -version = "0.2.172" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" - -[[package]] -name = "libloading" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" -dependencies = [ - "cfg-if", - "windows-targets 0.53.1", -] - -[[package]] -name = "libm" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - -[[package]] -name = "litemap" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" - -[[package]] -name = "lock_api" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "loom" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "serde", - "serde_json", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "macros" -version = "0.0.0" -dependencies = [ - "proc-macro2", - "quote", - "rand 0.9.1", - "syn 2.0.102", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "md-5" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" -dependencies = [ - "cfg-if", - "digest", -] - -[[package]] -name = "memchr" -version = "2.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" - -[[package]] -name = "mime" -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.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" -dependencies = [ - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", -] - -[[package]] -name = "multer" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http 1.3.1", - "httparse", - "memchr", - "mime", - "spin", - "tokio", - "tokio-util", - "version_check", -] - -[[package]] -name = "multimap" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" - -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nix" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" -dependencies = [ - "bitflags", - "cfg-if", - "cfg_aliases", - "libc", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-bigint-dig" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" -dependencies = [ - "byteorder", - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.8.5", - "smallvec", - "zeroize", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "openssl" -version = "0.10.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-sys" -version = "0.9.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "parking_lot" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "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 = "pear" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467" -dependencies = [ - "inlinable_string", - "pear_codegen", - "yansi", -] - -[[package]] -name = "pear_codegen" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147" -dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "petgraph" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" -dependencies = [ - "fixedbitset", - "indexmap 2.9.0", -] - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs1" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" -dependencies = [ - "der", - "pkcs8", - "spki", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "potential_utf" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "prettyplease" -version = "0.2.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d" -dependencies = [ - "proc-macro2", - "syn 2.0.102", -] - -[[package]] -name = "proc-macro2" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proc-macro2-diagnostics" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", - "version_check", - "yansi", -] - -[[package]] -name = "prost" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" -dependencies = [ - "heck", - "itertools 0.14.0", - "log", - "multimap", - "once_cell", - "petgraph", - "prettyplease", - "prost", - "prost-types", - "regex", - "syn 2.0.102", - "tempfile", -] - -[[package]] -name = "prost-derive" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" -dependencies = [ - "anyhow", - "itertools 0.14.0", - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "prost-types" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" -dependencies = [ - "prost", -] - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "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]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "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]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] - -[[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]] -name = "rc4" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1256e23efe6097f27aa82d6ca6889361c001586ae0f6917cbad072f05eb275" -dependencies = [ - "cipher", -] - -[[package]] -name = "redox_syscall" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" -dependencies = [ - "bitflags", -] - -[[package]] -name = "ref-cast" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "reqwest" -version = "0.12.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "h2 0.4.10", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "hyper 1.6.0", - "hyper-rustls", - "hyper-tls", - "hyper-util", - "js-sys", - "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-native-tls", - "tower 0.5.2", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.16", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rocket" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a516907296a31df7dc04310e7043b61d71954d703b603cc6867a026d7e72d73f" -dependencies = [ - "async-stream", - "async-trait", - "atomic 0.5.3", - "binascii", - "bytes", - "either", - "figment", - "futures", - "indexmap 2.9.0", - "log", - "memchr", - "multer", - "num_cpus", - "parking_lot", - "pin-project-lite", - "rand 0.8.5", - "ref-cast", - "rocket_codegen", - "rocket_http", - "serde", - "serde_json", - "state", - "tempfile", - "time", - "tokio", - "tokio-stream", - "tokio-util", - "ubyte", - "version_check", - "yansi", -] - -[[package]] -name = "rocket_codegen" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46" -dependencies = [ - "devise", - "glob", - "indexmap 2.9.0", - "proc-macro2", - "quote", - "rocket_http", - "syn 2.0.102", - "unicode-xid", - "version_check", -] - -[[package]] -name = "rocket_http" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e274915a20ee3065f611c044bd63c40757396b6dbc057d6046aec27f14f882b9" -dependencies = [ - "cookie", - "either", - "futures", - "http 0.2.12", - "hyper 0.14.32", - "indexmap 2.9.0", - "log", - "memchr", - "pear", - "percent-encoding", - "pin-project-lite", - "ref-cast", - "serde", - "smallvec", - "stable-pattern", - "state", - "time", - "tokio", - "uncased", -] - -[[package]] -name = "rsa" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" -dependencies = [ - "const-oid", - "digest", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core 0.6.4", - "signature", - "spki", - "subtle", - "zeroize", -] - -[[package]] -name = "rust-nex" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-trait", - "bytemuck", - "chacha20", - "chrono", - "ctrlc", - "dotenv", - "futures", - "hex", - "hmac", - "json", - "log", - "macros", - "md-5", - "once_cell", - "paste", - "prost", - "rand 0.8.5", - "rc4", - "reqwest", - "rocket", - "rsa", - "rustls", - "rustls-pki-types", - "rustls-webpki", - "serde", - "sha2", - "simplelog", - "thiserror", - "tokio", - "tokio-rustls", - "tokio-stream", - "tokio-tungstenite", - "tonic", - "tonic-build", - "tungstenite", - "typenum", - "v_byte_macros", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustls" -version = "0.23.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" -dependencies = [ - "aws-lc-rs", - "log", - "once_cell", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pki-types" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" -dependencies = [ - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" -dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "schannel" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "serde_json" -version = "1.0.140" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest", - "rand_core 0.6.4", -] - -[[package]] -name = "simplelog" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16257adbfaef1ee58b1363bdc0664c9b8e1e30aed86049635fb5f147d065a9c0" -dependencies = [ - "log", - "termcolor", - "time", -] - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "stable-pattern" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" -dependencies = [ - "memchr", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "state" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" -dependencies = [ - "loom", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6397daf94fa90f058bd0fd88429dd9e5738999cca8d701813c80723add80462" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tempfile" -version = "3.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" -dependencies = [ - "fastrand", - "getrandom 0.3.3", - "once_cell", - "rustix 1.0.7", - "windows-sys 0.59.0", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "thiserror" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "time" -version = "0.3.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" -dependencies = [ - "deranged", - "itoa", - "libc", - "num-conv", - "num_threads", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" - -[[package]] -name = "time-macros" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tokio" -version = "1.45.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-macros" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489a59b6730eda1b0171fcfda8b121f4bee2b35cba8645ca35c5f7ba3eb736c1" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite", -] - -[[package]] -name = "tokio-util" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap 2.9.0", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "tonic" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64", - "bytes", - "h2 0.4.10", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "hyper 1.6.0", - "hyper-timeout", - "hyper-util", - "percent-encoding", - "pin-project", - "prost", - "socket2", - "tokio", - "tokio-stream", - "tower 0.4.13", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tonic-build" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" -dependencies = [ - "prettyplease", - "proc-macro2", - "prost-build", - "prost-types", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand 0.8.5", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-http" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" -dependencies = [ - "bitflags", - "bytes", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "iri-string", - "pin-project-lite", - "tower 0.5.2", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "tungstenite" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d" -dependencies = [ - "bytes", - "data-encoding", - "http 1.3.1", - "httparse", - "log", - "rand 0.9.1", - "sha1", - "thiserror", - "utf-8", -] - -[[package]] -name = "typenum" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" - -[[package]] -name = "ubyte" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f720def6ce1ee2fc44d40ac9ed6d3a59c361c80a75a7aa8e75bb9baed31cf2ea" -dependencies = [ - "serde", -] - -[[package]] -name = "uncased" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" -dependencies = [ - "serde", - "version_check", -] - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "v_byte_macros" -version = "0.0.3" -source = "git+https://github.com/DJMrTV/VByteMacros#1f2d596271933155a405ecdd362f750350960d44" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[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 = "wasm-bindgen" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.102", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "web-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "windows-interface" -version = "0.59.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "windows-link" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3bfe459f85da17560875b8bf1423d6f113b7a87a5d942e7da0ac71be7c61f8b" - -[[package]] -name = "windows-registry" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3bab093bdd303a1240bb99b8aba8ea8a69ee19d34c9e2ef9594e708a4878820" -dependencies = [ - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "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]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "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]] -name = "windows-targets" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30357ec391cde730f8fbfcdc29adc47518b06504528df977ab5af02ef23fdee9" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "winnow" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen-rt" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] - -[[package]] -name = "writeable" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" - -[[package]] -name = "yansi" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" -dependencies = [ - "is-terminal", -] - -[[package]] -name = "yoke" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.102", -] diff --git a/Cargo.toml b/Cargo.toml index dd12b89..9c63a93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,91 +1,7 @@ -[package] -name = "rust-nex" -version = "0.1.0" -edition = "2021" - -[profile.prod] -inherits = "release" -overflow-checks = false -strip = true -debug = false -debug-assertions = false -lto = true -incremental = false - - - -[dependencies] -bytemuck = { version = "1.21.0", features = ["derive"] } -dotenv = "0.15.0" -once_cell = "1.20.2" -rc4 = "0.1.0" -thiserror = "2.0.11" -v_byte_macros = { git = "https://github.com/DJMrTV/VByteMacros" } -simplelog = "0.12.2" -chrono = "0.4.39" -log = "0.4.25" -anyhow = "1.0.95" -rand = "0.8.5" - -hmac = "0.12.1" -md-5 = "^0.10.6" -tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "net", "sync", "fs"] } -tokio-stream = { version = "0.1.17", features = ["io-util"] } -tonic = "0.12.3" -prost = "0.13.4" -hex = "0.4.3" - -macros = { path = "macros" } -rocket = { version = "0.5.1", features = ["json", "serde_json"] } -serde = { version = "1.0.217", features = ["derive"] } -async-trait = "0.1.86" -paste = "1.0.15" -typenum = "1.18.0" -futures = "0.3.31" -reqwest = "0.12.18" -json = "0.12.4" -ctrlc = "3.4.7" -rsa = "0.9.8" -sha2 = "0.10.9" -chacha20 = "0.9.1" - -rustls = "0.23.27" - -rustls-pki-types = "1.12.0" -rustls-webpki = "0.103.3" -tokio-rustls = "0.26.2" -tokio-tungstenite = "0.27.0" -tungstenite = "0.27.0" - - - - -[build-dependencies] -tonic-build = "0.12.3" - -[features] -default = ["secure", "auth"] -secure = [] -auth = [] -no_tls = [] - -[[bin]] -name = "proxy_insecure" -path = "src/executables/proxy_insecure.rs" - -[[bin]] -name = "proxy_secure" -path = "src/executables/proxy_secure.rs" - -[[bin]] -name = "backend_server_insecure" -path = "src/executables/backend_server_insecure.rs" - - -[[bin]] -name = "backend_server_secure" -path = "src/executables/backend_server_secure.rs" - -[[bin]] -name = "edge_node_holder_server" -path = "src/executables/edge_node_holder_server.rs" \ No newline at end of file +[workspace] +resolver = "3" +members = [ + "macros", + "rnex-core", + "prudpv1" +] \ No newline at end of file diff --git a/bu b/bu new file mode 100644 index 0000000..da34886 --- /dev/null +++ b/bu @@ -0,0 +1,12 @@ + + +[build-dependencies] +tonic-build = "0.12.3" + +[features] +default = ["secure", "auth"] +secure = [] +auth = [] +no_tls = [] + + diff --git a/macros/src/lib.rs b/macros/src/lib.rs index ad77595..39639b3 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -65,7 +65,7 @@ fn gen_serialize_data_struct( let ident = f.ident.as_ref().unwrap(); serialize_content.append_all(quote! { - self.#ident.serialize(writer)?; + rnex_core::rmc::structures::RmcSerialize::serialize(&self.#ident, writer)?; }) } @@ -143,7 +143,7 @@ fn gen_serialize_data_struct( quote! { #pre_inner - rust_nex::rmc::structures::rmc_struct::write_struct(writer, #version, |mut writer|{ + rnex_core::rmc::structures::rmc_struct::write_struct(writer, #version, |mut writer|{ #serialize_base_content })?; @@ -176,7 +176,7 @@ fn gen_serialize_data_struct( quote! { #pre_inner - Ok(rust_nex::rmc::structures::rmc_struct::read_struct(reader, #version, move |mut reader|{ + Ok(rnex_core::rmc::structures::rmc_struct::read_struct(reader, #version, move |mut reader|{ #deserialize_base_content })?) } @@ -235,7 +235,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { let name = &field.ident; base.append_all(quote!{ - #name: <#ty as rust_nex::rmc::structures::RmcSerialize>::deserialize(reader)?, + #name: <#ty as rnex_core::rmc::structures::RmcSerialize>::deserialize(reader)?, }); } @@ -248,7 +248,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { let ty = &field.ty; base.append_all(quote!{ - <#ty as rust_nex::rmc::structures::RmcSerialize>::deserialize(reader)?, + <#ty as rnex_core::rmc::structures::RmcSerialize>::deserialize(reader)?, }); } @@ -260,7 +260,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { }; let mut se_with_fields = quote! { - <#ty as rust_nex::rmc::structures::RmcSerialize>::serialize(&#val, writer)?; + <#ty as rnex_core::rmc::structures::RmcSerialize>::serialize(&#val, writer)?; }; match &variant.fields { @@ -270,7 +270,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { let name = &field.ident; se_with_fields.append_all(quote!{ - <#ty as rust_nex::rmc::structures::RmcSerialize>::serialize(#name ,writer)?; + <#ty as rnex_core::rmc::structures::RmcSerialize>::serialize(#name ,writer)?; }); } } @@ -281,7 +281,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { let ident = Ident::new(&format!("val_{}", i), Span::call_site()); se_with_fields.append_all(quote!{ - <#ty as rust_nex::rmc::structures::RmcSerialize>::serialize(#ident, writer)?; + <#ty as rnex_core::rmc::structures::RmcSerialize>::serialize(#ident, writer)?; }); } } @@ -344,9 +344,9 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { }; let deserialize_base_content = quote! { - let val: Self = match <#ty as rust_nex::rmc::structures::RmcSerialize>::deserialize(reader)?{ + let val: Self = match <#ty as rnex_core::rmc::structures::RmcSerialize>::deserialize(reader)?{ #inner_match_de - v => return Err(rust_nex::rmc::structures::Error::UnexpectedValue(v as _)) + v => return Err(rnex_core::rmc::structures::Error::UnexpectedValue(v as _)) }; Ok(val) @@ -364,14 +364,14 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { let ident = derive_input.ident; let tokens = quote! { - impl rust_nex::rmc::structures::RmcSerialize for #ident{ - fn serialize(&self, writer: &mut dyn ::std::io::Write) -> rust_nex::rmc::structures::Result<()>{ + impl rnex_core::rmc::structures::RmcSerialize for #ident{ + fn serialize(&self, writer: &mut dyn ::std::io::Write) -> rnex_core::rmc::structures::Result<()>{ #serialize_base_content } - fn deserialize(reader: &mut dyn ::std::io::Read) -> rust_nex::rmc::structures::Result{ + fn deserialize(reader: &mut dyn ::std::io::Read) -> rnex_core::rmc::structures::Result{ #deserialize_base_content } } @@ -511,8 +511,8 @@ pub fn rmc_struct(attr: TokenStream, input: TokenStream) -> TokenStream { } - impl rust_nex::rmc::protocols::RmcCallable for #struct_name{ - async fn rmc_call(&self, remote_response_connection: &rust_nex::util::SendingBufferConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec){ + impl rnex_core::rmc::protocols::RmcCallable for #struct_name{ + async fn rmc_call(&self, remote_response_connection: &rnex_core::util::SendingBufferConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec){ ::rmc_call(self, remote_response_connection, protocol_id, method_id, call_id, rest).await; } } diff --git a/macros/src/protos.rs b/macros/src/protos.rs index fdf8b62..711e931 100644 --- a/macros/src/protos.rs +++ b/macros/src/protos.rs @@ -73,7 +73,7 @@ impl RmcProtocolData{ for (param_name, param_type) in parameters{ quote!{ let Ok(#param_name) = - <#param_type as rust_nex::rmc::structures::RmcSerialize>::deserialize( + <#param_type as rnex_core::rmc::structures::RmcSerialize>::deserialize( &mut cursor ) else }.to_tokens(tokens); @@ -84,7 +84,7 @@ impl RmcProtocolData{ quote! { { log::error!(#error_msg); - return Err(rust_nex::rmc::response::ErrorCode::Core_InvalidArgument); + return Err(rnex_core::rmc::response::ErrorCode::Core_InvalidArgument); }; }.to_tokens(tokens) } else { @@ -116,7 +116,7 @@ impl RmcProtocolData{ quote!{ let retval = retval?; let mut vec = Vec::new(); - rust_nex::rmc::structures::RmcSerialize::serialize(&retval, &mut vec).ok(); + rnex_core::rmc::structures::RmcSerialize::serialize(&retval, &mut vec).ok(); Ok(vec) }.to_tokens(tokens); } @@ -126,7 +126,7 @@ impl RmcProtocolData{ quote!{ async fn rmc_call_proto( &self, - remote_response_connection: &rust_nex::util::SendingBufferConnection, + remote_response_connection: &rnex_core::util::SendingBufferConnection, method_id: u32, call_id: u32, data: Vec, @@ -165,7 +165,7 @@ impl RmcProtocolData{ }.to_tokens(tokens); if self.has_returns { quote! { - Err(rust_nex::rmc::response::ErrorCode::Core_NotImplemented) + Err(rnex_core::rmc::response::ErrorCode::Core_NotImplemented) }.to_tokens(tokens); } }); @@ -176,7 +176,7 @@ impl RmcProtocolData{ if *has_returns{ quote!{ - rust_nex::rmc::response::send_result( + rnex_core::rmc::response::send_result( remote_response_connection, ret, #id, @@ -209,7 +209,7 @@ impl RmcProtocolData{ // boilerplate tokens which all raw traits need quote!{ #[doc(hidden)] - pub trait #remote_name: rust_nex::rmc::protocols::HasRmcConnection + pub trait #remote_name: rnex_core::rmc::protocols::HasRmcConnection }.to_tokens(tokens); // generate the body of the raw protocol trait @@ -247,12 +247,12 @@ impl RmcProtocolData{ for (param_name, param_type) in parameters{ quote!{ - rust_nex::result::ResultExtension::display_err_or_some( - <#param_type as rust_nex::rmc::structures::RmcSerialize>::serialize( + rnex_core::result::ResultExtension::display_err_or_some( + <#param_type as rnex_core::rmc::structures::RmcSerialize>::serialize( &#param_name, &mut cursor ) - ).ok_or(rust_nex::rmc::response::ErrorCode::Core_InvalidArgument) + ).ok_or(rnex_core::rmc::response::ErrorCode::Core_InvalidArgument) }.to_tokens(tokens); if self.has_returns { quote! { @@ -268,25 +268,25 @@ impl RmcProtocolData{ quote!{ let call_id = rand::random(); - let message = rust_nex::rmc::message::RMCMessage{ + let message = rnex_core::rmc::message::RMCMessage{ call_id, method_id: #method_id, protocol_id: #proto_id, rest_of_data: send_data }; - let rmc_conn = ::get_connection(self); + let rmc_conn = ::get_connection(self); }.to_tokens(tokens); if *has_returns{ quote!{ - rust_nex::result::ResultExtension::display_err_or_some( + rnex_core::result::ResultExtension::display_err_or_some( rmc_conn.make_raw_call(&message).await - ).ok_or(rust_nex::rmc::response::ErrorCode::Core_Exception) + ).ok_or(rnex_core::rmc::response::ErrorCode::Core_Exception) }.to_tokens(tokens); } else { quote!{ - rust_nex::result::ResultExtension::display_err_or_some( + rnex_core::result::ResultExtension::display_err_or_some( rmc_conn.make_raw_call_no_response(&message).await ); }.to_tokens(tokens); diff --git a/prudpv1/src/executables/common.rs b/prudpv1/src/executables/common.rs new file mode 100644 index 0000000..e8162a1 --- /dev/null +++ b/prudpv1/src/executables/common.rs @@ -0,0 +1,18 @@ +use std::env; +use std::net::SocketAddrV4; +use once_cell::sync::Lazy; + +pub static EDGE_NODE_HOLDER: Lazy = Lazy::new(||{ + env::var("EDGE_NODE_HOLDER") + .ok() + .and_then(|s| s.parse().ok()) + .expect("EDGE_NODE_HOLDER not set") +}); + +pub static FORWARD_DESTINATION: Lazy = + Lazy::new(|| + env::var("FORWARD_DESTINATION") + .ok() + .and_then(|s| s.parse().ok()) + .expect("FORWARD_DESTINATION not set") + ); diff --git a/src/executables/mod.rs b/prudpv1/src/executables/mod.rs similarity index 100% rename from src/executables/mod.rs rename to prudpv1/src/executables/mod.rs diff --git a/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs similarity index 70% rename from src/executables/proxy_insecure.rs rename to prudpv1/src/executables/proxy_insecure.rs index 1232dc3..3ffe039 100644 --- a/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -1,5 +1,7 @@ -use rust_nex::reggie::RemoteEdgeNodeHolder; +use rnex_core::reggie::UnitPacketRead; +use rnex_core::reggie::UnitPacketWrite; +use rnex_core::rmc::structures::RmcSerialize; use std::env; use std::ffi::CStr; use std::io::{Read, Write}; @@ -7,35 +9,23 @@ use std::net::{Ipv4Addr, SocketAddrV4}; use std::sync::{Arc, OnceLock}; use std::time::Duration; use bytemuck::{Pod, Zeroable}; -use chacha20::{ChaCha20, Key}; -use chacha20::cipher::{Iv, KeyIvInit, StreamCipher}; use log::{error, warn}; -use macros::rmc_struct; use once_cell::sync::Lazy; -use rsa::pkcs8::{DecodePrivateKey, DecodePublicKey, Document}; -use rsa::{BigUint, Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey}; -use rsa::pkcs1::EncodeRsaPublicKey; -use rsa::pss::BlindedSigningKey; -use rsa::signature::{RandomizedSigner, SignatureEncoding}; -use sha2::Sha256; use tokio::net::{TcpSocket, TcpStream}; use tokio::sync::RwLock; use tokio::task; use tokio::time::sleep; -use rust_nex::common::setup; -use rust_nex::executables::common::{FORWARD_DESTINATION, OWN_IP_PRIVATE, OWN_IP_PUBLIC, SECURE_EDGE_NODE_HOLDER, SERVER_PORT}; -use rust_nex::prudp::packet::VirtualPort; -use rust_nex::prudp::router::Router; -use rust_nex::prudp::station_url::StationUrl; -use rust_nex::prudp::unsecure::Unsecure; -use rust_nex::reggie::{UnitPacketRead, UnitPacketWrite}; -use rust_nex::reggie::EdgeNodeHolderConnectOption::{DontRegister, Register}; -use rust_nex::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; -use rust_nex::rmc::response::ErrorCode; -use rust_nex::rmc::structures::RmcSerialize; -use rust_nex::rnex_proxy_common::ConnectionInitData; -use rust_nex::util::SplittableBufferConnection; - +use prudpv1::executables::common::{FORWARD_DESTINATION, EDGE_NODE_HOLDER}; +use prudpv1::prudp::router::Router; +use prudpv1::prudp::unsecure::Unsecure; +use rnex_core::common::setup; +use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT}; +use rnex_core::prudp::virtual_port::VirtualPort; +use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; +use rnex_core::reggie::RemoteEdgeNodeHolder; +use rnex_core::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; +use rnex_core::rnex_proxy_common::ConnectionInitData; +use rnex_core::util::SplittableBufferConnection; @@ -43,7 +33,7 @@ use rust_nex::util::SplittableBufferConnection; async fn main() { setup(); - let conn = tokio::net::TcpStream::connect(&*SECURE_EDGE_NODE_HOLDER).await.unwrap(); + let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER).await.unwrap(); let conn: SplittableBufferConnection = conn.into(); diff --git a/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs similarity index 71% rename from src/executables/proxy_secure.rs rename to prudpv1/src/executables/proxy_secure.rs index 1d554f9..b66fbc2 100644 --- a/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -1,35 +1,37 @@ -use std::net::SocketAddrV4; -use std::sync::Arc; +use rnex_core::reggie::UnitPacketRead; +use rnex_core::reggie::UnitPacketWrite; +use rnex_core::rmc::structures::RmcSerialize; +use std::env; +use std::ffi::CStr; +use std::io::{Read, Write}; +use std::net::{Ipv4Addr, SocketAddrV4}; +use std::sync::{Arc, OnceLock}; use std::time::Duration; -use futures::future::Remote; +use bytemuck::{Pod, Zeroable}; use log::{error, warn}; -use macros::rmc_struct; -use tokio::net::TcpStream; +use once_cell::sync::Lazy; +use tokio::net::{TcpSocket, TcpStream}; use tokio::sync::RwLock; use tokio::task; use tokio::time::sleep; -use tokio_rustls::client::TlsStream; -use tokio_tungstenite::MaybeTlsStream; -use rust_nex::common::setup; -use rust_nex::executables::common::{AUTH_SERVER_ACCOUNT, FORWARD_DESTINATION, OWN_IP_PRIVATE, OWN_IP_PUBLIC, SECURE_EDGE_NODE_HOLDER, SECURE_SERVER_ACCOUNT, SERVER_PORT}; -use rust_nex::prudp::packet::VirtualPort; -use rust_nex::prudp::router::Router; -use rust_nex::prudp::secure::Secure; -use rust_nex::prudp::unsecure::Unsecure; -use rust_nex::reggie::EdgeNodeHolderConnectOption::{DontRegister, Register}; -use rust_nex::rmc::response::ErrorCode; -use rust_nex::rnex_proxy_common::ConnectionInitData; -use rust_nex::reggie::{RemoteEdgeNodeHolder, UnitPacketWrite}; -use rust_nex::rmc::structures::RmcSerialize; -use rust_nex::reggie::UnitPacketRead; -use rust_nex::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote, RemoteInstantiatable}; -use rust_nex::util::SplittableBufferConnection; +use prudpv1::executables::common::{FORWARD_DESTINATION, EDGE_NODE_HOLDER}; +use prudpv1::prudp::router::Router; +use prudpv1::prudp::secure::Secure; +use prudpv1::prudp::unsecure::Unsecure; +use rnex_core::common::setup; +use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SECURE_SERVER_ACCOUNT, SERVER_PORT}; +use rnex_core::prudp::virtual_port::VirtualPort; +use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; +use rnex_core::reggie::RemoteEdgeNodeHolder; +use rnex_core::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; +use rnex_core::rnex_proxy_common::ConnectionInitData; +use rnex_core::util::SplittableBufferConnection; #[tokio::main] async fn main() { setup(); - let conn = tokio::net::TcpStream::connect(&*SECURE_EDGE_NODE_HOLDER).await.unwrap(); + let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER).await.unwrap(); let conn: SplittableBufferConnection = conn.into(); diff --git a/src/prudp/auth_module.rs b/prudpv1/src/prudp/auth_module.rs similarity index 100% rename from src/prudp/auth_module.rs rename to prudpv1/src/prudp/auth_module.rs diff --git a/src/prudp/mod.rs b/prudpv1/src/prudp/mod.rs similarity index 71% rename from src/prudp/mod.rs rename to prudpv1/src/prudp/mod.rs index 966523e..7f237c6 100644 --- a/src/prudp/mod.rs +++ b/prudpv1/src/prudp/mod.rs @@ -2,7 +2,5 @@ pub mod packet; pub mod router; pub mod socket; mod auth_module; -pub mod sockaddr; -pub mod station_url; pub mod secure; pub mod unsecure; \ No newline at end of file diff --git a/src/prudp/packet.rs b/prudpv1/src/prudp/packet.rs similarity index 91% rename from src/prudp/packet.rs rename to prudpv1/src/prudp/packet.rs index b66167c..da376bd 100644 --- a/src/prudp/packet.rs +++ b/prudpv1/src/prudp/packet.rs @@ -12,11 +12,12 @@ use hmac::{Hmac, Mac}; use log::{error, warn}; use md5::{Md5, Digest}; use thiserror::Error; -use v_byte_macros::{SwapEndian}; -use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions}; +use v_byte_helpers::{SwapEndian}; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::prudp::packet::flags::ACK; use crate::prudp::packet::PacketOption::{ConnectionSignature, FragmentId, InitialSequenceId, MaximumSubstreamId, SupportedFunctions}; -use crate::prudp::sockaddr::PRUDPSockAddr; +use rnex_core::prudp::socket_addr::PRUDPSockAddr; +use rnex_core::prudp::virtual_port::VirtualPort; type Md5Hmac = Hmac; @@ -96,51 +97,7 @@ impl Debug for TypesFlags { } } -#[repr(transparent)] -#[derive(PartialEq, Eq, Ord, PartialOrd, Copy, Clone, Pod, Zeroable, SwapEndian, Hash)] -pub struct VirtualPort(pub(crate) u8); -impl VirtualPort { - - #[inline] - pub const fn get_stream_type(self) -> u8 { - (self.0 & 0xF0) >> 4 - } - - #[inline] - pub const fn get_port_number(self) -> u8 { - self.0 & 0x0F - } - - #[inline] - pub fn stream_type(self, val: u8) -> Self { - let masked_val = val & 0x0F; - assert_eq!(masked_val, val); - - Self((self.0 & 0x0F) | (masked_val << 4)) - } - - #[inline] - pub fn port_number(self, val: u8) -> Self { - let masked_val = val & 0x0F; - assert_eq!(masked_val, val); - - Self((self.0 & 0xF0) | masked_val) - } - - #[inline] - pub fn new(port: u8, stream_type: u8) -> Self { - Self(0).stream_type(stream_type).port_number(port) - } -} - -impl Debug for VirtualPort { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let stream_type = self.get_stream_type(); - let port_number = self.get_port_number(); - write!(f, "VirtualPort{{ stream_type: {}, port_number: {} }}", stream_type, port_number) - } -} #[repr(C)] #[derive(Debug, Copy, Clone, Pod, Zeroable, SwapEndian, Eq, PartialEq)] @@ -481,7 +438,8 @@ impl PRUDPV1Packet { mod test { use crate::prudp::packet::flags::{NEED_ACK, RELIABLE}; use crate::prudp::packet::types::DATA; - use super::{OptionId, PacketOption, PRUDPV1Header, TypesFlags, VirtualPort}; + use super::{OptionId, PacketOption, PRUDPV1Header, TypesFlags}; + use rnex_core::prudp::virtual_port::VirtualPort; #[test] fn size_test() { assert_eq!(size_of::(), 14); diff --git a/src/prudp/router.rs b/prudpv1/src/prudp/router.rs similarity index 98% rename from src/prudp/router.rs rename to prudpv1/src/prudp/router.rs index 3aa8bdd..3212155 100644 --- a/src/prudp/router.rs +++ b/prudpv1/src/prudp/router.rs @@ -15,7 +15,8 @@ use tokio::select; use tokio::sync::RwLock; use tokio::time::sleep; use crate::prudp::socket::{new_socket_pair, AnyInternalSocket, CryptoHandler, ExternalSocket}; -use crate::prudp::packet::{PRUDPV1Packet, VirtualPort}; +use crate::prudp::packet::{PRUDPV1Packet}; +use rnex_core::prudp::virtual_port::VirtualPort; use crate::prudp::router::Error::VirtualPortTaken; static SERVER_DATAGRAMS: Lazy = Lazy::new(||{ diff --git a/src/prudp/secure.rs b/prudpv1/src/prudp/secure.rs similarity index 96% rename from src/prudp/secure.rs rename to prudpv1/src/prudp/secure.rs index e0438d7..acf8bfb 100644 --- a/src/prudp/secure.rs +++ b/prudpv1/src/prudp/secure.rs @@ -5,12 +5,12 @@ use rc4::cipher::StreamCipherCoreWrapper; use rc4::{KeyInit, Rc4, Rc4Core, StreamCipher}; use rc4::consts::U16; use typenum::U5; -use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions}; -use crate::kerberos::{derive_key, TicketInternalData}; -use crate::nex::account::Account; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; +use rnex_core::kerberos::{derive_key, TicketInternalData}; +use rnex_core::nex::account::Account; use crate::prudp::packet::PRUDPV1Packet; use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance, EncryptionPair}; -use crate::rmc::structures::RmcSerialize; +use rnex_core::rmc::structures::RmcSerialize; pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 32], u32, u32)>{ let mut cursor = Cursor::new(data); diff --git a/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs similarity index 99% rename from src/prudp/socket.rs rename to prudpv1/src/prudp/socket.rs index 0455bd7..dde9b4d 100644 --- a/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -3,8 +3,9 @@ use crate::prudp::packet::types::{CONNECT, DATA, DISCONNECT, PING, SYN}; use crate::prudp::packet::PacketOption::{ ConnectionSignature, FragmentId, MaximumSubstreamId, SupportedFunctions, }; -use crate::prudp::packet::{PRUDPV1Header, PRUDPV1Packet, TypesFlags, VirtualPort}; -use crate::prudp::sockaddr::PRUDPSockAddr; +use crate::prudp::packet::{PRUDPV1Header, PRUDPV1Packet, TypesFlags}; +use rnex_core::prudp::virtual_port::VirtualPort; +use rnex_core::prudp::socket_addr::PRUDPSockAddr; use async_trait::async_trait; use log::info; use log::error; diff --git a/src/prudp/unsecure.rs b/prudpv1/src/prudp/unsecure.rs similarity index 100% rename from src/prudp/unsecure.rs rename to prudpv1/src/prudp/unsecure.rs diff --git a/src/common.rs b/rnex-core/src/common.rs similarity index 100% rename from src/common.rs rename to rnex-core/src/common.rs diff --git a/src/executables/backend_server_insecure.rs b/rnex-core/src/executables/backend_server_insecure.rs similarity index 70% rename from src/executables/backend_server_insecure.rs rename to rnex-core/src/executables/backend_server_insecure.rs index 4cb8634..005936b 100644 --- a/src/executables/backend_server_insecure.rs +++ b/rnex-core/src/executables/backend_server_insecure.rs @@ -1,4 +1,4 @@ -use rust_nex::reggie::{RemoteEdgeNodeHolder, UnitPacketRead}; +use rnex_core::reggie::{RemoteEdgeNodeHolder, UnitPacketRead}; use log::{error, info}; use once_cell::sync::Lazy; use rustls::client::danger::HandshakeSignatureValid; @@ -10,7 +10,7 @@ use rustls::{ SignatureScheme, }; use rustls_pki_types::PrivateKeyDer; -use rust_nex::common::setup; +use rnex_core::common::setup; use std::borrow::ToOwned; use std::{env, fs}; use std::io::Cursor; @@ -21,28 +21,22 @@ use tokio::io::AsyncReadExt; use tokio::net::{TcpListener, TcpSocket, TcpStream}; use tokio::task; use tokio_rustls::TlsAcceptor; -use rust_nex::define_rmc_proto; -use rust_nex::executables::common::{OWN_IP_PRIVATE, SECURE_EDGE_NODE_HOLDER, SECURE_SERVER_ACCOUNT, SERVER_PORT}; -use rust_nex::nex::auth_handler::AuthHandler; -use rust_nex::reggie::EdgeNodeHolderConnectOption::DontRegister; -use rust_nex::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; -use rust_nex::rmc::response::ErrorCode; -use rust_nex::rmc::structures::RmcSerialize; -use rust_nex::rnex_proxy_common::ConnectionInitData; -use rust_nex::util::SplittableBufferConnection; +use rnex_core::define_rmc_proto; +use rnex_core::executables::common::{OWN_IP_PRIVATE, SECURE_SERVER_ACCOUNT, SERVER_PORT}; +use rnex_core::nex::auth_handler::AuthHandler; +use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister; +use rnex_core::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; +use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::structures::RmcSerialize; +use rnex_core::rnex_proxy_common::ConnectionInitData; +use rnex_core::util::SplittableBufferConnection; -pub static SECURE_PROXY_ADDR: Lazy = Lazy::new(|| { - env::var("SECURE_PROXY_ADDR") + +pub static FORWARD_EDGE_NODE_HOLDER: Lazy = Lazy::new(||{ + env::var("FORWARD_EDGE_NODE_HOLDER") .ok() .and_then(|s| s.parse().ok()) - .expect("no secure proxy ip specified") -}); - -pub static SECURE_PROXY_PORT: Lazy = Lazy::new(|| { - env::var("SECURE_PROXY_PORT") - .ok() - .and_then(|s| s.parse().ok()) - .unwrap_or(10000) + .expect("SECURE_EDGE_NODE_HOLDER not set") }); @@ -51,7 +45,7 @@ pub static SECURE_PROXY_PORT: Lazy = Lazy::new(|| { async fn main() { setup(); - let conn = TcpStream::connect(&*SECURE_EDGE_NODE_HOLDER).await.unwrap(); + let conn = TcpStream::connect(&*FORWARD_EDGE_NODE_HOLDER).await.unwrap(); let conn: SplittableBufferConnection = conn.into(); diff --git a/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs similarity index 74% rename from src/executables/backend_server_secure.rs rename to rnex-core/src/executables/backend_server_secure.rs index 6ada7b8..f758679 100644 --- a/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -1,22 +1,22 @@ use std::io::Cursor; -use rust_nex::rmc::structures::RmcSerialize; -use rust_nex::reggie::{RemoteEdgeNodeHolder, UnitPacketRead}; +use rnex_core::rmc::structures::RmcSerialize; +use rnex_core::reggie::{RemoteEdgeNodeHolder, UnitPacketRead}; use std::net::SocketAddrV4; use std::sync::Arc; use std::sync::atomic::AtomicU32; use log::{error, info}; use tokio::net::{TcpListener, TcpStream}; use tokio::task; -use rust_nex::common::setup; -use rust_nex::executables::common::{OWN_IP_PRIVATE, SECURE_EDGE_NODE_HOLDER, SERVER_PORT}; -use rust_nex::nex::matchmake::MatchmakeManager; -use rust_nex::nex::remote_console::RemoteConsole; -use rust_nex::nex::user::User; -use rust_nex::reggie::EdgeNodeHolderConnectOption::DontRegister; -use rust_nex::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; -use rust_nex::rnex_proxy_common::ConnectionInitData; -use rust_nex::rmc::protocols::RemoteInstantiatable; -use rust_nex::util::SplittableBufferConnection; +use rnex_core::common::setup; +use rnex_core::executables::common::{OWN_IP_PRIVATE, SERVER_PORT}; +use rnex_core::nex::matchmake::MatchmakeManager; +use rnex_core::nex::remote_console::RemoteConsole; +use rnex_core::nex::user::User; +use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister; +use rnex_core::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; +use rnex_core::rnex_proxy_common::ConnectionInitData; +use rnex_core::rmc::protocols::RemoteInstantiatable; +use rnex_core::util::SplittableBufferConnection; #[tokio::main] async fn main() { diff --git a/src/executables/common.rs b/rnex-core/src/executables/common.rs similarity index 69% rename from src/executables/common.rs rename to rnex-core/src/executables/common.rs index 3114436..77bccf7 100644 --- a/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -3,8 +3,8 @@ use std::net::{Ipv4Addr, SocketAddrV4}; use macros::{method_id, rmc_proto, RmcSerialize}; use once_cell::sync::Lazy; use tonic::transport::Server; -use rust_nex::define_rmc_proto; -use rust_nex::prudp::station_url::StationUrl; +use crate::define_rmc_proto; +use crate::prudp::station_url::StationUrl; use crate::nex::account::Account; use crate::rmc::response::ErrorCode; @@ -40,17 +40,5 @@ pub static AUTH_SERVER_ACCOUNT: Lazy = pub static SECURE_SERVER_ACCOUNT: Lazy = Lazy::new(|| Account::new(2, "Quazal Rendez-Vous", &KERBEROS_SERVER_PASSWORD)); -pub static SECURE_EDGE_NODE_HOLDER: Lazy = Lazy::new(||{ - env::var("SECURE_EDGE_NODE_HOLDER") - .ok() - .and_then(|s| s.parse().ok()) - .expect("SECURE_EDGE_NODE_HOLDER not set") -}); -pub static FORWARD_DESTINATION: Lazy = - Lazy::new(|| - env::var("FORWARD_DESTINATION") - .ok() - .and_then(|s| s.parse().ok()) - .expect("FORWARD_DESTINATION not set") - ); + diff --git a/src/executables/edge_node_holder_server.rs b/rnex-core/src/executables/edge_node_holder_server.rs similarity index 85% rename from src/executables/edge_node_holder_server.rs rename to rnex-core/src/executables/edge_node_holder_server.rs index 021dbb1..5146a86 100644 --- a/src/executables/edge_node_holder_server.rs +++ b/rnex-core/src/executables/edge_node_holder_server.rs @@ -5,13 +5,13 @@ use log::error; use macros::rmc_struct; use tokio::net::TcpListener; use tokio::sync::RwLock; -use rust_nex::common::setup; -use rust_nex::executables::common::{OWN_IP_PRIVATE, SERVER_PORT}; -use rust_nex::reggie::{EdgeNodeHolderConnectOption, EdgeNodeManagement, LocalEdgeNodeHolder}; -use rust_nex::rmc::protocols::new_rmc_gateway_connection; -use rust_nex::rmc::response::ErrorCode; -use rust_nex::util::SplittableBufferConnection; -use rust_nex::rmc::structures::RmcSerialize; +use rnex_core::common::setup; +use rnex_core::executables::common::{OWN_IP_PRIVATE, SERVER_PORT}; +use rnex_core::reggie::{EdgeNodeHolderConnectOption, EdgeNodeManagement, LocalEdgeNodeHolder}; +use rnex_core::rmc::protocols::new_rmc_gateway_connection; +use rnex_core::rmc::response::ErrorCode; +use rnex_core::util::SplittableBufferConnection; +use rnex_core::rmc::structures::RmcSerialize; #[rmc_struct(EdgeNodeHolder)] struct EdgeNode{ diff --git a/rnex-core/src/executables/mod.rs b/rnex-core/src/executables/mod.rs new file mode 100644 index 0000000..ffac467 --- /dev/null +++ b/rnex-core/src/executables/mod.rs @@ -0,0 +1 @@ +pub mod common; \ No newline at end of file diff --git a/src/grpc/account.rs b/rnex-core/src/grpc/account.rs similarity index 100% rename from src/grpc/account.rs rename to rnex-core/src/grpc/account.rs diff --git a/src/grpc/mod.rs b/rnex-core/src/grpc/mod.rs similarity index 95% rename from src/grpc/mod.rs rename to rnex-core/src/grpc/mod.rs index 2ca742e..16cb73b 100644 --- a/src/grpc/mod.rs +++ b/rnex-core/src/grpc/mod.rs @@ -5,5 +5,4 @@ use tonic::{Request, Status}; type InterceptorFunc = Box<(dyn Fn(Request<()>) -> Result, Status> + Send)>; -mod protobufs; pub mod account; \ No newline at end of file diff --git a/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs similarity index 98% rename from src/kerberos/mod.rs rename to rnex-core/src/kerberos/mod.rs index a40b816..09dc46c 100644 --- a/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -135,7 +135,7 @@ pub struct Ticket{ } impl Ticket{ - pub(crate) fn encrypt(&self, key: [u8; 16], internal_data: &[u8]) -> Box<[u8]>{ + pub fn encrypt(&self, key: [u8; 16], internal_data: &[u8]) -> Box<[u8]>{ let mut data = bytes_of(self).to_vec(); internal_data.serialize(&mut data).expect("unable to write to vec"); diff --git a/src/lib.rs b/rnex-core/src/lib.rs similarity index 90% rename from src/lib.rs rename to rnex-core/src/lib.rs index 53553c2..21b354a 100644 --- a/src/lib.rs +++ b/rnex-core/src/lib.rs @@ -6,9 +6,8 @@ -extern crate self as rust_nex; +extern crate self as rnex_core; -pub mod endianness; pub mod prudp; pub mod rmc; //mod protocols; @@ -24,3 +23,4 @@ pub mod reggie; pub mod rnex_proxy_common; pub mod util; pub mod executables; +pub use macros::*; diff --git a/src/main.rs b/rnex-core/src/main.rs similarity index 98% rename from src/main.rs rename to rnex-core/src/main.rs index 338b9d3..b3b226b 100644 --- a/src/main.rs +++ b/rnex-core/src/main.rs @@ -14,11 +14,6 @@ use crate::nex::account::Account; use crate::nex::auth_handler::{AuthHandler, RemoteAuthClientProtocol}; use crate::nex::remote_console::RemoteConsole; use crate::nex::user::{RemoteUserProtocol, User}; -use crate::prudp::packet::VirtualPort; -use crate::prudp::router::Router; -use crate::prudp::secure::Secure; -use crate::prudp::sockaddr::PRUDPSockAddr; -use crate::prudp::unsecure::Unsecure; use crate::rmc::protocols::auth::Auth; use crate::rmc::protocols::auth::RawAuth; use crate::rmc::protocols::auth::RawAuthInfo; @@ -51,7 +46,6 @@ use crate::kerberos::KerberosDateTime; use crate::nex::matchmake::MatchmakeManager; use crate::rmc::protocols::secure::RemoteSecure; -mod endianness; mod prudp; pub mod rmc; //mod protocols; diff --git a/src/nex/account.rs b/rnex-core/src/nex/account.rs similarity index 100% rename from src/nex/account.rs rename to rnex-core/src/nex/account.rs diff --git a/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs similarity index 89% rename from src/nex/auth_handler.rs rename to rnex-core/src/nex/auth_handler.rs index ca7f970..134c1bc 100644 --- a/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -2,18 +2,18 @@ use std::hash::{DefaultHasher, Hasher}; use std::net::SocketAddrV4; use std::sync::Arc; use crate::grpc::account; -use crate::kerberos::{derive_key, KerberosDateTime, Ticket}; -use crate::nex::account::Account; -use crate::rmc::protocols::auth::{Auth, RawAuth, RawAuthInfo, RemoteAuth}; -use crate::rmc::response::ErrorCode; -use crate::rmc::response::ErrorCode::Core_Unknown; -use crate::rmc::structures::any::Any; -use crate::rmc::structures::connection_data::ConnectionData; -use crate::rmc::structures::qresult::QResult; +use rnex_core::kerberos::{derive_key, KerberosDateTime, Ticket}; +use rnex_core::nex::account::Account; +use rnex_core::rmc::protocols::auth::{Auth, RawAuth, RawAuthInfo, RemoteAuth}; +use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::response::ErrorCode::Core_Unknown; +use rnex_core::rmc::structures::any::Any; +use rnex_core::rmc::structures::connection_data::ConnectionData; +use rnex_core::rmc::structures::qresult::QResult; use crate::{define_rmc_proto, kerberos}; use macros::rmc_struct; use crate::reggie::{RemoteEdgeNodeHolder, RemoteEdgeNodeManagement}; -use crate::rmc::protocols::OnlyRemote; +use rnex_core::rmc::protocols::OnlyRemote; define_rmc_proto!( proto AuthClientProtocol{ @@ -157,10 +157,10 @@ impl Auth for AuthHandler { #[cfg(test)] mod test { - use crate::rmc::structures::connection_data::ConnectionData; - use crate::rmc::structures::qresult::QResult; - use crate::rmc::structures::RmcSerialize; - use crate::rmc::response::RMCResponse; + use rnex_core::rmc::structures::connection_data::ConnectionData; + use rnex_core::rmc::structures::qresult::QResult; + use rnex_core::rmc::structures::RmcSerialize; + use rnex_core::rmc::response::RMCResponse; use std::io::Cursor; #[test] @@ -169,7 +169,7 @@ mod test { let stuff = hex::decode("200100000a0106000000028000000100010051b3995774000000a6321c7f78847c1c5e9fb825eb26bd91841f1a40d92fc694159666119cb13527f1463ac48ad42a63e6613ede67041554b1770978112e6f1f3e177a2bfc75933216dbe38f70133a1eb28e2ae32a4b5c4b0c3e3efd4c02907992e259b257270b57a9dbe7792f4721b07f8fafb9e32d50f2555c616a015c0000004b007072756470733a2f5049443d323b7369643d313b73747265616d3d31303b747970653d323b616464726573733d322e3234332e39352e3131333b706f72743d31303030313b4349443d3100000000000100002c153ba51f00000033006272616e63683a6f726967696e2f70726f6a6563742f7775702d61676d6a206275696c643a335f385f31355f323030345f3000").unwrap(); let stuff = RMCResponse::new(&mut Cursor::new(stuff)).unwrap(); - let crate::rmc::response::RMCResponseResult::Success { call_id, method_id, data: stuff} = stuff.response_result else { + let rnex_core::rmc::response::RMCResponseResult::Success { call_id, method_id, data: stuff} = stuff.response_result else { panic!() }; diff --git a/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs similarity index 95% rename from src/nex/matchmake.rs rename to rnex-core/src/nex/matchmake.rs index c01c9a7..1f4f61a 100644 --- a/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -8,15 +8,15 @@ use log::info; use rand::random; use tokio::sync::{Mutex, RwLock}; use tokio::time::sleep; -use crate::kerberos::KerberosDateTime; +use rnex_core::kerberos::KerberosDateTime; use crate::nex::user::User; use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; -use crate::rmc::protocols::notifications::notification_types::{HOST_CHANGED, OWNERSHIP_CHANGED}; -use crate::rmc::response::ErrorCode; -use crate::rmc::response::ErrorCode::{Core_InvalidArgument, RendezVous_SessionVoid}; -use crate::rmc::structures::matchmake::{Gathering, MatchmakeParam, MatchmakeSession, MatchmakeSessionSearchCriteria}; -use crate::rmc::structures::matchmake::gathering_flags::PERSISTENT_GATHERING; -use crate::rmc::structures::variant::Variant; +use rnex_core::rmc::protocols::notifications::notification_types::{HOST_CHANGED, OWNERSHIP_CHANGED}; +use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::response::ErrorCode::{Core_InvalidArgument, RendezVous_SessionVoid}; +use rnex_core::rmc::structures::matchmake::{Gathering, MatchmakeParam, MatchmakeSession, MatchmakeSessionSearchCriteria}; +use rnex_core::rmc::structures::matchmake::gathering_flags::PERSISTENT_GATHERING; +use rnex_core::rmc::structures::variant::Variant; pub struct MatchmakeManager{ pub gid_counter: AtomicU32, diff --git a/src/nex/mod.rs b/rnex-core/src/nex/mod.rs similarity index 100% rename from src/nex/mod.rs rename to rnex-core/src/nex/mod.rs diff --git a/src/nex/remote_console.rs b/rnex-core/src/nex/remote_console.rs similarity index 100% rename from src/nex/remote_console.rs rename to rnex-core/src/nex/remote_console.rs diff --git a/src/nex/user.rs b/rnex-core/src/nex/user.rs similarity index 95% rename from src/nex/user.rs rename to rnex-core/src/nex/user.rs index d77c289..dd30cb4 100644 --- a/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -1,33 +1,33 @@ use crate::define_rmc_proto; use crate::nex::matchmake::{ExtendedMatchmakeSession, MatchmakeManager}; use crate::nex::remote_console::RemoteConsole; -use crate::prudp::sockaddr::PRUDPSockAddr; -use crate::prudp::station_url::UrlOptions::{ +use rnex_core::prudp::station_url::StationUrl; +use rnex_core::prudp::station_url::UrlOptions::{ Address, NatFiltering, NatMapping, NatType, Port, PrincipalID, RVConnectionID, }; -use crate::prudp::station_url::{StationUrl}; use crate::rmc::protocols::matchmake::{ Matchmake, RawMatchmake, RawMatchmakeInfo, RemoteMatchmake, }; -use crate::rmc::protocols::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking}; -use crate::rmc::protocols::matchmake_extension::{ +use rnex_core::rmc::protocols::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking}; +use rnex_core::rmc::protocols::matchmake_extension::{ MatchmakeExtension, RawMatchmakeExtension, RawMatchmakeExtensionInfo, RemoteMatchmakeExtension, }; use crate::rmc::protocols::nat_traversal::{NatTraversal, RawNatTraversal, RawNatTraversalInfo, RemoteNatTraversal, RemoteNatTraversalConsole}; -use crate::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; -use crate::rmc::protocols::matchmake_ext::{MatchmakeExt, RawMatchmakeExt, RawMatchmakeExtInfo, RemoteMatchmakeExt}; -use crate::rmc::response::ErrorCode; -use crate::rmc::structures::matchmake::{AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession}; +use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; +use rnex_core::rmc::protocols::matchmake_ext::{MatchmakeExt, RawMatchmakeExt, RawMatchmakeExtInfo, RemoteMatchmakeExt}; +use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession}; -use crate::rmc::structures::qresult::QResult; +use rnex_core::rmc::structures::qresult::QResult; use macros::rmc_struct; use std::sync::{Arc, Weak}; use log::info; use tokio::sync::{Mutex, RwLock}; -use crate::prudp::station_url::nat_types::PUBLIC; +use rnex_core::prudp::socket_addr::PRUDPSockAddr; +use rnex_core::prudp::station_url::nat_types::PUBLIC; use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; -use crate::rmc::response::ErrorCode::{Core_Exception, Core_InvalidArgument, RendezVous_AccountExpired}; +use rnex_core::rmc::response::ErrorCode::{Core_Exception, Core_InvalidArgument, RendezVous_AccountExpired}; define_rmc_proto!( proto UserProtocol{ diff --git a/rnex-core/src/prudp/mod.rs b/rnex-core/src/prudp/mod.rs new file mode 100644 index 0000000..093723d --- /dev/null +++ b/rnex-core/src/prudp/mod.rs @@ -0,0 +1,3 @@ +pub mod virtual_port; +pub mod station_url; +pub mod socket_addr; \ No newline at end of file diff --git a/src/prudp/sockaddr.rs b/rnex-core/src/prudp/socket_addr.rs similarity index 85% rename from src/prudp/sockaddr.rs rename to rnex-core/src/prudp/socket_addr.rs index 4e42fcc..f3ea10c 100644 --- a/src/prudp/sockaddr.rs +++ b/rnex-core/src/prudp/socket_addr.rs @@ -1,8 +1,9 @@ use std::io::Write; use std::net::SocketAddrV4; -use hmac::{Hmac, Mac}; +use hmac::{Hmac}; +use md5::digest::Mac; use macros::RmcSerialize; -use crate::prudp::packet::VirtualPort; +use rnex_core::prudp::virtual_port::VirtualPort; type Md5Hmac = Hmac; @@ -24,7 +25,7 @@ impl PRUDPSockAddr{ } } - pub(super) fn calculate_connection_signature(&self) -> [u8; 16] { + pub fn calculate_connection_signature(&self) -> [u8; 16] { let mut hmac = Md5Hmac::new_from_slice(&[0; 16]).expect("fuck"); let mut data = self.regular_socket_addr.ip().octets().to_vec(); diff --git a/src/prudp/station_url.rs b/rnex-core/src/prudp/station_url.rs similarity index 99% rename from src/prudp/station_url.rs rename to rnex-core/src/prudp/station_url.rs index 441c1b3..b2f70bb 100644 --- a/src/prudp/station_url.rs +++ b/rnex-core/src/prudp/station_url.rs @@ -111,7 +111,7 @@ impl StationUrl{ impl TryFrom<&str> for StationUrl{ type Error = (); - + fn try_from(value: &str) -> Result { let (url_type, options) = value.split_at(value.find(":/").ok_or(())?); diff --git a/rnex-core/src/prudp/virtual_port.rs b/rnex-core/src/prudp/virtual_port.rs new file mode 100644 index 0000000..54d2eeb --- /dev/null +++ b/rnex-core/src/prudp/virtual_port.rs @@ -0,0 +1,49 @@ +use std::fmt::{Debug, Formatter}; +use bytemuck::{Pod, Zeroable}; +use v_byte_helpers::SwapEndian; + +#[repr(transparent)] +#[derive(PartialEq, Eq, Ord, PartialOrd, Copy, Clone, Pod, Zeroable, SwapEndian, Hash, Default)] +pub struct VirtualPort(pub u8); + +impl VirtualPort { + + #[inline] + pub const fn get_stream_type(self) -> u8 { + (self.0 & 0xF0) >> 4 + } + + #[inline] + pub const fn get_port_number(self) -> u8 { + self.0 & 0x0F + } + + #[inline] + pub fn stream_type(self, val: u8) -> Self { + let masked_val = val & 0x0F; + assert_eq!(masked_val, val); + + Self((self.0 & 0x0F) | (masked_val << 4)) + } + + #[inline] + pub fn port_number(self, val: u8) -> Self { + let masked_val = val & 0x0F; + assert_eq!(masked_val, val); + + Self((self.0 & 0xF0) | masked_val) + } + + #[inline] + pub fn new(port: u8, stream_type: u8) -> Self { + Self(0).stream_type(stream_type).port_number(port) + } +} + +impl Debug for VirtualPort { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let stream_type = self.get_stream_type(); + let port_number = self.get_port_number(); + write!(f, "VirtualPort{{ stream_type: {}, port_number: {} }}", stream_type, port_number) + } +} \ No newline at end of file diff --git a/src/reggie.rs b/rnex-core/src/reggie.rs similarity index 97% rename from src/reggie.rs rename to rnex-core/src/reggie.rs index f57ebb0..b3d73c9 100644 --- a/src/reggie.rs +++ b/rnex-core/src/reggie.rs @@ -20,11 +20,11 @@ use tokio_rustls::client::TlsStream; use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; use tokio_tungstenite::tungstenite::Message; use webpki::anchor_from_trusted_cert; -use rust_nex::common::setup; +use crate::common::setup; use crate::define_rmc_proto; use crate::nex::account::Account; use crate::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote, RmcCallable, RmcConnection}; -use crate::rmc::response::ErrorCode; +use rnex_core::rmc::response::ErrorCode; use crate::rmc::structures::RmcSerialize; pub trait UnitPacketRead: AsyncRead + Unpin{ diff --git a/src/result.rs b/rnex-core/src/result.rs similarity index 100% rename from src/result.rs rename to rnex-core/src/result.rs diff --git a/src/rmc/message.rs b/rnex-core/src/rmc/message.rs similarity index 97% rename from src/rmc/message.rs rename to rnex-core/src/rmc/message.rs index f45b585..cf951bf 100644 --- a/src/rmc/message.rs +++ b/rnex-core/src/rmc/message.rs @@ -2,7 +2,7 @@ use std::io; use std::io::{Read, Seek, Write}; use bytemuck::bytes_of; use log::error; -use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions}; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::rmc::response::{ErrorCode, RMCResponseResult}; #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/src/rmc/mod.rs b/rnex-core/src/rmc/mod.rs similarity index 100% rename from src/rmc/mod.rs rename to rnex-core/src/rmc/mod.rs diff --git a/src/rmc/protocols/auth.rs b/rnex-core/src/rmc/protocols/auth.rs similarity index 93% rename from src/rmc/protocols/auth.rs rename to rnex-core/src/rmc/protocols/auth.rs index ed8d1cd..49feb2b 100644 --- a/src/rmc/protocols/auth.rs +++ b/rnex-core/src/rmc/protocols/auth.rs @@ -1,7 +1,7 @@ -use crate::rmc::response::ErrorCode; -use crate::rmc::structures::any::Any; +use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::structures::any::Any; use crate::rmc::structures::connection_data::ConnectionData; -use crate::rmc::structures::qresult::QResult; +use rnex_core::rmc::structures::qresult::QResult; use macros::{method_id, rmc_proto}; diff --git a/src/rmc/protocols/matchmake.rs b/rnex-core/src/rmc/protocols/matchmake.rs similarity index 86% rename from src/rmc/protocols/matchmake.rs rename to rnex-core/src/rmc/protocols/matchmake.rs index 1c2d5e5..24942c0 100644 --- a/src/rmc/protocols/matchmake.rs +++ b/rnex-core/src/rmc/protocols/matchmake.rs @@ -1,6 +1,6 @@ use macros::{method_id, rmc_proto}; -use crate::prudp::station_url::StationUrl; -use crate::rmc::response::ErrorCode; +use rnex_core::prudp::station_url::StationUrl; +use rnex_core::rmc::response::ErrorCode; #[rmc_proto(21)] pub trait Matchmake{ diff --git a/src/rmc/protocols/matchmake_ext.rs b/rnex-core/src/rmc/protocols/matchmake_ext.rs similarity index 82% rename from src/rmc/protocols/matchmake_ext.rs rename to rnex-core/src/rmc/protocols/matchmake_ext.rs index b795d3d..46c1c09 100644 --- a/src/rmc/protocols/matchmake_ext.rs +++ b/rnex-core/src/rmc/protocols/matchmake_ext.rs @@ -1,5 +1,5 @@ use macros::{method_id, rmc_proto}; -use crate::rmc::response::ErrorCode; +use rnex_core::rmc::response::ErrorCode; #[rmc_proto(50)] pub trait MatchmakeExt{ diff --git a/src/rmc/protocols/matchmake_extension.rs b/rnex-core/src/rmc/protocols/matchmake_extension.rs similarity index 87% rename from src/rmc/protocols/matchmake_extension.rs rename to rnex-core/src/rmc/protocols/matchmake_extension.rs index cd3f281..fff5252 100644 --- a/src/rmc/protocols/matchmake_extension.rs +++ b/rnex-core/src/rmc/protocols/matchmake_extension.rs @@ -1,6 +1,6 @@ use macros::{method_id, rmc_proto}; -use crate::rmc::response::ErrorCode; -use crate::rmc::structures::matchmake::{AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession}; +use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession}; #[rmc_proto(109)] pub trait MatchmakeExtension{ diff --git a/src/rmc/protocols/mod.rs b/rnex-core/src/rmc/protocols/mod.rs similarity index 94% rename from src/rmc/protocols/mod.rs rename to rnex-core/src/rmc/protocols/mod.rs index b206b44..7ad8e8c 100644 --- a/src/rmc/protocols/mod.rs +++ b/rnex-core/src/rmc/protocols/mod.rs @@ -154,7 +154,7 @@ macro_rules! define_rmc_proto { }) => { paste::paste!{ pub trait []: std::any::Any $( + [] + $protocol)* { - async fn rmc_call(&self, remote_response_connection: &rust_nex::util::SendingBufferConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec){ + async fn rmc_call(&self, remote_response_connection: &rnex_core::util::SendingBufferConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec){ match protocol_id{ $( []::PROTOCOL_ID => ]>::rmc_call_proto(self, remote_response_connection, method_id, call_id, rest).await, @@ -164,10 +164,10 @@ macro_rules! define_rmc_proto { } } - pub struct [](rust_nex::rmc::protocols::RmcConnection); + pub struct [](rnex_core::rmc::protocols::RmcConnection); - impl rust_nex::rmc::protocols::RemoteInstantiatable for []{ - fn new(conn: rust_nex::rmc::protocols::RmcConnection) -> Self{ + impl rnex_core::rmc::protocols::RemoteInstantiatable for []{ + fn new(conn: rnex_core::rmc::protocols::RmcConnection) -> Self{ Self(conn) } async fn disconnect(&self){ @@ -175,8 +175,8 @@ macro_rules! define_rmc_proto { } } - impl rust_nex::rmc::protocols::HasRmcConnection for []{ - fn get_connection(&self) -> &rust_nex::rmc::protocols::RmcConnection{ + impl rnex_core::rmc::protocols::HasRmcConnection for []{ + fn get_connection(&self) -> &rnex_core::rmc::protocols::RmcConnection{ &self.0 } } diff --git a/src/rmc/protocols/nat_traversal.rs b/rnex-core/src/rmc/protocols/nat_traversal.rs similarity index 94% rename from src/rmc/protocols/nat_traversal.rs rename to rnex-core/src/rmc/protocols/nat_traversal.rs index 222e62c..c0862a8 100644 --- a/src/rmc/protocols/nat_traversal.rs +++ b/rnex-core/src/rmc/protocols/nat_traversal.rs @@ -1,5 +1,5 @@ use macros::{method_id, rmc_proto}; -use crate::rmc::response::ErrorCode; +use rnex_core::rmc::response::ErrorCode; #[rmc_proto(3)] pub trait NatTraversal{ diff --git a/src/rmc/protocols/notifications.rs b/rnex-core/src/rmc/protocols/notifications.rs similarity index 100% rename from src/rmc/protocols/notifications.rs rename to rnex-core/src/rmc/protocols/notifications.rs diff --git a/src/rmc/protocols/ranking.rs b/rnex-core/src/rmc/protocols/ranking.rs similarity index 100% rename from src/rmc/protocols/ranking.rs rename to rnex-core/src/rmc/protocols/ranking.rs diff --git a/src/rmc/protocols/secure.rs b/rnex-core/src/rmc/protocols/secure.rs similarity index 69% rename from src/rmc/protocols/secure.rs rename to rnex-core/src/rmc/protocols/secure.rs index 3071c3a..50afb5b 100644 --- a/src/rmc/protocols/secure.rs +++ b/rnex-core/src/rmc/protocols/secure.rs @@ -1,7 +1,7 @@ use macros::{method_id, rmc_proto}; -use crate::prudp::station_url::StationUrl; -use crate::rmc::response::ErrorCode; -use crate::rmc::structures::qresult::QResult; +use rnex_core::prudp::station_url::StationUrl; +use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::structures::qresult::QResult; #[rmc_proto(11)] pub trait Secure { diff --git a/src/rmc/response.rs b/rnex-core/src/rmc/response.rs similarity index 99% rename from src/rmc/response.rs rename to rnex-core/src/rmc/response.rs index dcdebc6..a732853 100644 --- a/src/rmc/response.rs +++ b/rnex-core/src/rmc/response.rs @@ -7,8 +7,8 @@ use std::io::{Read, Seek, Write}; use std::mem::transmute; use bytemuck::bytes_of; use log::error; -use v_byte_macros::EnumTryInto; -use crate::endianness::{ReadExtensions, IS_BIG_ENDIAN}; +use v_byte_helpers::EnumTryInto; +use v_byte_helpers::{ReadExtensions, IS_BIG_ENDIAN}; use crate::rmc::response::ErrorCode::Core_Exception; use crate::rmc::structures::qresult::ERROR_MASK; use crate::util::SendingBufferConnection; diff --git a/src/rmc/structures/any.rs b/rnex-core/src/rmc/structures/any.rs similarity index 94% rename from src/rmc/structures/any.rs rename to rnex-core/src/rmc/structures/any.rs index d402f3e..c1e68a4 100644 --- a/src/rmc/structures/any.rs +++ b/rnex-core/src/rmc/structures/any.rs @@ -1,5 +1,5 @@ use std::io::{Read, Write}; -use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions}; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use super::{Result, RmcSerialize}; #[derive(Debug, Default)] diff --git a/src/rmc/structures/buffer.rs b/rnex-core/src/rmc/structures/buffer.rs similarity index 100% rename from src/rmc/structures/buffer.rs rename to rnex-core/src/rmc/structures/buffer.rs diff --git a/src/rmc/structures/connection_data.rs b/rnex-core/src/rmc/structures/connection_data.rs similarity index 75% rename from src/rmc/structures/connection_data.rs rename to rnex-core/src/rmc/structures/connection_data.rs index a949d91..da6a17b 100644 --- a/src/rmc/structures/connection_data.rs +++ b/rnex-core/src/rmc/structures/connection_data.rs @@ -1,7 +1,6 @@ use macros::RmcSerialize; -use crate::kerberos::KerberosDateTime; -use crate::rmc::structures::RmcSerialize; +use rnex_core::kerberos::KerberosDateTime; #[derive(Debug, RmcSerialize)] #[rmc_struct(1)] diff --git a/src/rmc/structures/list.rs b/rnex-core/src/rmc/structures/list.rs similarity index 96% rename from src/rmc/structures/list.rs rename to rnex-core/src/rmc/structures/list.rs index 870be65..1ebb60b 100644 --- a/src/rmc/structures/list.rs +++ b/rnex-core/src/rmc/structures/list.rs @@ -3,7 +3,7 @@ use std::io::{Read, Write}; use std::mem::MaybeUninit; use bytemuck::bytes_of; use serde::Serialize; -use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions}; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::rmc::structures::RmcSerialize; diff --git a/src/rmc/structures/matchmake.rs b/rnex-core/src/rmc/structures/matchmake.rs similarity index 97% rename from src/rmc/structures/matchmake.rs rename to rnex-core/src/rmc/structures/matchmake.rs index 28e851b..9194b97 100644 --- a/src/rmc/structures/matchmake.rs +++ b/rnex-core/src/rmc/structures/matchmake.rs @@ -1,5 +1,5 @@ -use crate::kerberos::KerberosDateTime; -use crate::rmc::structures::variant::Variant; +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::rmc::structures::variant::Variant; use macros::RmcSerialize; // rmc structure diff --git a/src/rmc/structures/mod.rs b/rnex-core/src/rmc/structures/mod.rs similarity index 100% rename from src/rmc/structures/mod.rs rename to rnex-core/src/rmc/structures/mod.rs diff --git a/src/rmc/structures/networking.rs b/rnex-core/src/rmc/structures/networking.rs similarity index 94% rename from src/rmc/structures/networking.rs rename to rnex-core/src/rmc/structures/networking.rs index 9a11c5a..824a442 100644 --- a/src/rmc/structures/networking.rs +++ b/rnex-core/src/rmc/structures/networking.rs @@ -1,6 +1,6 @@ use std::io::{Read, Write}; use std::net::{Ipv4Addr, SocketAddrV4}; -use crate::prudp::packet::VirtualPort; +use rnex_core::prudp::virtual_port::VirtualPort; use crate::rmc::structures::RmcSerialize; impl RmcSerialize for SocketAddrV4{ diff --git a/src/rmc/structures/primitives.rs b/rnex-core/src/rmc/structures/primitives.rs similarity index 99% rename from src/rmc/structures/primitives.rs rename to rnex-core/src/rmc/structures/primitives.rs index a834d9a..73985ed 100644 --- a/src/rmc/structures/primitives.rs +++ b/rnex-core/src/rmc/structures/primitives.rs @@ -1,6 +1,6 @@ use std::io::{Read, Write}; use bytemuck::bytes_of; -use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions}; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::rmc::structures::RmcSerialize; impl RmcSerialize for u8{ diff --git a/src/rmc/structures/qbuffer.rs b/rnex-core/src/rmc/structures/qbuffer.rs similarity index 91% rename from src/rmc/structures/qbuffer.rs rename to rnex-core/src/rmc/structures/qbuffer.rs index bb6c235..8fbfd5e 100644 --- a/src/rmc/structures/qbuffer.rs +++ b/rnex-core/src/rmc/structures/qbuffer.rs @@ -1,6 +1,6 @@ use std::io::{Read, Write}; use bytemuck::bytes_of; -use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions}; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::rmc::structures::{Result, RmcSerialize}; diff --git a/src/rmc/structures/qresult.rs b/rnex-core/src/rmc/structures/qresult.rs similarity index 90% rename from src/rmc/structures/qresult.rs rename to rnex-core/src/rmc/structures/qresult.rs index 41a5263..77ad70e 100644 --- a/src/rmc/structures/qresult.rs +++ b/rnex-core/src/rmc/structures/qresult.rs @@ -1,7 +1,7 @@ use std::io::{Read, Write}; use bytemuck::{bytes_of, Pod, Zeroable}; -use v_byte_macros::SwapEndian; -use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions}; +use v_byte_helpers::SwapEndian; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::rmc::response::ErrorCode; use crate::rmc::structures::{RmcSerialize, Result}; diff --git a/src/rmc/structures/ranking.rs b/rnex-core/src/rmc/structures/ranking.rs similarity index 96% rename from src/rmc/structures/ranking.rs rename to rnex-core/src/rmc/structures/ranking.rs index c912d3f..afb0698 100644 --- a/src/rmc/structures/ranking.rs +++ b/rnex-core/src/rmc/structures/ranking.rs @@ -1,6 +1,6 @@ use bytemuck::{Pod, Zeroable}; use macros::RmcSerialize; -use crate::rmc::structures::qbuffer::QBuffer; +use rnex_core::rmc::structures::qbuffer::QBuffer; #[derive(RmcSerialize, Debug)] #[rmc_struct(0)] @@ -27,7 +27,7 @@ mod test{ use bytemuck::from_bytes; use tokio::io::AsyncReadExt; use crate::rmc::structures::ranking::{UploadCompetitionData, UserData}; - use crate::rmc::structures::RmcSerialize; + use rnex_core::rmc::structures::RmcSerialize; #[test] fn test() { diff --git a/src/rmc/structures/rmc_struct.rs b/rnex-core/src/rmc/structures/rmc_struct.rs similarity index 95% rename from src/rmc/structures/rmc_struct.rs rename to rnex-core/src/rmc/structures/rmc_struct.rs index 8f51a5a..071cfdb 100644 --- a/src/rmc/structures/rmc_struct.rs +++ b/rnex-core/src/rmc/structures/rmc_struct.rs @@ -1,6 +1,6 @@ use std::io::{Cursor, Read, Write}; use bytemuck::bytes_of; -use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions}; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::rmc::structures::Error::VersionMismatch; use crate::rmc::structures::Result; diff --git a/src/rmc/structures/string.rs b/rnex-core/src/rmc/structures/string.rs similarity index 94% rename from src/rmc/structures/string.rs rename to rnex-core/src/rmc/structures/string.rs index 690e6a1..d25bc81 100644 --- a/src/rmc/structures/string.rs +++ b/rnex-core/src/rmc/structures/string.rs @@ -1,7 +1,7 @@ use std::io::{Read, Write}; use bytemuck::bytes_of; use log::error; -use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions}; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use super::{Result, RmcSerialize}; impl RmcSerialize for String{ diff --git a/src/rmc/structures/variant.rs b/rnex-core/src/rmc/structures/variant.rs similarity index 100% rename from src/rmc/structures/variant.rs rename to rnex-core/src/rmc/structures/variant.rs diff --git a/src/rnex_proxy_common.rs b/rnex-core/src/rnex_proxy_common.rs similarity index 78% rename from src/rnex_proxy_common.rs rename to rnex-core/src/rnex_proxy_common.rs index c300aa0..29cb161 100644 --- a/src/rnex_proxy_common.rs +++ b/rnex-core/src/rnex_proxy_common.rs @@ -1,5 +1,5 @@ use macros::RmcSerialize; -use crate::prudp::sockaddr::PRUDPSockAddr; +use crate::prudp::socket_addr::PRUDPSockAddr; #[derive(Debug, RmcSerialize)] #[rmc_struct(0)] diff --git a/src/util.rs b/rnex-core/src/util.rs similarity index 98% rename from src/util.rs rename to rnex-core/src/util.rs index 04c8400..b052fe2 100644 --- a/src/util.rs +++ b/rnex-core/src/util.rs @@ -5,7 +5,7 @@ use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio::sync::Notify; use tokio::task; -use rust_nex::reggie::{UnitPacketRead, UnitPacketWrite}; +use crate::reggie::{UnitPacketRead, UnitPacketWrite}; #[derive(Clone)] pub struct SendingBufferConnection(Sender>, Arc); diff --git a/src/versions.rs b/rnex-core/src/versions.rs similarity index 100% rename from src/versions.rs rename to rnex-core/src/versions.rs diff --git a/src/web/mod.rs b/rnex-core/src/web/mod.rs similarity index 100% rename from src/web/mod.rs rename to rnex-core/src/web/mod.rs diff --git a/src/endianness.rs b/src/endianness.rs deleted file mode 100644 index 160b1a1..0000000 --- a/src/endianness.rs +++ /dev/null @@ -1,230 +0,0 @@ -use std::{io, mem}; -use std::io::Read; -use std::marker::PhantomData; -use bytemuck::Pod; - -#[cfg(target_endian = "little")] -pub const IS_LITTLE_ENDIAN: bool = true; - -#[cfg(target_endian = "big")] -pub const IS_LITTLE_ENDIAN: bool = false; - -pub const IS_BIG_ENDIAN: bool = !IS_LITTLE_ENDIAN; - -pub mod little_endian{ - use std::io; - use std::io::Read; - - #[inline] - pub fn read_u16(reader: &mut (impl Read + ?Sized)) -> io::Result{ - let mut data = [0u8; 2]; - - reader.read_exact(&mut data)?; - - Ok(((data[0] as u16) << 8) | (data[1] as u16)) - } - - #[inline] - pub fn read_u32(reader: &mut (impl Read + ?Sized)) -> io::Result{ - let mut data = [0u8; 4]; - - reader.read_exact(&mut data)?; - - Ok( - ((data[0] as u32) << 24) | - ((data[1] as u32) << 16) | - ((data[2] as u32) << 8) | - (data[3] as u32) - ) - } -} - -pub struct StructMultiReadIter<'a, T: Pod + SwapEndian>{ - reader: &'a mut dyn Read, - left_to_read: usize, - swap_endian: bool, - _phantom_data: PhantomData<&'static T> -} - -impl<'a, T: Pod + SwapEndian> Iterator for StructMultiReadIter<'a, T>{ - type Item = io::Result; - - #[inline] - fn next(&mut self) -> Option { - if self.left_to_read == 0{ - None - } else { - Some(self.reader.read_struct(self.swap_endian)) - } - } -} - -impl<'a, T: Pod + SwapEndian> Drop for StructMultiReadIter<'a, T>{ - #[inline] - fn drop(&mut self) { - - // read all the structs we would be reading and discard them to make the result after using - // this always be the same - while let Some(_) = self.next() { } - } -} - - - - -pub trait ReadExtensions: Read{ - #[inline] - fn read_le_u16(&mut self) -> io::Result{ - little_endian::read_u16(self) - } - - #[inline] - fn read_le_u32(&mut self) -> io::Result{ - little_endian::read_u32(self) - } - - #[inline] - fn read_le_struct(&mut self) -> io::Result{ - let mut data = T::zeroed(); - let bytes = bytemuck::bytes_of_mut(&mut data); - - self.read_exact(bytes)?; - - if cfg!(not(target_endian = "little")){ - data = data.swap_endian(); - } - - Ok(data) - } - - #[inline] - fn read_struct(&mut self, swap_endian: bool) -> io::Result{ - let mut data = T::zeroed(); - let bytes = bytemuck::bytes_of_mut(&mut data); - - self.read_exact(bytes)?; - - if swap_endian{ - data = data.swap_endian(); - } - - Ok(data) - } - - - fn read_struct_multi(&mut self, swap_endian: bool, count: usize) -> io::Result>; -} - -impl ReadExtensions for T{ - // i was forced to put this here because it requires info about self - #[inline] - fn read_struct_multi(&mut self, swap_endian: bool, count: usize) -> io::Result>{ - Ok(StructMultiReadIter{ - reader: self, - swap_endian, - left_to_read: count, - _phantom_data: Default::default() - }) - } -} - - - - -pub trait SwapEndian: Clone + Copy{ - fn swap_endian(self) -> Self; -} - -impl SwapEndian for u8{ - #[inline] - fn swap_endian(self) -> Self { - self - } -} - -impl SwapEndian for u16{ - #[inline] - fn swap_endian(self) -> Self { - self.swap_bytes() - } -} -impl SwapEndian for u32{ - #[inline] - fn swap_endian(self) -> Self { - self.swap_bytes() - } -} - -impl SwapEndian for u64{ - #[inline] - fn swap_endian(self) -> Self { - self.swap_bytes() - } -} - -impl SwapEndian for f64{ - #[inline] - fn swap_endian(self) -> Self { - //trust me this is safe - unsafe{ mem::transmute::<_, f64>(mem::transmute::<_, u64>(self).swap_bytes()) } - } -} - -impl SwapEndian for i8{ - #[inline] - fn swap_endian(self) -> Self { - self - } -} - -impl SwapEndian for i16{ - #[inline] - fn swap_endian(self) -> Self { - self.swap_bytes() - } -} -impl SwapEndian for i32{ - #[inline] - fn swap_endian(self) -> Self { - self.swap_bytes() - } -} - -impl SwapEndian for i64{ - #[inline] - fn swap_endian(self) -> Self { - self.swap_bytes() - } -} - -impl SwapEndian for (T, U){ - #[inline] - fn swap_endian(self) -> Self { - (self.0.swap_endian(), self.1.swap_endian()) - } -} - -impl SwapEndian for (T, U, V){ - #[inline] - fn swap_endian(self) -> Self { - (self.0.swap_endian(), self.1.swap_endian(), self.2.swap_endian()) - } -} - -impl SwapEndian for (T, U, V, W){ - #[inline] - fn swap_endian(self) -> Self { - (self.0.swap_endian(), self.1.swap_endian(), self.2.swap_endian(), self.3.swap_endian()) - } -} - -impl SwapEndian for [T; SIZE]{ - #[inline] - fn swap_endian(mut self) -> Self { - for elem in &mut self{ - *elem = elem.swap_endian(); - } - - self - } -} \ No newline at end of file diff --git a/src/grpc/protobufs.rs b/src/grpc/protobufs.rs deleted file mode 100644 index bae7331..0000000 --- a/src/grpc/protobufs.rs +++ /dev/null @@ -1,5 +0,0 @@ - -pub mod account { - tonic::include_proto!("account"); -} - From 4e830686621355a5632fc398a9dd81066f475559 Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 21 Sep 2025 16:21:58 +0200 Subject: [PATCH 004/203] remove temporary file and add missing ones --- Cargo.lock | 3697 ++++++++++++++++++++++++++++++++++++++++++ bu | 12 - prudpv1/Cargo.toml | 26 + prudpv1/src/lib.rs | 2 + rnex-core/Cargo.toml | 61 + 5 files changed, 3786 insertions(+), 12 deletions(-) create mode 100644 Cargo.lock delete mode 100644 bu create mode 100644 prudpv1/Cargo.toml create mode 100644 prudpv1/src/lib.rs create mode 100644 rnex-core/Cargo.toml diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..d7d6490 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,3697 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "async-trait" +version = "0.1.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "atomic" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + +[[package]] +name = "atomic" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "aws-lc-rs" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", +] + +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower 0.5.2", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" + +[[package]] +name = "binascii" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools 0.12.1", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.104", + "which", +] + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "bytemuck" +version = "1.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "441473f2b4b0459a68628c744bc61d23e730fb00128b841d30fa4bb3972257e4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctrlc" +version = "3.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73" +dependencies = [ + "nix", + "windows-sys 0.59.0", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "devise" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1d90b0c4c777a2cad215e3c7be59ac7c15adf45cf76317009b7d096d46f651d" +dependencies = [ + "devise_codegen", + "devise_core", +] + +[[package]] +name = "devise_codegen" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71b28680d8be17a570a2334922518be6adc3f58ecc880cbb404eaeb8624fd867" +dependencies = [ + "devise_core", + "quote", +] + +[[package]] +name = "devise_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b035a542cf7abf01f2e3c4d5a7acbaebfefe120ae4efc7bde3df98186e4b8af7" +dependencies = [ + "bitflags", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "figment" +version = "0.10.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" +dependencies = [ + "atomic 0.6.1", + "pear", + "serde", + "toml", + "uncased", + "version_check", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+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]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "h2" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.10.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.3.1", + "indexmap 2.10.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.3.1", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.11", + "http 1.3.1", + "http-body 1.0.1", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http 1.3.1", + "hyper 1.6.0", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper 1.6.0", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.6.0", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "hyper 1.6.0", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.0", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown 0.15.4", + "serde", +] + +[[package]] +name = "inlinable_string" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "io-uring" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is-terminal" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jobserver" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +dependencies = [ + "getrandom 0.3.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.53.3", +] + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "macros" +version = "0.0.0" +dependencies = [ + "proc-macro2", + "quote", + "rand 0.9.2", + "syn 2.0.104", +] + +[[package]] +name = "macros" +version = "0.1.1" +source = "git+https://github.com/DJMrTV/VByteMacros#e2f31bded8c5591e847ba03faf79ae0351e43e69" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "mime" +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.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "multer" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http 1.3.1", + "httparse", + "memchr", + "mime", + "spin", + "tokio", + "tokio-util", + "version_check", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "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 = "pear" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467" +dependencies = [ + "inlinable_string", + "pear_codegen", + "yansi", +] + +[[package]] +name = "pear_codegen" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +dependencies = [ + "proc-macro2", + "syn 2.0.104", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "version_check", + "yansi", +] + +[[package]] +name = "prost" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "prudpv1" +version = "0.1.0" +dependencies = [ + "async-trait", + "bytemuck", + "hmac", + "log", + "md-5", + "once_cell", + "rc4", + "rnex-core", + "thiserror", + "tokio", + "typenum", + "v-byte-helpers", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 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]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[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]] +name = "rc4" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1256e23efe6097f27aa82d6ca6889361c001586ae0f6917cbad072f05eb275" +dependencies = [ + "cipher", +] + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +dependencies = [ + "bitflags", +] + +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "reqwest" +version = "0.12.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "h2 0.4.11", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.6.0", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower 0.5.2", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rnex-core" +version = "0.1.1" +dependencies = [ + "anyhow", + "async-trait", + "bytemuck", + "chacha20", + "chrono", + "ctrlc", + "dotenv", + "futures", + "hex", + "hmac", + "json", + "log", + "macros 0.0.0", + "md-5", + "once_cell", + "paste", + "prost", + "rand 0.8.5", + "rc4", + "reqwest", + "rocket", + "rsa", + "rustls", + "rustls-pki-types", + "rustls-webpki", + "serde", + "sha2", + "simplelog", + "thiserror", + "tokio", + "tokio-rustls", + "tokio-stream", + "tokio-tungstenite", + "tonic", + "tungstenite", + "typenum", + "v-byte-helpers", +] + +[[package]] +name = "rocket" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a516907296a31df7dc04310e7043b61d71954d703b603cc6867a026d7e72d73f" +dependencies = [ + "async-stream", + "async-trait", + "atomic 0.5.3", + "binascii", + "bytes", + "either", + "figment", + "futures", + "indexmap 2.10.0", + "log", + "memchr", + "multer", + "num_cpus", + "parking_lot", + "pin-project-lite", + "rand 0.8.5", + "ref-cast", + "rocket_codegen", + "rocket_http", + "serde", + "serde_json", + "state", + "tempfile", + "time", + "tokio", + "tokio-stream", + "tokio-util", + "ubyte", + "version_check", + "yansi", +] + +[[package]] +name = "rocket_codegen" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46" +dependencies = [ + "devise", + "glob", + "indexmap 2.10.0", + "proc-macro2", + "quote", + "rocket_http", + "syn 2.0.104", + "unicode-xid", + "version_check", +] + +[[package]] +name = "rocket_http" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e274915a20ee3065f611c044bd63c40757396b6dbc057d6046aec27f14f882b9" +dependencies = [ + "cookie", + "either", + "futures", + "http 0.2.12", + "hyper 0.14.32", + "indexmap 2.10.0", + "log", + "memchr", + "pear", + "percent-encoding", + "pin-project-lite", + "ref-cast", + "serde", + "smallvec", + "stable-pattern", + "state", + "time", + "tokio", + "uncased", +] + +[[package]] +name = "rsa" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.60.2", +] + +[[package]] +name = "rustls" +version = "0.23.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "serde_json" +version = "1.0.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "simplelog" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16257adbfaef1ee58b1363bdc0664c9b8e1e30aed86049635fb5f147d065a9c0" +dependencies = [ + "log", + "termcolor", + "time", +] + +[[package]] +name = "slab" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable-pattern" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" +dependencies = [ + "memchr", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" +dependencies = [ + "loom", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix 1.0.8", + "windows-sys 0.59.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.47.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "slab", + "socket2 0.6.0", + "tokio-macros", + "windows-sys 0.59.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489a59b6730eda1b0171fcfda8b121f4bee2b35cba8645ca35c5f7ba3eb736c1" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap 2.10.0", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64", + "bytes", + "h2 0.4.11", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.6.0", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "socket2 0.5.10", + "tokio", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "iri-string", + "pin-project-lite", + "tower 0.5.2", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d" +dependencies = [ + "bytes", + "data-encoding", + "http 1.3.1", + "httparse", + "log", + "rand 0.9.2", + "sha1", + "thiserror", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "ubyte" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f720def6ce1ee2fc44d40ac9ed6d3a59c361c80a75a7aa8e75bb9baed31cf2ea" +dependencies = [ + "serde", +] + +[[package]] +name = "uncased" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" +dependencies = [ + "serde", + "version_check", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "v-byte-helpers" +version = "0.1.1" +source = "git+https://github.com/DJMrTV/VByteMacros#e2f31bded8c5591e847ba03faf79ae0351e43e69" +dependencies = [ + "bytemuck", + "macros 0.1.1", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[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 = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.104", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.44", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-registry" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "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]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "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]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +dependencies = [ + "is-terminal", +] + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] diff --git a/bu b/bu deleted file mode 100644 index da34886..0000000 --- a/bu +++ /dev/null @@ -1,12 +0,0 @@ - - -[build-dependencies] -tonic-build = "0.12.3" - -[features] -default = ["secure", "auth"] -secure = [] -auth = [] -no_tls = [] - - diff --git a/prudpv1/Cargo.toml b/prudpv1/Cargo.toml new file mode 100644 index 0000000..bdf340e --- /dev/null +++ b/prudpv1/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "prudpv1" +version = "0.1.0" +edition = "2024" + +[dependencies] +bytemuck = { version = "1.23.1", features = ["derive"] } +tokio = { version = "1.47.0", features = ["full"] } +hmac = "0.12.1" +md-5 = "^0.10.6" +rc4 = "0.1.0" +v-byte-helpers = { git = "https://github.com/DJMrTV/VByteMacros", version = "0.1.1" } +thiserror = "2.0.12" +log = "0.4.27" +async-trait = "0.1.88" +typenum = "1.18.0" +once_cell = "1.21.3" +rnex-core = { path = "../rnex-core", version = "0.1.1" } + +[[bin]] +name = "proxy_insecure" +path = "src/executables/proxy_insecure.rs" + +[[bin]] +name = "proxy_secure" +path = "src/executables/proxy_secure.rs" \ No newline at end of file diff --git a/prudpv1/src/lib.rs b/prudpv1/src/lib.rs new file mode 100644 index 0000000..ed53644 --- /dev/null +++ b/prudpv1/src/lib.rs @@ -0,0 +1,2 @@ +pub mod prudp; +pub mod executables; \ No newline at end of file diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml new file mode 100644 index 0000000..8a5c9bd --- /dev/null +++ b/rnex-core/Cargo.toml @@ -0,0 +1,61 @@ +[package] +name = "rnex-core" +version = "0.1.1" +edition = "2024" + +[dependencies] +bytemuck = { version = "1.21.0", features = ["derive"] } +dotenv = "0.15.0" +once_cell = "1.20.2" +rc4 = "0.1.0" +thiserror = "2.0.11" +v-byte-helpers = { git = "https://github.com/DJMrTV/VByteMacros", version = "0.1.1" } +simplelog = "0.12.2" +chrono = "0.4.39" +log = "0.4.25" +anyhow = "1.0.95" +rand = "0.8.5" + +hmac = "0.12.1" +md-5 = "^0.10.6" +tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "net", "sync", "fs"] } +tokio-stream = { version = "0.1.17", features = ["io-util"] } +tonic = "0.12.3" +prost = "0.13.4" +hex = "0.4.3" + +macros = { path = "../macros" } +rocket = { version = "0.5.1", features = ["json", "serde_json"] } +serde = { version = "1.0.217", features = ["derive"] } +async-trait = "0.1.86" +paste = "1.0.15" +typenum = "1.18.0" +futures = "0.3.31" +reqwest = "0.12.18" +json = "0.12.4" +ctrlc = "3.4.7" +rsa = "0.9.8" +sha2 = "0.10.9" +chacha20 = "0.9.1" + +rustls = "0.23.27" + +rustls-pki-types = "1.12.0" +rustls-webpki = "0.103.3" +tokio-rustls = "0.26.2" +tokio-tungstenite = "0.27.0" +tungstenite = "0.27.0" + + +[[bin]] +name = "backend_server_insecure" +path = "src/executables/backend_server_insecure.rs" + + +[[bin]] +name = "backend_server_secure" +path = "src/executables/backend_server_secure.rs" + +[[bin]] +name = "edge_node_holder_server" +path = "src/executables/edge_node_holder_server.rs" \ No newline at end of file From c698e0b3dd749d9d02c015231f76f87f06ce9328 Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 7 Oct 2025 20:39:52 +0200 Subject: [PATCH 005/203] chore: anti pretendo people note and cleanup --- Cargo.lock | 542 +----------------- README.md | 15 +- macros/Cargo.toml | 1 - macros/src/protos.rs | 2 + prudpv1/src/executables/proxy_insecure.rs | 15 +- prudpv1/src/executables/proxy_secure.rs | 17 +- prudpv1/src/prudp/auth_module.rs | 4 +- prudpv1/src/prudp/router.rs | 13 +- prudpv1/src/prudp/socket.rs | 2 +- prudpv1/src/prudp/unsecure.rs | 2 +- rnex-core/Cargo.toml | 14 - .../executables/backend_server_insecure.rs | 25 +- .../src/executables/backend_server_secure.rs | 10 +- rnex-core/src/executables/common.rs | 7 +- .../executables/edge_node_holder_server.rs | 3 +- rnex-core/src/main.rs | 29 +- rnex-core/src/nex/matchmake.rs | 4 +- rnex-core/src/prudp/socket_addr.rs | 2 +- rnex-core/src/reggie.rs | 29 +- rnex-core/src/rmc/protocols/matchmake.rs | 2 - rnex-core/src/rmc/protocols/mod.rs | 1 + rnex-core/src/rmc/structures/list.rs | 2 - rnex-core/src/rmc/structures/mod.rs | 4 +- rnex-core/src/util.rs | 4 +- rnex-core/src/web/mod.rs | 2 +- 25 files changed, 69 insertions(+), 682 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7d6490..fb9c740 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,12 +41,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anyhow" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" - [[package]] name = "async-stream" version = "0.3.6" @@ -107,29 +101,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "aws-lc-rs" -version = "1.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" -dependencies = [ - "aws-lc-sys", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" -dependencies = [ - "bindgen", - "cc", - "cmake", - "dunce", - "fs_extra", -] - [[package]] name = "axum" version = "0.7.9" @@ -198,41 +169,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "base64ct" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" - [[package]] name = "binascii" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.104", - "which", -] - [[package]] name = "bitflags" version = "2.9.1" @@ -274,12 +216,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.10.1" @@ -292,20 +228,9 @@ version = "1.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" dependencies = [ - "jobserver", - "libc", "shlex", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.1" @@ -318,17 +243,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - [[package]] name = "chrono" version = "0.4.41" @@ -353,32 +267,6 @@ dependencies = [ "inout", ] -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "cmake" -version = "0.1.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" -dependencies = [ - "cc", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - [[package]] name = "cookie" version = "0.18.1" @@ -406,15 +294,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -435,23 +314,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "data-encoding" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" - -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - [[package]] name = "deranged" version = "0.4.0" @@ -501,7 +363,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", - "const-oid", "crypto-common", "subtle", ] @@ -523,12 +384,6 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - [[package]] name = "either" version = "1.15.0" @@ -610,12 +465,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "futures" version = "0.3.31" @@ -624,7 +473,6 @@ checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", - "futures-executor", "futures-io", "futures-sink", "futures-task", @@ -647,34 +495,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - [[package]] name = "futures-io" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "futures-sink" version = "0.3.31" @@ -696,7 +522,6 @@ dependencies = [ "futures-channel", "futures-core", "futures-io", - "futures-macro", "futures-sink", "futures-task", "memchr", @@ -834,15 +659,6 @@ dependencies = [ "digest", ] -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "http" version = "0.2.12" @@ -1232,40 +1048,12 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" -[[package]] -name = "jobserver" -version = "0.1.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" -dependencies = [ - "getrandom 0.3.3", - "libc", -] - [[package]] name = "js-sys" version = "0.3.77" @@ -1287,15 +1075,6 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" @@ -1303,28 +1082,6 @@ version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" -[[package]] -name = "libloading" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" -dependencies = [ - "cfg-if", - "windows-targets 0.53.3", -] - -[[package]] -name = "libm" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - [[package]] name = "linux-raw-sys" version = "0.9.4" @@ -1374,7 +1131,6 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "rand 0.9.2", "syn 2.0.104", ] @@ -1425,12 +1181,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.8.9" @@ -1499,16 +1249,6 @@ dependencies = [ "libc", ] -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1519,49 +1259,12 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-bigint-dig" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" -dependencies = [ - "byteorder", - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.8.5", - "smallvec", - "zeroize", -] - [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -1569,7 +1272,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -1708,15 +1410,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - [[package]] name = "percent-encoding" version = "2.3.1" @@ -1755,27 +1448,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs1" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" -dependencies = [ - "der", - "pkcs8", - "spki", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - [[package]] name = "pkg-config" version = "0.3.32" @@ -1806,16 +1478,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" -dependencies = [ - "proc-macro2", - "syn 2.0.104", -] - [[package]] name = "proc-macro2" version = "1.0.95" @@ -1845,20 +1507,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" dependencies = [ "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" -dependencies = [ - "anyhow", - "itertools 0.14.0", - "proc-macro2", - "quote", - "syn 2.0.104", ] [[package]] @@ -1901,18 +1549,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_chacha", + "rand_core", ] [[package]] @@ -1922,17 +1560,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "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", + "rand_core", ] [[package]] @@ -1944,15 +1572,6 @@ dependencies = [ "getrandom 0.2.16", ] -[[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]] name = "rc4" version = "0.1.0" @@ -2093,14 +1712,11 @@ dependencies = [ name = "rnex-core" version = "0.1.1" dependencies = [ - "anyhow", "async-trait", "bytemuck", - "chacha20", "chrono", "ctrlc", "dotenv", - "futures", "hex", "hmac", "json", @@ -2109,25 +1725,14 @@ dependencies = [ "md-5", "once_cell", "paste", - "prost", - "rand 0.8.5", + "rand", "rc4", "reqwest", "rocket", - "rsa", - "rustls", - "rustls-pki-types", - "rustls-webpki", - "serde", - "sha2", "simplelog", "thiserror", "tokio", - "tokio-rustls", - "tokio-stream", - "tokio-tungstenite", "tonic", - "tungstenite", "typenum", "v-byte-helpers", ] @@ -2153,7 +1758,7 @@ dependencies = [ "num_cpus", "parking_lot", "pin-project-lite", - "rand 0.8.5", + "rand", "ref-cast", "rocket_codegen", "rocket_http", @@ -2214,51 +1819,12 @@ dependencies = [ "uncased", ] -[[package]] -name = "rsa" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" -dependencies = [ - "const-oid", - "digest", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core 0.6.4", - "signature", - "spki", - "subtle", - "zeroize", -] - [[package]] name = "rustc-demangle" version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - [[package]] name = "rustix" version = "1.0.8" @@ -2268,7 +1834,7 @@ dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys 0.9.4", + "linux-raw-sys", "windows-sys 0.60.2", ] @@ -2278,8 +1844,6 @@ version = "0.23.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ - "aws-lc-rs", - "log", "once_cell", "rustls-pki-types", "rustls-webpki", @@ -2302,7 +1866,6 @@ version = "0.103.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" dependencies = [ - "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -2417,28 +1980,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - [[package]] name = "sharded-slab" version = "0.1.7" @@ -2463,16 +2004,6 @@ dependencies = [ "libc", ] -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest", - "rand_core 0.6.4", -] - [[package]] name = "simplelog" version = "0.12.2" @@ -2522,16 +2053,6 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - [[package]] name = "stable-pattern" version = "0.1.0" @@ -2634,7 +2155,7 @@ dependencies = [ "fastrand", "getrandom 0.3.3", "once_cell", - "rustix 1.0.8", + "rustix", "windows-sys 0.59.0", ] @@ -2781,18 +2302,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-tungstenite" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489a59b6730eda1b0171fcfda8b121f4bee2b35cba8645ca35c5f7ba3eb736c1" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite", -] - [[package]] name = "tokio-util" version = "0.7.15" @@ -2888,7 +2397,7 @@ dependencies = [ "indexmap 1.9.3", "pin-project", "pin-project-lite", - "rand 0.8.5", + "rand", "slab", "tokio", "tokio-util", @@ -3009,23 +2518,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "tungstenite" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d" -dependencies = [ - "bytes", - "data-encoding", - "http 1.3.1", - "httparse", - "log", - "rand 0.9.2", - "sha1", - "thiserror", - "utf-8", -] - [[package]] name = "typenum" version = "1.18.0" @@ -3080,12 +2572,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -3224,18 +2710,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - [[package]] name = "winapi" version = "0.3.9" diff --git a/README.md b/README.md index f0526a0..c5f1ada 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,17 @@ - Pretendo team for the rest of the Servers and Reverse engineering efforts - Kinnay for his huge work on reversing nex servers and documentation(https://github.com/Kinnay/NintendoClients/) - Splatfestival testing team for helping us test our messes of code -- The SPFN team(Bloxer, Ceantix and Maple(aka TV)) \ No newline at end of file +- The SPFN team(Bloxer, Ceantix and RusticMaple) + +This nex implementation was not created and is not intended to compete with pretendo, +we wholeheartedly support pretendo. +This project would never have been possible without their reverse engineering efforts. +As such if you want to respect the Authors wishes(Maple(Me) is pretty much the sole author of Rust-Nex), do not +use it if you mean any harm to pretendo. If you do show intent to harm them you will be blocked from ever contributing +and will be refused support, as such please also refrain from asking for support if you have been blocked by pretendo. + + +I felt like this needed to be said as there are far too many pretendo copycats who blatantly copy their code and use +their reversal efforts with no credits in sight in an attempt to harm them for some grudge or stupid reason. +I feel that by working together and not against each other we can reach a better and healthier future for the community, +health of developers and numerous more reasons. diff --git a/macros/Cargo.toml b/macros/Cargo.toml index e301949..d0bb83b 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -13,5 +13,4 @@ proc-macro = true quote = "1.0.38" proc-macro2 = "1.0.93" syn = { version = "2.0.98", features = ["full"] } -rand = "0.9.0" diff --git a/macros/src/protos.rs b/macros/src/protos.rs index 711e931..a19f01e 100644 --- a/macros/src/protos.rs +++ b/macros/src/protos.rs @@ -39,6 +39,7 @@ impl RmcProtocolData{ // boilerplate tokens which all raw traits need quote!{ #[doc(hidden)] + #[allow(unused_must_use)] pub trait #raw_name: #name }.to_tokens(tokens); @@ -209,6 +210,7 @@ impl RmcProtocolData{ // boilerplate tokens which all raw traits need quote!{ #[doc(hidden)] + #[allow(unused_must_use)] pub trait #remote_name: rnex_core::rmc::protocols::HasRmcConnection }.to_tokens(tokens); diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index 3ffe039..b33e069 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -2,17 +2,11 @@ use rnex_core::reggie::UnitPacketRead; use rnex_core::reggie::UnitPacketWrite; use rnex_core::rmc::structures::RmcSerialize; -use std::env; -use std::ffi::CStr; -use std::io::{Read, Write}; -use std::net::{Ipv4Addr, SocketAddrV4}; -use std::sync::{Arc, OnceLock}; +use std::net::SocketAddrV4; +use std::sync::Arc; use std::time::Duration; -use bytemuck::{Pod, Zeroable}; -use log::{error, warn}; -use once_cell::sync::Lazy; -use tokio::net::{TcpSocket, TcpStream}; -use tokio::sync::RwLock; +use log::error; +use tokio::net::TcpStream; use tokio::task; use tokio::time::sleep; use prudpv1::executables::common::{FORWARD_DESTINATION, EDGE_NODE_HOLDER}; @@ -110,4 +104,5 @@ async fn main() { } }); } + drop(conn); } \ No newline at end of file diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index b66fbc2..91a66fa 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -1,23 +1,16 @@ use rnex_core::reggie::UnitPacketRead; use rnex_core::reggie::UnitPacketWrite; use rnex_core::rmc::structures::RmcSerialize; -use std::env; -use std::ffi::CStr; -use std::io::{Read, Write}; -use std::net::{Ipv4Addr, SocketAddrV4}; -use std::sync::{Arc, OnceLock}; +use std::net::SocketAddrV4; +use std::sync::Arc; use std::time::Duration; -use bytemuck::{Pod, Zeroable}; -use log::{error, warn}; -use once_cell::sync::Lazy; -use tokio::net::{TcpSocket, TcpStream}; -use tokio::sync::RwLock; +use log::error; +use tokio::net::TcpStream; use tokio::task; use tokio::time::sleep; use prudpv1::executables::common::{FORWARD_DESTINATION, EDGE_NODE_HOLDER}; use prudpv1::prudp::router::Router; use prudpv1::prudp::secure::Secure; -use prudpv1::prudp::unsecure::Unsecure; use rnex_core::common::setup; use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SECURE_SERVER_ACCOUNT, SERVER_PORT}; use rnex_core::prudp::virtual_port::VirtualPort; @@ -113,4 +106,6 @@ async fn main() { } }); } + + drop(conn); } \ No newline at end of file diff --git a/prudpv1/src/prudp/auth_module.rs b/prudpv1/src/prudp/auth_module.rs index d7e93b0..28659d6 100644 --- a/prudpv1/src/prudp/auth_module.rs +++ b/prudpv1/src/prudp/auth_module.rs @@ -1,8 +1,8 @@ +/* use std::net::Ipv4Addr; - pub trait AuthModule{ fn get_auth_key(addr: Ipv4Addr) -> [u8; 32]; -} +}*/ /* struct AuthServerAuthModule; diff --git a/prudpv1/src/prudp/router.rs b/prudpv1/src/prudp/router.rs index 3212155..ca28dd6 100644 --- a/prudpv1/src/prudp/router.rs +++ b/prudpv1/src/prudp/router.rs @@ -1,14 +1,12 @@ -use std::{env, io}; +use std::io; use std::io::Cursor; use std::marker::PhantomData; use tokio::net::UdpSocket; use std::net::{SocketAddr, SocketAddrV4}; use std::net::SocketAddr::V4; use std::sync::{Arc, Weak}; -use std::sync::atomic::{AtomicBool}; use std::time::Duration; use tokio::task::JoinHandle; -use once_cell::sync::Lazy; use log::{error, info}; use thiserror::Error; use tokio::select; @@ -19,16 +17,11 @@ use crate::prudp::packet::{PRUDPV1Packet}; use rnex_core::prudp::virtual_port::VirtualPort; use crate::prudp::router::Error::VirtualPortTaken; -static SERVER_DATAGRAMS: Lazy = Lazy::new(||{ - env::var("SERVER_DATAGRAM_COUNT").ok() - .and_then(|s| s.parse().ok()) - .unwrap_or(1) -}); pub struct Router { endpoints: RwLock<[Option>; 16]>, - running: AtomicBool, + //running: AtomicBool, socket: Arc, _no_outside_construction: PhantomData<()> } @@ -114,7 +107,7 @@ impl Router { let own_impl = Router { endpoints: Default::default(), - running: AtomicBool::new(true), + // running: AtomicBool::new(true), socket: socket.clone(), _no_outside_construction: Default::default() }; diff --git a/prudpv1/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs index dde9b4d..4aca993 100644 --- a/prudpv1/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -679,7 +679,7 @@ impl AnyInternalSocket for InternalSocket { self.send_packet_unbuffered(address, packet).await; - let Some(connect_ack_packet) = recv.recv().await else { + let Some(_connect_ack_packet) = recv.recv().await else { error!("what"); return None; }; diff --git a/prudpv1/src/prudp/unsecure.rs b/prudpv1/src/prudp/unsecure.rs index 6d7d9ff..6c45824 100644 --- a/prudpv1/src/prudp/unsecure.rs +++ b/prudpv1/src/prudp/unsecure.rs @@ -78,7 +78,7 @@ impl CryptoHandlerConnectionInstance for UnsecureInstance { packet.calculate_and_assign_signature(self.key, None, Some(self.self_signature)); } - fn verify_packet(&self, packet: &PRUDPV1Packet) -> bool { + fn verify_packet(&self, _packet: &PRUDPV1Packet) -> bool { true } } \ No newline at end of file diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 8a5c9bd..b41bc8d 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -13,38 +13,24 @@ v-byte-helpers = { git = "https://github.com/DJMrTV/VByteMacros", version = "0.1 simplelog = "0.12.2" chrono = "0.4.39" log = "0.4.25" -anyhow = "1.0.95" rand = "0.8.5" hmac = "0.12.1" md-5 = "^0.10.6" tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "net", "sync", "fs"] } -tokio-stream = { version = "0.1.17", features = ["io-util"] } tonic = "0.12.3" -prost = "0.13.4" hex = "0.4.3" macros = { path = "../macros" } rocket = { version = "0.5.1", features = ["json", "serde_json"] } -serde = { version = "1.0.217", features = ["derive"] } async-trait = "0.1.86" paste = "1.0.15" typenum = "1.18.0" -futures = "0.3.31" reqwest = "0.12.18" json = "0.12.4" ctrlc = "3.4.7" -rsa = "0.9.8" -sha2 = "0.10.9" -chacha20 = "0.9.1" -rustls = "0.23.27" -rustls-pki-types = "1.12.0" -rustls-webpki = "0.103.3" -tokio-rustls = "0.26.2" -tokio-tungstenite = "0.27.0" -tungstenite = "0.27.0" [[bin]] diff --git a/rnex-core/src/executables/backend_server_insecure.rs b/rnex-core/src/executables/backend_server_insecure.rs index 005936b..7a9f88a 100644 --- a/rnex-core/src/executables/backend_server_insecure.rs +++ b/rnex-core/src/executables/backend_server_insecure.rs @@ -1,32 +1,17 @@ use rnex_core::reggie::{RemoteEdgeNodeHolder, UnitPacketRead}; use log::{error, info}; use once_cell::sync::Lazy; -use rustls::client::danger::HandshakeSignatureValid; -use rustls::pki_types::{CertificateDer, TrustAnchor, UnixTime}; -use rustls::server::danger::{ClientCertVerified, ClientCertVerifier}; -use rustls::server::{ClientCertVerifierBuilder, WebPkiClientVerifier}; -use rustls::{ - DigitallySignedStruct, DistinguishedName, Error, RootCertStore, ServerConfig, ServerConnection, - SignatureScheme, -}; -use rustls_pki_types::PrivateKeyDer; use rnex_core::common::setup; -use std::borrow::ToOwned; -use std::{env, fs}; +use std::{env}; use std::io::Cursor; -use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4}; +use std::net::SocketAddrV4; use std::sync::Arc; -use macros::{method_id, rmc_proto, rmc_struct}; -use tokio::io::AsyncReadExt; -use tokio::net::{TcpListener, TcpSocket, TcpStream}; +use tokio::net::{TcpListener, TcpStream}; use tokio::task; -use tokio_rustls::TlsAcceptor; -use rnex_core::define_rmc_proto; use rnex_core::executables::common::{OWN_IP_PRIVATE, SECURE_SERVER_ACCOUNT, SERVER_PORT}; use rnex_core::nex::auth_handler::AuthHandler; use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister; use rnex_core::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; -use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::RmcSerialize; use rnex_core::rnex_proxy_common::ConnectionInitData; use rnex_core::util::SplittableBufferConnection; @@ -57,7 +42,7 @@ async fn main() { - while let Ok((mut stream, addr)) = listen.accept().await { + while let Ok((mut stream, _addr)) = listen.accept().await { let buffer = match stream.read_buffer().await{ Ok(v) => v, Err(e) => { @@ -68,7 +53,7 @@ async fn main() { let user_connection_data = ConnectionInitData::deserialize(&mut Cursor::new(buffer)); - let user_connection_data = match user_connection_data{ + let _user_connection_data = match user_connection_data{ Ok(v) => v, Err(e) => { error!("an error ocurred whilest reading connection data: {:?}", e); diff --git a/rnex-core/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs index f758679..82d1a39 100644 --- a/rnex-core/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -1,22 +1,20 @@ use std::io::Cursor; use rnex_core::rmc::structures::RmcSerialize; -use rnex_core::reggie::{RemoteEdgeNodeHolder, UnitPacketRead}; +use rnex_core::reggie::UnitPacketRead; use std::net::SocketAddrV4; use std::sync::Arc; use std::sync::atomic::AtomicU32; use log::{error, info}; -use tokio::net::{TcpListener, TcpStream}; +use tokio::net::TcpListener; use tokio::task; use rnex_core::common::setup; use rnex_core::executables::common::{OWN_IP_PRIVATE, SERVER_PORT}; use rnex_core::nex::matchmake::MatchmakeManager; use rnex_core::nex::remote_console::RemoteConsole; use rnex_core::nex::user::User; -use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister; -use rnex_core::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; +use rnex_core::rmc::protocols::new_rmc_gateway_connection; use rnex_core::rnex_proxy_common::ConnectionInitData; use rnex_core::rmc::protocols::RemoteInstantiatable; -use rnex_core::util::SplittableBufferConnection; #[tokio::main] async fn main() { @@ -35,7 +33,7 @@ async fn main() { MatchmakeManager::initialize_garbage_collect_thread(weak_mmm).await; - while let Ok((mut stream, addr)) = listen.accept().await { + while let Ok((mut stream, _addr)) = listen.accept().await { let buffer = match stream.read_buffer().await{ Ok(v) => v, Err(e) => { diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index 77bccf7..f12a84c 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -1,12 +1,7 @@ use std::env; -use std::net::{Ipv4Addr, SocketAddrV4}; -use macros::{method_id, rmc_proto, RmcSerialize}; +use std::net::Ipv4Addr; use once_cell::sync::Lazy; -use tonic::transport::Server; -use crate::define_rmc_proto; -use crate::prudp::station_url::StationUrl; use crate::nex::account::Account; -use crate::rmc::response::ErrorCode; pub static OWN_IP_PRIVATE: Lazy = Lazy::new(|| { env::var("SERVER_IP") diff --git a/rnex-core/src/executables/edge_node_holder_server.rs b/rnex-core/src/executables/edge_node_holder_server.rs index 5146a86..ea798c5 100644 --- a/rnex-core/src/executables/edge_node_holder_server.rs +++ b/rnex-core/src/executables/edge_node_holder_server.rs @@ -1,7 +1,6 @@ use std::io::Cursor; use std::net::SocketAddrV4; use std::sync::{Arc, Weak}; -use log::error; use macros::rmc_struct; use tokio::net::TcpListener; use tokio::sync::RwLock; @@ -56,7 +55,7 @@ async fn main() { let holder: Arc = Default::default(); - while let Ok((mut stream, addr)) = listen.accept().await { + while let Ok((stream, _addr)) = listen.accept().await { let mut conn: SplittableBufferConnection = stream.into(); let Some(data) = conn.recv().await else { diff --git a/rnex-core/src/main.rs b/rnex-core/src/main.rs index b3b226b..0af4975 100644 --- a/rnex-core/src/main.rs +++ b/rnex-core/src/main.rs @@ -11,40 +11,15 @@ extern crate self as rust_nex; use crate::nex::account::Account; -use crate::nex::auth_handler::{AuthHandler, RemoteAuthClientProtocol}; -use crate::nex::remote_console::RemoteConsole; -use crate::nex::user::{RemoteUserProtocol, User}; -use crate::rmc::protocols::auth::Auth; -use crate::rmc::protocols::auth::RawAuth; -use crate::rmc::protocols::auth::RawAuthInfo; -use crate::rmc::protocols::auth::RemoteAuth; -use crate::rmc::protocols::matchmake_extension::RemoteMatchmakeExtension; -use crate::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote, RemoteInstantiatable}; -use crate::rmc::response::ErrorCode; -use crate::rmc::structures::any::Any; -use crate::rmc::structures::connection_data::ConnectionData; -use crate::rmc::structures::matchmake::{CreateMatchmakeSessionParam, Gathering, MatchmakeParam, MatchmakeSession}; -use crate::rmc::structures::qresult::QResult; use chrono::{Local, SecondsFormat}; -use log::{error, info}; -use macros::rmc_struct; use once_cell::sync::Lazy; use simplelog::{ ColorChoice, CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode, WriteLogger, }; use std::fs::File; -use std::marker::PhantomData; -use std::net::{Ipv4Addr, SocketAddrV4}; -use std::ops::{BitAnd, BitOr}; -use std::str::FromStr; -use std::sync::{Arc, Once, Weak}; -use std::time::Duration; +use std::net::{Ipv4Addr}; +use std::sync::Once; use std::{env, fs}; -use std::sync::atomic::AtomicU32; -use tokio::task::JoinHandle; -use crate::kerberos::KerberosDateTime; -use crate::nex::matchmake::MatchmakeManager; -use crate::rmc::protocols::secure::RemoteSecure; mod prudp; pub mod rmc; diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 1f4f61a..93e8ced 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -203,7 +203,7 @@ impl ExtendedMatchmakeSession{ }; - let other_pid = other_conn.pid; + // let other_pid = other_conn.pid; /*if other_pid == self.session.gathering.owner_pid && joining_pid == self.session.gathering.owner_pid{ continue; @@ -341,7 +341,7 @@ impl ExtendedMatchmakeSession{ } pub async fn migrate_host(&mut self, initiator_pid: u32) -> Result<(), ErrorCode>{ - let players: Vec<_> = self.connected_players.iter().filter_map(|p| p.upgrade()).collect(); + // let players: Vec<_> = self.connected_players.iter().filter_map(|p| p.upgrade()).collect(); self.session.gathering.host_pid = self.session.gathering.owner_pid; diff --git a/rnex-core/src/prudp/socket_addr.rs b/rnex-core/src/prudp/socket_addr.rs index f3ea10c..5c55e88 100644 --- a/rnex-core/src/prudp/socket_addr.rs +++ b/rnex-core/src/prudp/socket_addr.rs @@ -28,7 +28,7 @@ impl PRUDPSockAddr{ pub fn calculate_connection_signature(&self) -> [u8; 16] { let mut hmac = Md5Hmac::new_from_slice(&[0; 16]).expect("fuck"); - let mut data = self.regular_socket_addr.ip().octets().to_vec(); + let data = self.regular_socket_addr.ip().octets().to_vec(); //data.extend_from_slice(&self.regular_socket_addr.port().to_be_bytes()); hmac.write_all(&data).expect("figuring this out was complete ass"); diff --git a/rnex-core/src/reggie.rs b/rnex-core/src/reggie.rs index b3d73c9..47bf2d2 100644 --- a/rnex-core/src/reggie.rs +++ b/rnex-core/src/reggie.rs @@ -1,29 +1,8 @@ -use std::{env, fs, io}; -use std::hash::Hash; -use std::io::{Error, ErrorKind}; -use std::net::{SocketAddrV4, ToSocketAddrs}; -use std::pin::Pin; -use std::sync::Arc; -use std::task::{Context, Poll}; -use futures::{SinkExt, StreamExt}; -use macros::{method_id, rmc_proto, rmc_struct, RmcSerialize}; -use once_cell::sync::Lazy; -use rustls::{ClientConfig, RootCertStore, ServerConfig}; -use rustls::client::WebPkiServerVerifier; -use rustls::server::WebPkiClientVerifier; -use rustls_pki_types::{CertificateDer, PrivateKeyDer, ServerName, TrustAnchor}; -use thiserror::Error; -use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, ReadBuf}; -use tokio::net::{TcpListener, TcpStream}; -use tokio_rustls::{TlsAcceptor, TlsConnector}; -use tokio_rustls::client::TlsStream; -use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; -use tokio_tungstenite::tungstenite::Message; -use webpki::anchor_from_trusted_cert; -use crate::common::setup; +use std::io; +use std::net::SocketAddrV4; +use macros::{method_id, rmc_proto, RmcSerialize}; +use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; use crate::define_rmc_proto; -use crate::nex::account::Account; -use crate::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote, RmcCallable, RmcConnection}; use rnex_core::rmc::response::ErrorCode; use crate::rmc::structures::RmcSerialize; diff --git a/rnex-core/src/rmc/protocols/matchmake.rs b/rnex-core/src/rmc/protocols/matchmake.rs index 24942c0..595127a 100644 --- a/rnex-core/src/rmc/protocols/matchmake.rs +++ b/rnex-core/src/rmc/protocols/matchmake.rs @@ -8,10 +8,8 @@ pub trait Matchmake{ async fn unregister_gathering(&self, gid: u32) -> Result; #[method_id(41)] async fn get_session_urls(&self, gid: u32) -> Result, ErrorCode>; - #[method_id(42)] async fn update_session_host(&self, gid: u32, change_owner: bool) -> Result<(), ErrorCode>; - #[method_id(44)] async fn migrate_gathering_ownership(&self, gid: u32, candidates: Vec, participants_only: bool) -> Result<(), ErrorCode>; } \ No newline at end of file diff --git a/rnex-core/src/rmc/protocols/mod.rs b/rnex-core/src/rmc/protocols/mod.rs index 7ad8e8c..0b6fc65 100644 --- a/rnex-core/src/rmc/protocols/mod.rs +++ b/rnex-core/src/rmc/protocols/mod.rs @@ -153,6 +153,7 @@ macro_rules! define_rmc_proto { $($protocol:path),* }) => { paste::paste!{ + #[allow(unused_variables)] pub trait []: std::any::Any $( + [] + $protocol)* { async fn rmc_call(&self, remote_response_connection: &rnex_core::util::SendingBufferConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec){ match protocol_id{ diff --git a/rnex-core/src/rmc/structures/list.rs b/rnex-core/src/rmc/structures/list.rs index 1ebb60b..f4843c1 100644 --- a/rnex-core/src/rmc/structures/list.rs +++ b/rnex-core/src/rmc/structures/list.rs @@ -1,8 +1,6 @@ -use std::array::from_fn; use std::io::{Read, Write}; use std::mem::MaybeUninit; use bytemuck::bytes_of; -use serde::Serialize; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::rmc::structures::RmcSerialize; diff --git a/rnex-core/src/rmc/structures/mod.rs b/rnex-core/src/rmc/structures/mod.rs index fd6d61d..9d127f7 100644 --- a/rnex-core/src/rmc/structures/mod.rs +++ b/rnex-core/src/rmc/structures/mod.rs @@ -49,10 +49,10 @@ pub trait RmcSerialize{ } impl RmcSerialize for (){ - fn serialize(&self, writer: &mut dyn Write) -> Result<()> { + fn serialize(&self, _writer: &mut dyn Write) -> Result<()> { Ok(()) } - fn deserialize(reader: &mut dyn Read) -> Result { + fn deserialize(_reader: &mut dyn Read) -> Result { Ok(()) } diff --git a/rnex-core/src/util.rs b/rnex-core/src/util.rs index b052fe2..ff0150c 100644 --- a/rnex-core/src/util.rs +++ b/rnex-core/src/util.rs @@ -81,7 +81,9 @@ impl SplittableBufferConnection { } } } - stream.shutdown().await; + if let Err(e) = stream.shutdown().await{ + error!("failed to shut down stream: {}", e); + } }); } diff --git a/rnex-core/src/web/mod.rs b/rnex-core/src/web/mod.rs index cd2bcf2..9412967 100644 --- a/rnex-core/src/web/mod.rs +++ b/rnex-core/src/web/mod.rs @@ -13,7 +13,7 @@ struct RnexApiAuth; impl<'r> FromRequest<'r> for RnexApiAuth{ type Error = (); - async fn from_request<'a>(request: &'r Request<'a>) -> Outcome { + async fn from_request<'a>(_request: &'r Request<'a>) -> Outcome { Outcome::Success(RnexApiAuth) } } From d7f1ee404080ff169a9ff620fdbf8908688d8139 Mon Sep 17 00:00:00 2001 From: Maple Date: Wed, 5 Nov 2025 21:54:47 +0100 Subject: [PATCH 006/203] update ci --- .gitlab-ci.yml | 33 +++++++++++++++++++++------------ Dockerfile | 26 ++++++++++++++++++++------ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 56c6940..02de8a8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,19 +1,28 @@ -image: docker:latest +default: + image: quay.io/podman/stable variables: - IMAGE_NAME: "ci.perditum.com/perditum/rnex-splatoon" + DOCKER_TLS_CERTDIR: "/certs" IMAGE_TAG: "${CI_COMMIT_REF_SLUG}" -before_script: - - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" ci.perditum.com - stages: - - build-and-push + - test + - build-and-push-image + - push-retagged-branch + - push-retagged-latest -build-and-push: - stage: build-and-push +build-and-push-image: + stage: build-and-push-image script: - - docker build -t "$IMAGE_NAME:$IMAGE_TAG" . - - docker tag "$IMAGE_NAME:$IMAGE_TAG" "$IMAGE_NAME:latest" - - docker push "$IMAGE_NAME:$IMAGE_TAG" - - docker push "$IMAGE_NAME:latest" + - git submodule update --init + - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - podman build -t "$CI_REGISTRY_IMAGE/node-holder:$CI_COMMIT_SHORT_SHA" --target=node-holder . + - podman build -t "$CI_REGISTRY_IMAGE/proxy-secure-v1:$CI_COMMIT_SHORT_SHA" --target=proxy-secure-v1 . + - podman build -t "$CI_REGISTRY_IMAGE/proxy-insecure-v1:$CI_COMMIT_SHORT_SHA" --target=proxy-insecure-v1 . + - podman build -t "$CI_REGISTRY_IMAGE/backend-auth:$CI_COMMIT_SHORT_SHA" --target=backend-auth . + - podman build -t "$CI_REGISTRY_IMAGE/backend-secure:$CI_COMMIT_SHORT_SHA" --target=backend-secure . + - podman push "$CI_REGISTRY_IMAGE/node-holder:$CI_COMMIT_SHORT_SHA" + - podman push "$CI_REGISTRY_IMAGE/proxy-secure-v1:$CI_COMMIT_SHORT_SHA" + - podman push "$CI_REGISTRY_IMAGE/proxy-insecure-v1:$CI_COMMIT_SHORT_SHA" + - podman push "$CI_REGISTRY_IMAGE/backend-auth:$CI_COMMIT_SHORT_SHA" + - podman push "$CI_REGISTRY_IMAGE/backend-secure:$CI_COMMIT_SHORT_SHA" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 74f7efd..5d32b23 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,12 +9,26 @@ RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-st RUN git submodule update --init --recursive RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo test --target x86_64-unknown-linux-musl -RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --profile prod --target x86_64-unknown-linux-musl +RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --profile prod --target x86_64-unknown-linux-musl # -FROM scratch AS final +FROM scratch AS node-holder +COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/edge_node_holder_server /edge_node_holder_server +ENTRYPOINT ["/edge_node_holder_server"] -# Copy the compiled binary from the builder stage -COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/splatoon-server-rust /splatoon-server-rust -# Command to run the application -ENTRYPOINT ["/splatoon-server-rust"] +FROM scratch AS proxy-insecure-v1 +COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/proxy_insecure /proxy_insecure +ENTRYPOINT ["/proxy_insecure"] + +FROM scratch AS proxy-secure-v1 +COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/proxy_secure /proxy_secure +ENTRYPOINT ["/proxy_secure"] + + +FROM scratch AS backend-auth +COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/backend_server_insecure /backend_server_insecure +ENTRYPOINT ["/backend_server_secure"] + +FROM scratch AS backend-secure +COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/backend_server_secure /backend_server_secure +ENTRYPOINT ["/backend_server_secure"] From 58eecef9058e464e9a718ce60032bab0326eff2a Mon Sep 17 00:00:00 2001 From: Maple Date: Wed, 5 Nov 2025 21:57:57 +0100 Subject: [PATCH 007/203] fix ci --- rnex-core/src/grpc/account.rs | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/rnex-core/src/grpc/account.rs b/rnex-core/src/grpc/account.rs index d369501..5f49cbd 100644 --- a/rnex-core/src/grpc/account.rs +++ b/rnex-core/src/grpc/account.rs @@ -136,21 +136,4 @@ impl Client{ Ok(response) } } -*/ -#[cfg(test)] -mod test{ - use crate::grpc::account::Client; - - #[tokio::test] - async fn test(){ - dotenv::dotenv().ok(); - - let mut client = Client::new().await.unwrap(); - - let cli = client.get_nex_password(1699562916).await.unwrap(); - - println!("{:?}", cli); - } - - -} \ No newline at end of file +*/ \ No newline at end of file From b8e24686db474bfa30b108652016b2f31937a7db Mon Sep 17 00:00:00 2001 From: Maple Date: Wed, 5 Nov 2025 22:03:03 +0100 Subject: [PATCH 008/203] disable doctests for macros --- macros/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/macros/Cargo.toml b/macros/Cargo.toml index d0bb83b..dca135c 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" [lib] proc-macro = true +doctest = false [dependencies] quote = "1.0.38" From c978ee8e8482e15a319977e30f28655abd287413 Mon Sep 17 00:00:00 2001 From: Maple Date: Wed, 5 Nov 2025 22:09:43 +0100 Subject: [PATCH 009/203] remove prod profile from dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5d32b23..f482893 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-st RUN git submodule update --init --recursive RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo test --target x86_64-unknown-linux-musl -RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --profile prod --target x86_64-unknown-linux-musl # +RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --target x86_64-unknown-linux-musl # FROM scratch AS node-holder COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/edge_node_holder_server /edge_node_holder_server From d008859ad433776fb2fc8254dc7bd51bcdfc8c8a Mon Sep 17 00:00:00 2001 From: Maple Date: Wed, 5 Nov 2025 22:13:56 +0100 Subject: [PATCH 010/203] fix dockerfile --- Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index f482893..422eacb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,23 +12,23 @@ RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_ST RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --target x86_64-unknown-linux-musl # FROM scratch AS node-holder -COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/edge_node_holder_server /edge_node_holder_server +COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/edge_node_holder_server /edge_node_holder_server ENTRYPOINT ["/edge_node_holder_server"] FROM scratch AS proxy-insecure-v1 -COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/proxy_insecure /proxy_insecure +COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_insecure /proxy_insecure ENTRYPOINT ["/proxy_insecure"] FROM scratch AS proxy-secure-v1 -COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/proxy_secure /proxy_secure +COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_secure /proxy_secure ENTRYPOINT ["/proxy_secure"] FROM scratch AS backend-auth -COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/backend_server_insecure /backend_server_insecure +COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server_insecure /backend_server_insecure ENTRYPOINT ["/backend_server_secure"] FROM scratch AS backend-secure -COPY --from=builder /app/target/x86_64-unknown-linux-musl/prod/backend_server_secure /backend_server_secure +COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server_secure /backend_server_secure ENTRYPOINT ["/backend_server_secure"] From 41955a7e21a3bf22a350529fef9230c8a428ed65 Mon Sep 17 00:00:00 2001 From: Maple Date: Wed, 5 Nov 2025 22:21:17 +0100 Subject: [PATCH 011/203] build for release --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 422eacb..c65fcff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-st RUN git submodule update --init --recursive RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo test --target x86_64-unknown-linux-musl -RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --target x86_64-unknown-linux-musl # +RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --target x86_64-unknown-linux-musl # FROM scratch AS node-holder COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/edge_node_holder_server /edge_node_holder_server From d352e7537cdd9140be343868ed916a62315806f7 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Wed, 5 Nov 2025 22:47:06 +0100 Subject: [PATCH 012/203] add dev container and default ip --- Dockerfile | 11 ++++++++--- devcontainer.json | 3 +++ rnex-core/src/executables/common.rs | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 devcontainer.json diff --git a/Dockerfile b/Dockerfile index c65fcff..30cd59f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,13 @@ -FROM rust:alpine AS builder +FROM rust:alpine AS dev-container + +RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static + +FROM dev-container as builder WORKDIR /app COPY . . -RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static - RUN git submodule update --init --recursive RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo test --target x86_64-unknown-linux-musl @@ -32,3 +34,6 @@ ENTRYPOINT ["/backend_server_secure"] FROM scratch AS backend-secure COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server_secure /backend_server_secure ENTRYPOINT ["/backend_server_secure"] + +# make sure the final output container is the dev container so that we can use it from the devcontainer.json +FROM final as dev-container diff --git a/devcontainer.json b/devcontainer.json new file mode 100644 index 0000000..a1447f1 --- /dev/null +++ b/devcontainer.json @@ -0,0 +1,3 @@ +{ + "build": { "dockerfile": "Dockerfile" } +} diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index f12a84c..5697d7c 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -6,8 +6,8 @@ use crate::nex::account::Account; pub static OWN_IP_PRIVATE: Lazy = Lazy::new(|| { env::var("SERVER_IP") .ok() - .and_then(|s| s.parse().ok()) - .expect("SERVER_IP not specified") + .map(|s| s.parse().expect("invalid ip address")) + .unwrap_or(Ipv4Addr::UNSPECIFIED) }); pub static OWN_IP_PUBLIC: Lazy = Lazy::new(|| { From d8e53407bcedcbb1308d6ae2ad34d375fe542388 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Wed, 5 Nov 2025 22:50:51 +0100 Subject: [PATCH 013/203] fix devcontainer --- devcontainer.json => .devcontainer.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename devcontainer.json => .devcontainer.json (100%) diff --git a/devcontainer.json b/.devcontainer.json similarity index 100% rename from devcontainer.json rename to .devcontainer.json From 3672e0194406136a6f69be9b12866760c657af0e Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Wed, 5 Nov 2025 22:53:32 +0100 Subject: [PATCH 014/203] fix dockerfile --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 30cd59f..4463896 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM rust:alpine AS dev-container RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static -FROM dev-container as builder +FROM dev-container AS builder WORKDIR /app @@ -36,4 +36,4 @@ COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server ENTRYPOINT ["/backend_server_secure"] # make sure the final output container is the dev container so that we can use it from the devcontainer.json -FROM final as dev-container +FROM dev-container AS final From 66d323fe731422642949a15e67cfff8667c2b7b1 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Thu, 6 Nov 2025 22:22:37 +0100 Subject: [PATCH 015/203] add devcontainer build to ci --- .devcontainer.json | 2 +- .gitlab-ci.yml | 6 +++--- Dockerfile | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.devcontainer.json b/.devcontainer.json index a1447f1..ac711b7 100644 --- a/.devcontainer.json +++ b/.devcontainer.json @@ -1,3 +1,3 @@ { - "build": { "dockerfile": "Dockerfile" } + "image": "ci.virintox.com/spfn/rust-nex/dev-container:latest" } diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 02de8a8..24011c9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,14 +8,14 @@ variables: stages: - test - build-and-push-image - - push-retagged-branch - - push-retagged-latest build-and-push-image: stage: build-and-push-image script: - git submodule update --init - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - podman build -t "$CI_REGISTRY_IMAGE/dev-container:latest" --target=dev-container . + - podman push "$CI_REGISTRY_IMAGE/dev-container:latest" - podman build -t "$CI_REGISTRY_IMAGE/node-holder:$CI_COMMIT_SHORT_SHA" --target=node-holder . - podman build -t "$CI_REGISTRY_IMAGE/proxy-secure-v1:$CI_COMMIT_SHORT_SHA" --target=proxy-secure-v1 . - podman build -t "$CI_REGISTRY_IMAGE/proxy-insecure-v1:$CI_COMMIT_SHORT_SHA" --target=proxy-insecure-v1 . @@ -25,4 +25,4 @@ build-and-push-image: - podman push "$CI_REGISTRY_IMAGE/proxy-secure-v1:$CI_COMMIT_SHORT_SHA" - podman push "$CI_REGISTRY_IMAGE/proxy-insecure-v1:$CI_COMMIT_SHORT_SHA" - podman push "$CI_REGISTRY_IMAGE/backend-auth:$CI_COMMIT_SHORT_SHA" - - podman push "$CI_REGISTRY_IMAGE/backend-secure:$CI_COMMIT_SHORT_SHA" \ No newline at end of file + - podman push "$CI_REGISTRY_IMAGE/backend-secure:$CI_COMMIT_SHORT_SHA" diff --git a/Dockerfile b/Dockerfile index 4463896..c3b8a2c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM rust:alpine AS dev-container RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static -FROM dev-container AS builder +FROM build-container AS builder WORKDIR /app @@ -36,4 +36,5 @@ COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server ENTRYPOINT ["/backend_server_secure"] # make sure the final output container is the dev container so that we can use it from the devcontainer.json -FROM dev-container AS final +FROM build-container AS dev-container +RUN apk add openjdk21-jdk gcompat From 79835a1e199a0caed5ffbefcfd4ff761c27998bb Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Thu, 6 Nov 2025 22:25:17 +0100 Subject: [PATCH 016/203] fix dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c3b8a2c..0438d5e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:alpine AS dev-container +FROM rust:alpine AS build-container RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static From e2b564cc48cfecacb3b0a68ae01de705536871af Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Thu, 6 Nov 2025 22:55:41 +0000 Subject: [PATCH 017/203] add public ip inferrence --- Cargo.lock | 2 ++ rnex-core/Cargo.toml | 2 +- rnex-core/src/executables/common.rs | 16 ++++++++++++++-- rnex-core/src/prudp/socket_addr.rs | 1 - 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb9c740..82797de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1663,7 +1663,9 @@ dependencies = [ "base64", "bytes", "encoding_rs", + "futures-channel", "futures-core", + "futures-util", "h2 0.4.11", "http 1.3.1", "http-body 1.0.1", diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index b41bc8d..90ce871 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -26,7 +26,7 @@ rocket = { version = "0.5.1", features = ["json", "serde_json"] } async-trait = "0.1.86" paste = "1.0.15" typenum = "1.18.0" -reqwest = "0.12.18" +reqwest = { version= "0.12.18", features = ["blocking"]} json = "0.12.4" ctrlc = "3.4.7" diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index 5697d7c..0c553b4 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -2,6 +2,16 @@ use std::env; use std::net::Ipv4Addr; use once_cell::sync::Lazy; use crate::nex::account::Account; +use std::error::Error; + +const IP_REQ_SERVICE_URL: &str = "https://ipinfo.io/ip"; + + + +fn try_get_ip() -> Result> { + let req = reqwest::blocking::get(IP_REQ_SERVICE_URL)?; + Ok(req.text()?.parse()?) +} pub static OWN_IP_PRIVATE: Lazy = Lazy::new(|| { env::var("SERVER_IP") @@ -13,8 +23,10 @@ pub static OWN_IP_PRIVATE: Lazy = Lazy::new(|| { pub static OWN_IP_PUBLIC: Lazy = Lazy::new(|| { env::var("SERVER_IP_PUBLIC") .ok() - .and_then(|s| s.parse().ok()) - .expect("SERVER_IP_PUBLIC not specified") + .map(|s| s.parse().expect("invalid ip address")) + .unwrap_or_else(||{ + try_get_ip().unwrap() + }) }); pub static SERVER_PORT: Lazy = Lazy::new(|| { diff --git a/rnex-core/src/prudp/socket_addr.rs b/rnex-core/src/prudp/socket_addr.rs index 5c55e88..f5eb179 100644 --- a/rnex-core/src/prudp/socket_addr.rs +++ b/rnex-core/src/prudp/socket_addr.rs @@ -17,7 +17,6 @@ pub struct PRUDPSockAddr{ impl PRUDPSockAddr{ - pub fn new(regular_socket_addr: SocketAddrV4, virtual_port: VirtualPort) -> Self{ Self{ regular_socket_addr, From a64699442ee7ad6c65bbc4d9ac0674dc5507ad44 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Fri, 7 Nov 2025 18:06:22 +0000 Subject: [PATCH 018/203] fix auth backend in dockerfile --- Dockerfile | 6 +++--- rnex-core/src/grpc/mod.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0438d5e..70d1b46 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,11 +25,11 @@ ENTRYPOINT ["/proxy_insecure"] FROM scratch AS proxy-secure-v1 COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_secure /proxy_secure ENTRYPOINT ["/proxy_secure"] - - + + FROM scratch AS backend-auth COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server_insecure /backend_server_insecure -ENTRYPOINT ["/backend_server_secure"] +ENTRYPOINT ["/backend_server_insecure"] FROM scratch AS backend-secure COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server_secure /backend_server_secure diff --git a/rnex-core/src/grpc/mod.rs b/rnex-core/src/grpc/mod.rs index 16cb73b..31831f8 100644 --- a/rnex-core/src/grpc/mod.rs +++ b/rnex-core/src/grpc/mod.rs @@ -4,5 +4,5 @@ //! This WILL be deprecated as soon as account rs is in a stable state. use tonic::{Request, Status}; -type InterceptorFunc = Box<(dyn Fn(Request<()>) -> Result, Status> + Send)>; +type InterceptorFunc = Box) -> Result, Status> + Send>; pub mod account; \ No newline at end of file From d5b1be28fcf003218de9b18046ca6f88c6a90e8e Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Fri, 7 Nov 2025 18:37:28 +0000 Subject: [PATCH 019/203] fix ssl --- Dockerfile | 2 +- rnex-core/src/executables/backend_server_insecure.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 70d1b46..5b89318 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM rust:alpine AS build-container -RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static +RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static ca-certificates FROM build-container AS builder diff --git a/rnex-core/src/executables/backend_server_insecure.rs b/rnex-core/src/executables/backend_server_insecure.rs index 7a9f88a..2997864 100644 --- a/rnex-core/src/executables/backend_server_insecure.rs +++ b/rnex-core/src/executables/backend_server_insecure.rs @@ -21,7 +21,7 @@ pub static FORWARD_EDGE_NODE_HOLDER: Lazy = Lazy::new(||{ env::var("FORWARD_EDGE_NODE_HOLDER") .ok() .and_then(|s| s.parse().ok()) - .expect("SECURE_EDGE_NODE_HOLDER not set") + .expect("FORWARD_EDGE_NODE_HOLDER not set") }); From e840d5c6198cd33f672bbf79c5c1f71c52daaf6e Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Fri, 7 Nov 2025 18:42:15 +0000 Subject: [PATCH 020/203] actually fix ca issues --- Dockerfile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5b89318..f1ea22f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM rust:alpine AS build-container -RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static ca-certificates +RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static FROM build-container AS builder @@ -18,12 +18,16 @@ COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/edge_node_hold ENTRYPOINT ["/edge_node_holder_server"] -FROM scratch AS proxy-insecure-v1 +FROM alpine:latest AS proxy-insecure-v1 COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_insecure /proxy_insecure +RUN apk add --no-cache ca-certificates +RUN update-ca-certificates ENTRYPOINT ["/proxy_insecure"] -FROM scratch AS proxy-secure-v1 +FROM alpine:latest AS proxy-secure-v1 COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_secure /proxy_secure +RUN apk add --no-cache ca-certificates +RUN update-ca-certificates ENTRYPOINT ["/proxy_secure"] From f5b30496d757aedf5f7995d30c11563de74bf06e Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Sat, 8 Nov 2025 12:04:39 +0000 Subject: [PATCH 021/203] make sending data actually reliable --- prudpv1/src/prudp/socket.rs | 185 +++++++++++++++++++------ rnex-core/src/rmc/protocols/ranking.rs | 30 ++++ 2 files changed, 169 insertions(+), 46 deletions(-) diff --git a/prudpv1/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs index 4aca993..d44c97b 100644 --- a/prudpv1/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -10,7 +10,11 @@ use async_trait::async_trait; use log::info; use log::error; use rc4::StreamCipher; +use rnex_core::rmc::structures::qbuffer::QBuffer; +use v_byte_helpers::ReadExtensions; +use v_byte_helpers::little_endian::{read_u16, read_u32}; use std::collections::{BTreeMap, HashMap}; +use std::io::Cursor; use std::marker::PhantomData; use std::ops::Deref; use std::sync::{Arc, Weak}; @@ -51,12 +55,14 @@ struct InternalConnection { connections: Weak>>>>>, reliable_server_counter: u16, reliable_client_counter: u16, + supported_function_version: u32, // maybe add connection id(need to see if its even needed) crypto_handler_instance: E, data_sender: Sender>, socket: Arc, packet_queue: HashMap, last_packet_time: Instant, + unacknowleged_packets: Vec<(Instant, PRUDPV1Packet)> } impl Deref for InternalConnection { @@ -67,6 +73,7 @@ impl Deref for InternalConnection { } impl InternalConnection { + /// gives back the next server packet sequence id which the client expects to send, incrementing it in the process fn next_server_count(&mut self) -> u16 { let prev_val = self.reliable_server_counter; let (val, _) = self.reliable_server_counter.overflowing_add(1); @@ -75,20 +82,15 @@ impl InternalConnection { prev_val } + /// Sends a raw packet to a given client on the connection + /// + /// a raw packet is one which does not get processed any further(other than to send it + /// off without buffering or anything), + /// as such you need to make sure that + /// the sizes are set correctly and so on #[inline] - async fn send_raw_packet(&self, mut prudp_packet: PRUDPV1Packet) { - prudp_packet.set_sizes(); - - let mut vec = Vec::new(); - - prudp_packet - .write_to(&mut vec) - .expect("somehow failed to convert backet to bytes"); - - self.socket - .send_to(&vec, self.socket_addr.regular_socket_addr) - .await - .expect("failed to send data back"); + async fn send_raw_packet(&self, prudp_packet: &PRUDPV1Packet) { + send_raw_prudp_to_sockaddr(&self.socket, self.socket_addr, prudp_packet).await; } } @@ -196,7 +198,9 @@ impl AnyInternalConnection for InternalConne self.crypto_handler_instance.sign_packet(&mut packet); - self.send_raw_packet(packet).await; + self.send_raw_packet(&packet).await; + + self.unacknowleged_packets.push((Instant::now(), packet)); } async fn close_connection(&mut self) { @@ -223,7 +227,7 @@ impl AnyInternalConnection for InternalConne self.crypto_handler_instance.sign_packet(&mut packet); - self.send_raw_packet(packet).await; + self.send_raw_packet(&packet).await; let Some(conns) = self.connections.upgrade() else { // this is fine as it implies the server has already quit, thus meaning that we dont @@ -240,6 +244,19 @@ impl AnyInternalConnection for InternalConne } } +async fn send_raw_prudp_to_sockaddr(udp_socket: &UdpSocket, dest: PRUDPSockAddr, packet: &PRUDPV1Packet){ + let mut vec = Vec::new(); + + packet + .write_to(&mut vec) + .expect("somehow failed to convert backet to bytes"); + + udp_socket + .send_to(&vec, dest.regular_socket_addr) + .await + .expect("failed to send data back"); +} + impl InternalSocket { async fn get_connection( &self, @@ -257,19 +274,12 @@ impl InternalSocket { Some(conn) } - async fn send_packet_unbuffered(&self, dest: PRUDPSockAddr, mut packet: PRUDPV1Packet) { - packet.set_sizes(); - - let mut vec = Vec::new(); - - packet - .write_to(&mut vec) - .expect("somehow failed to convert backet to bytes"); - - self.socket - .send_to(&vec, dest.regular_socket_addr) - .await - .expect("failed to send data back"); + /// sends a raw packet to a specific prudp socket address + /// + /// a raw packet is a packet is a packet which wont get processed any further, + /// sizes signatures etc need to be set before using this function + async fn send_packet_unbuffered(&self, dest: PRUDPSockAddr, packet: &PRUDPV1Packet) { + send_raw_prudp_to_sockaddr(&self.socket, dest, packet).await } async fn handle_syn(&self, address: PRUDPSockAddr, packet: PRUDPV1Packet) { @@ -304,7 +314,7 @@ impl InternalSocket { //println!("got syn: {:?}", response); - self.send_packet_unbuffered(address, response).await; + self.send_packet_unbuffered(address, &response).await; } async fn connection_thread( @@ -316,7 +326,7 @@ impl InternalSocket { let mut conn = conn.lock().await; if conn.last_packet_time < (Instant::now() - Duration::from_secs(5)) { - conn.send_raw_packet(PRUDPV1Packet { + conn.send_raw_packet(&PRUDPV1Packet { header: PRUDPV1Header { sequence_id: 0, substream_id: 0, @@ -336,9 +346,17 @@ impl InternalSocket { if conn.last_packet_time < (Instant::now() - Duration::from_secs(30)) { conn.close_connection().await; } + + for (send_time, packet) in &conn.unacknowleged_packets{ + if *send_time < (Instant::now() - Duration::from_millis(500)){ + info!("unacknowledged packet sat arround for more than 500 ms, resending"); + conn.send_raw_packet(packet).await; + } + } + drop(conn); - sleep(Duration::from_secs(5)).await; + sleep(Duration::from_millis(500)).await; } } @@ -348,6 +366,7 @@ impl InternalSocket { socket_addr: PRUDPSockAddr, session_id: u8, is_instantiator: bool, + supported_function_version: u32, ) { let common = Arc::new(CommonConnection { user_id: crypto_handler_instance.get_user_id(), @@ -368,6 +387,8 @@ impl InternalSocket { socket: self.socket.clone(), packet_queue: Default::default(), last_packet_time: Instant::now(), + unacknowleged_packets: Vec::new(), + supported_function_version }; let internal = Arc::new(Mutex::new(internal)); @@ -445,12 +466,17 @@ impl InternalSocket { .options .push(ConnectionSignature(Default::default())); + let mut functions: u32 = 0; + for option in &packet.options { match option { MaximumSubstreamId(max_substream) => { response.options.push(MaximumSubstreamId(*max_substream)) } - SupportedFunctions(funcs) => response.options.push(SupportedFunctions(*funcs & 0xFF)), + SupportedFunctions(funcs) => { + functions = *funcs & 0xFF; + response.options.push(SupportedFunctions(*funcs & 0xFF)); + }, _ => { /* ? */ } } } @@ -461,10 +487,10 @@ impl InternalSocket { //println!("connect out: {:?}", response); - self.create_connection(crypto, address, session_id, false) + self.create_connection(crypto, address, session_id, false, functions) .await; - self.send_packet_unbuffered(address, response).await; + self.send_packet_unbuffered(address, &response).await; } async fn handle_data(&self, address: PRUDPSockAddr, packet: PRUDPV1Packet) { @@ -503,7 +529,7 @@ impl InternalSocket { conn.crypto_handler_instance.sign_packet(&mut response); - self.send_packet_unbuffered(address, response).await; + self.send_packet_unbuffered(address, &response).await; conn.data_sender.send(packet.payload).await.ok(); @@ -529,7 +555,7 @@ impl InternalSocket { conn.crypto_handler_instance.sign_packet(&mut response); - self.send_packet_unbuffered(address, response).await; + self.send_packet_unbuffered(address, &response).await; } async fn handle_disconnect(&self, address: PRUDPSockAddr, packet: PRUDPV1Packet) { @@ -549,9 +575,9 @@ impl InternalSocket { conn.crypto_handler_instance.sign_packet(&mut response); - self.send_packet_unbuffered(address, response.clone()).await; - self.send_packet_unbuffered(address, response.clone()).await; - self.send_packet_unbuffered(address, response).await; + self.send_packet_unbuffered(address, &response).await; + self.send_packet_unbuffered(address, &response).await; + self.send_packet_unbuffered(address, &response).await; //self.internal_connections.lock().await; } @@ -572,7 +598,7 @@ impl AnyInternalSocket for InternalSocket { if (packet.header.types_and_flags.get_flags() & ACK) != 0 { info!("got ack"); - + if packet.header.types_and_flags.get_types() == SYN || packet.header.types_and_flags.get_types() == CONNECT { @@ -597,13 +623,76 @@ impl AnyInternalSocket for InternalSocket { } else { error!("got connection response without the active reciever being present"); } + return; + } + + if let Some(conn) = self.get_connection(address).await { + let mut conn = conn.lock().await; + + // remove the packet whose sequence id matches the ack packet + // or in other words keep all of those which dont match the sequence id + conn.unacknowleged_packets.retain_mut(|v| { + packet.header.sequence_id != v.1.header.sequence_id + }); + } else { + error!("non connection acknowledgement packet on nonexistent connection...") } return; } if (packet.header.types_and_flags.get_flags() & MULTI_ACK) != 0 { - info!("got multi ack"); + if let Some(conn) = self.get_connection(address).await { + let mut conn = conn.lock().await; + + if conn.supported_function_version == 1{ + let mut collected_ids: Vec = Vec::new(); + let mut cursor = Cursor::new(&packet.payload); + + while let Ok(v) = read_u16(&mut cursor){ + collected_ids.push(v); + } + + conn.unacknowleged_packets.retain_mut(|(_, up)| { + !( + collected_ids.iter().any(|id| up.header.sequence_id == *id) || + up.header.sequence_id < packet.header.sequence_id + ) + }); + + } else { + let mut collected_ids: Vec = Vec::new(); + let mut cursor = Cursor::new(&packet.payload); + + let Ok(_substream_id): Result = cursor.read_le_struct() else{ + error!("invalid data whilest reading new version agregate acknowledgement"); + return; + }; + let Ok(additional_sequence_ids): Result = cursor.read_le_struct() else { + error!("invalid data whilest reading new version agregate acknowledgement"); + return; + }; + let Ok(sequence_id): Result = cursor.read_le_struct() else { + error!("invalid data whilest reading new version agregate acknowledgement"); + return; + }; + for _ in 0..additional_sequence_ids{ + let Ok(additional_sequence_id): Result = cursor.read_le_struct() else { + error!("invalid data whilest reading new version agregate acknowledgement"); + return; + }; + collected_ids.push(additional_sequence_id); + conn.unacknowleged_packets.retain_mut(|(_, up)| { + !( + collected_ids.iter().any(|id| up.header.sequence_id == *id) || + up.header.sequence_id < sequence_id + ) + }); + } + } + } else { + error!("non connection acknowledgement packet on nonexistent connection...") + } return; } @@ -631,7 +720,7 @@ impl AnyInternalSocket for InternalSocket { let remote_signature = address.calculate_connection_signature(); - let packet = PRUDPV1Packet { + let mut packet = PRUDPV1Packet { header: PRUDPV1Header { source_port: self.virtual_port, destination_port: address.virtual_port, @@ -646,7 +735,9 @@ impl AnyInternalSocket for InternalSocket { ..Default::default() }; - self.send_packet_unbuffered(address, packet).await; + packet.set_sizes(); + + self.send_packet_unbuffered(address, &packet).await; let Some(syn_ack_packet) = recv.recv().await else { error!("what"); @@ -662,7 +753,7 @@ impl AnyInternalSocket for InternalSocket { return None; }; - let packet = PRUDPV1Packet { + let mut packet = PRUDPV1Packet { header: PRUDPV1Header { source_port: self.virtual_port, destination_port: address.virtual_port, @@ -677,7 +768,9 @@ impl AnyInternalSocket for InternalSocket { ..Default::default() }; - self.send_packet_unbuffered(address, packet).await; + packet.set_sizes(); + + self.send_packet_unbuffered(address, &packet).await; let Some(_connect_ack_packet) = recv.recv().await else { error!("what"); @@ -689,7 +782,7 @@ impl AnyInternalSocket for InternalSocket { .instantiate(remote_signature, *own_signature, &[], 1)?; //todo: make this work for secure servers as well - self.create_connection(crypt, address, 0, true).await; + self.create_connection(crypt, address, 0, true, 4).await; Some(()) } diff --git a/rnex-core/src/rmc/protocols/ranking.rs b/rnex-core/src/rmc/protocols/ranking.rs index 298922f..d5746e9 100644 --- a/rnex-core/src/rmc/protocols/ranking.rs +++ b/rnex-core/src/rmc/protocols/ranking.rs @@ -1,5 +1,35 @@ use macros::rmc_proto; +use crate::rmc::response::ErrorCode; +use macros::{method_id, rmc_struct, RmcSerialize}; + +#[derive(RmcSerialize, Debug, Default, Clone)] +struct ResultsRange{ + offset: u32, + size: u32 +} + +#[derive(RmcSerialize, Debug, Default, Clone)] +#[rmc_struct(1)] +struct CompetitionRankingGetParam{ + unk: u32, + range: ResultsRange, + festival_ids: Vec, +} + +#[derive(RmcSerialize, Debug, Default, Clone)] +#[rmc_struct(0)] +struct CompetitionRankingScoreInfo{ + fest_id: u32, + score_data: Vec, + unk: u32, + team_wins: Vec, + team_votes: Vec +} + + #[rmc_proto(112)] pub trait Ranking{ + //#[method_id(16)] + //async fn competition_ranking_get_param(&self, param: CompetitionRankingGetParam) -> Result,ErrorCode>; } \ No newline at end of file From f264f34a18faef214c104a40661ab4157892b82d Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Sat, 8 Nov 2025 12:17:21 +0000 Subject: [PATCH 022/203] add debugging to packet acknowledgements --- prudpv1/src/prudp/socket.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/prudpv1/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs index d44c97b..f5fb448 100644 --- a/prudpv1/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -4,6 +4,7 @@ use crate::prudp::packet::PacketOption::{ ConnectionSignature, FragmentId, MaximumSubstreamId, SupportedFunctions, }; use crate::prudp::packet::{PRUDPV1Header, PRUDPV1Packet, TypesFlags}; +use md5::digest::generic_array::sequence; use rnex_core::prudp::virtual_port::VirtualPort; use rnex_core::prudp::socket_addr::PRUDPSockAddr; use async_trait::async_trait; @@ -626,6 +627,8 @@ impl AnyInternalSocket for InternalSocket { return; } + info!("got ack"); + if let Some(conn) = self.get_connection(address).await { let mut conn = conn.lock().await; @@ -682,13 +685,18 @@ impl AnyInternalSocket for InternalSocket { return; }; collected_ids.push(additional_sequence_id); - conn.unacknowleged_packets.retain_mut(|(_, up)| { - !( - collected_ids.iter().any(|id| up.header.sequence_id == *id) || - up.header.sequence_id < sequence_id - ) - }); } + + println!("multiack new summary: \n\tup_till_id {}\n\tadditionals {:?}", sequence_id, collected_ids); + println!("pre size: {}", conn.unacknowleged_packets.len()); + + conn.unacknowleged_packets.retain_mut(|(_, up)| { + !( + collected_ids.iter().any(|id| up.header.sequence_id == *id) || + up.header.sequence_id < sequence_id + ) + }); + println!("post size: {}", conn.unacknowleged_packets.len()); } } else { error!("non connection acknowledgement packet on nonexistent connection...") From adae697154539e4f05176bad81a651dc74d7b972 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Sat, 8 Nov 2025 12:27:17 +0000 Subject: [PATCH 023/203] fix resending issues and remove debugging again --- prudpv1/src/prudp/socket.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/prudpv1/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs index f5fb448..3e88a70 100644 --- a/prudpv1/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -659,7 +659,7 @@ impl AnyInternalSocket for InternalSocket { conn.unacknowleged_packets.retain_mut(|(_, up)| { !( collected_ids.iter().any(|id| up.header.sequence_id == *id) || - up.header.sequence_id < packet.header.sequence_id + up.header.sequence_id <= packet.header.sequence_id ) }); @@ -687,16 +687,12 @@ impl AnyInternalSocket for InternalSocket { collected_ids.push(additional_sequence_id); } - println!("multiack new summary: \n\tup_till_id {}\n\tadditionals {:?}", sequence_id, collected_ids); - println!("pre size: {}", conn.unacknowleged_packets.len()); - conn.unacknowleged_packets.retain_mut(|(_, up)| { !( collected_ids.iter().any(|id| up.header.sequence_id == *id) || - up.header.sequence_id < sequence_id + up.header.sequence_id <= sequence_id ) }); - println!("post size: {}", conn.unacknowleged_packets.len()); } } else { error!("non connection acknowledgement packet on nonexistent connection...") From 6ea1518a9dcaf72d3621912483fc5de07a57e9b6 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Sat, 8 Nov 2025 13:00:23 +0000 Subject: [PATCH 024/203] clean up a bit --- prudpv1/src/prudp/socket.rs | 4 +- .../executables/backend_server_insecure.rs | 55 ++++-------------- .../src/executables/backend_server_secure.rs | 57 ++++--------------- rnex-core/src/executables/common.rs | 42 +++++++++++++- rnex-core/src/rmc/protocols/ranking.rs | 4 +- 5 files changed, 65 insertions(+), 97 deletions(-) diff --git a/prudpv1/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs index 3e88a70..d85948c 100644 --- a/prudpv1/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -4,16 +4,14 @@ use crate::prudp::packet::PacketOption::{ ConnectionSignature, FragmentId, MaximumSubstreamId, SupportedFunctions, }; use crate::prudp::packet::{PRUDPV1Header, PRUDPV1Packet, TypesFlags}; -use md5::digest::generic_array::sequence; use rnex_core::prudp::virtual_port::VirtualPort; use rnex_core::prudp::socket_addr::PRUDPSockAddr; use async_trait::async_trait; use log::info; use log::error; use rc4::StreamCipher; -use rnex_core::rmc::structures::qbuffer::QBuffer; use v_byte_helpers::ReadExtensions; -use v_byte_helpers::little_endian::{read_u16, read_u32}; +use v_byte_helpers::little_endian::read_u16; use std::collections::{BTreeMap, HashMap}; use std::io::Cursor; use std::marker::PhantomData; diff --git a/rnex-core/src/executables/backend_server_insecure.rs b/rnex-core/src/executables/backend_server_insecure.rs index 2997864..6b2625c 100644 --- a/rnex-core/src/executables/backend_server_insecure.rs +++ b/rnex-core/src/executables/backend_server_insecure.rs @@ -1,19 +1,15 @@ -use rnex_core::reggie::{RemoteEdgeNodeHolder, UnitPacketRead}; -use log::{error, info}; +use rnex_core::reggie::RemoteEdgeNodeHolder; use once_cell::sync::Lazy; use rnex_core::common::setup; -use std::{env}; -use std::io::Cursor; +use rnex_core::rmc::structures::RmcSerialize; +use std::env; use std::net::SocketAddrV4; use std::sync::Arc; -use tokio::net::{TcpListener, TcpStream}; -use tokio::task; -use rnex_core::executables::common::{OWN_IP_PRIVATE, SECURE_SERVER_ACCOUNT, SERVER_PORT}; +use tokio::net::TcpStream; +use rnex_core::executables::common::{SECURE_SERVER_ACCOUNT, new_simple_backend}; use rnex_core::nex::auth_handler::AuthHandler; use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister; use rnex_core::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; -use rnex_core::rmc::structures::RmcSerialize; -use rnex_core::rnex_proxy_common::ConnectionInitData; use rnex_core::util::SplittableBufferConnection; @@ -38,39 +34,12 @@ async fn main() { let conn = new_rmc_gateway_connection(conn, |r| Arc::new(OnlyRemote::::new(r))); - let listen = TcpListener::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)).await.unwrap(); - - - - while let Ok((mut stream, _addr)) = listen.accept().await { - let buffer = match stream.read_buffer().await{ - Ok(v) => v, - Err(e) => { - error!("an error ocurred whilest reading connection data buffer: {:?}", e); - continue; - } - }; - - let user_connection_data = ConnectionInitData::deserialize(&mut Cursor::new(buffer)); - - let _user_connection_data = match user_connection_data{ - Ok(v) => v, - Err(e) => { - error!("an error ocurred whilest reading connection data: {:?}", e); - continue; - } - }; + new_simple_backend(move |_, _|{ let controller = conn.clone(); - task::spawn(async move { - info!("connection to secure backend established"); - new_rmc_gateway_connection(stream.into(), |_| { - Arc::new(AuthHandler { - destination_server_acct: &SECURE_SERVER_ACCOUNT, - build_name: "branch:origin/project/wup-agmj build:3_8_15_2004_0", - control_server: controller - }) - }); - }); - - } + Arc::new(AuthHandler { + destination_server_acct: &SECURE_SERVER_ACCOUNT, + build_name: "branch:origin/project/wup-agmj build:3_8_15_2004_0", + control_server: controller + }) + }).await; } diff --git a/rnex-core/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs index 82d1a39..1488369 100644 --- a/rnex-core/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -1,26 +1,16 @@ -use std::io::Cursor; -use rnex_core::rmc::structures::RmcSerialize; -use rnex_core::reggie::UnitPacketRead; -use std::net::SocketAddrV4; use std::sync::Arc; use std::sync::atomic::AtomicU32; -use log::{error, info}; -use tokio::net::TcpListener; -use tokio::task; use rnex_core::common::setup; -use rnex_core::executables::common::{OWN_IP_PRIVATE, SERVER_PORT}; +use rnex_core::executables::common::{new_simple_backend}; use rnex_core::nex::matchmake::MatchmakeManager; use rnex_core::nex::remote_console::RemoteConsole; use rnex_core::nex::user::User; -use rnex_core::rmc::protocols::new_rmc_gateway_connection; -use rnex_core::rnex_proxy_common::ConnectionInitData; use rnex_core::rmc::protocols::RemoteInstantiatable; #[tokio::main] async fn main() { setup(); - let listen = TcpListener::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)).await.unwrap(); let mmm = Arc::new(MatchmakeManager{ gid_counter: AtomicU32::new(1), @@ -33,40 +23,15 @@ async fn main() { MatchmakeManager::initialize_garbage_collect_thread(weak_mmm).await; - while let Ok((mut stream, _addr)) = listen.accept().await { - let buffer = match stream.read_buffer().await{ - Ok(v) => v, - Err(e) => { - error!("an error ocurred whilest reading connection data buffer: {:?}", e); - continue; - } - }; - - let user_connection_data = ConnectionInitData::deserialize(&mut Cursor::new(buffer)); - - let user_connection_data = match user_connection_data{ - Ok(v) => v, - Err(e) => { - error!("an error ocurred whilest reading connection data: {:?}", e); - continue; - } - }; - - + new_simple_backend(move |c, r|{ let mmm = mmm.clone(); - task::spawn(async move { - info!("connection to secure backend established"); - new_rmc_gateway_connection(stream.into(), |r| { - Arc::new_cyclic(|this| User{ - this: this.clone(), - ip: user_connection_data.prudpsock_addr, - pid: user_connection_data.pid, - remote: RemoteConsole::new(r), - matchmake_manager: mmm, - station_url: Default::default() - }) - }); - }); - - } + Arc::new_cyclic(move |this| User{ + this: this.clone(), + ip: c.prudpsock_addr, + pid:c.pid, + remote: RemoteConsole::new(r), + matchmake_manager: mmm, + station_url: Default::default() + }) + }).await; } \ No newline at end of file diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index 0c553b4..73571d7 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -1,8 +1,18 @@ use std::env; -use std::net::Ipv4Addr; +use std::io::Cursor; +use std::net::{Ipv4Addr, SocketAddrV4}; +use std::sync::Arc; use once_cell::sync::Lazy; -use crate::nex::account::Account; +use rnex_core::nex::account::Account; +use rnex_core::rmc::protocols::{RmcCallable, RmcConnection, new_rmc_gateway_connection}; +use rnex_core::rnex_proxy_common::ConnectionInitData; +use rnex_core::rmc::structures::RmcSerialize; +use tokio::net::TcpListener; + use std::error::Error; +use log::error; + +use crate::reggie::UnitPacketRead; const IP_REQ_SERVICE_URL: &str = "https://ipinfo.io/ip"; @@ -48,4 +58,32 @@ pub static SECURE_SERVER_ACCOUNT: Lazy = Lazy::new(|| Account::new(2, "Quazal Rendez-Vous", &KERBEROS_SERVER_PASSWORD)); +pub async fn new_simple_backend(mut creation_function: F) +where + F: FnMut(ConnectionInitData, RmcConnection) -> Arc, +{ + let listen = TcpListener::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)).await.unwrap(); + while let Ok((mut stream, _addr)) = listen.accept().await { + let buffer = match stream.read_buffer().await{ + Ok(v) => v, + Err(e) => { + error!("an error ocurred whilest reading connection data buffer: {:?}", e); + continue; + } + }; + let user_connection_data = ConnectionInitData::deserialize(&mut Cursor::new(buffer)); + + let user_connection_data = match user_connection_data{ + Ok(v) => v, + Err(e) => { + error!("an error ocurred whilest reading connection data: {:?}", e); + continue; + } + }; + let fun_ref = &mut creation_function; + new_rmc_gateway_connection(stream.into(), move |r|{ + fun_ref(user_connection_data, r) + }); + } +} \ No newline at end of file diff --git a/rnex-core/src/rmc/protocols/ranking.rs b/rnex-core/src/rmc/protocols/ranking.rs index d5746e9..93dcb87 100644 --- a/rnex-core/src/rmc/protocols/ranking.rs +++ b/rnex-core/src/rmc/protocols/ranking.rs @@ -1,6 +1,4 @@ -use macros::rmc_proto; -use crate::rmc::response::ErrorCode; -use macros::{method_id, rmc_struct, RmcSerialize}; +use macros::{rmc_struct, rmc_proto, RmcSerialize}; #[derive(RmcSerialize, Debug, Default, Clone)] struct ResultsRange{ From 449ce0c0ba5afb6b1f5f384aa7e46afad3914ead Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Sat, 8 Nov 2025 13:41:41 +0000 Subject: [PATCH 025/203] add closing a connection if it becomes unreliable/doesnt ack a packet 5 times --- prudpv1/src/prudp/socket.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/prudpv1/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs index d85948c..9307007 100644 --- a/prudpv1/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -7,7 +7,7 @@ use crate::prudp::packet::{PRUDPV1Header, PRUDPV1Packet, TypesFlags}; use rnex_core::prudp::virtual_port::VirtualPort; use rnex_core::prudp::socket_addr::PRUDPSockAddr; use async_trait::async_trait; -use log::info; +use log::{info, warn}; use log::error; use rc4::StreamCipher; use v_byte_helpers::ReadExtensions; @@ -347,6 +347,11 @@ impl InternalSocket { } for (send_time, packet) in &conn.unacknowleged_packets{ + if *send_time < (Instant::now() - Duration::from_millis(3000)){ + warn!("failed to resend packet 5 times and never got response, destroying connection"); + conn.close_connection().await; + break; + } if *send_time < (Instant::now() - Duration::from_millis(500)){ info!("unacknowledged packet sat arround for more than 500 ms, resending"); conn.send_raw_packet(packet).await; From 949c347569c254ca6f8c2640a339448bf4c80aa9 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Sat, 8 Nov 2025 17:04:32 +0000 Subject: [PATCH 026/203] fix proxy not disconnecting propperly --- prudpv1/src/executables/proxy_insecure.rs | 6 ++--- prudpv1/src/executables/proxy_secure.rs | 6 ++--- prudpv1/src/prudp/socket.rs | 32 ++++++++++++++--------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index b33e069..cbfacec 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -76,12 +76,12 @@ async fn main() { tokio::select! { data = conn.recv() => { let Some(data) = data else { - break; + return; }; if let Err(e) = stream.send_buffer(&data[..]).await{ error!("error sending data to backend: {}", e); - break; + return; } }, data = stream.read_buffer() => { @@ -89,7 +89,7 @@ async fn main() { Ok(d) => d, Err(e) => { error!("error reveiving data from backend: {}", e); - break; + return; } }; diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index 91a66fa..b25a03a 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -78,12 +78,12 @@ async fn main() { tokio::select! { data = conn.recv() => { let Some(data) = data else { - break; + return; }; if let Err(e) = stream.send_buffer(&data[..]).await{ error!("error sending data to backend: {}", e); - break; + return; } }, data = stream.read_buffer() => { @@ -91,7 +91,7 @@ async fn main() { Ok(d) => d, Err(e) => { error!("error reveiving data from backend: {}", e); - break; + return; } }; diff --git a/prudpv1/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs index 9307007..6467d8f 100644 --- a/prudpv1/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -91,6 +91,21 @@ impl InternalConnection { async fn send_raw_packet(&self, prudp_packet: &PRUDPV1Packet) { send_raw_prudp_to_sockaddr(&self.socket, self.socket_addr, prudp_packet).await; } + + async fn delete_connection(&self){ + let Some(conns) = self.connections.upgrade() else { + // this is fine as it implies the server has already quit, thus meaning that we dont + // have to remove ourselves from the server + return; + }; + + let mut conns = conns.lock().await; + + conns.remove(&self.socket_addr); + + // the connection will now drop as soon as we leave this due to no longer having a permanent + // reference + } } pub struct ExternalConnection { @@ -172,6 +187,8 @@ pub(super) trait AnyInternalConnection: async fn close_connection(&mut self); } + + #[async_trait] impl AnyInternalConnection for InternalConnection { async fn send_data_packet(&mut self, data: Vec) { @@ -202,6 +219,7 @@ impl AnyInternalConnection for InternalConne self.unacknowleged_packets.push((Instant::now(), packet)); } + async fn close_connection(&mut self) { // jon confirmed that this should be a safe way to dc a client @@ -228,18 +246,7 @@ impl AnyInternalConnection for InternalConne self.send_raw_packet(&packet).await; - let Some(conns) = self.connections.upgrade() else { - // this is fine as it implies the server has already quit, thus meaning that we dont - // have to remove ourselves from the server - return; - }; - - let mut conns = conns.lock().await; - - conns.remove(&self.socket_addr); - - // the connection will now drop as soon as we leave this due to no longer having a permanent - // reference + self.delete_connection().await; } } @@ -583,6 +590,7 @@ impl InternalSocket { self.send_packet_unbuffered(address, &response).await; self.send_packet_unbuffered(address, &response).await; + conn.delete_connection().await; //self.internal_connections.lock().await; } } From 4de04a46275ef0cb213f847068f9b6e0e6949621 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Sat, 8 Nov 2025 17:19:28 +0000 Subject: [PATCH 027/203] fix checking if a session has active players --- rnex-core/src/nex/matchmake.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 93e8ced..f74be5d 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -240,17 +240,21 @@ impl ExtendedMatchmakeSession{ }).await; } } + pub fn has_active_players(&self) -> bool{ + self.connected_players.iter().filter(|v| v.upgrade().is_some()).count() != 0 + } + #[inline] pub fn is_reachable(&self) -> bool{ (if self.session.gathering.flags & PERSISTENT_GATHERING != 0{ - if !self.connected_players.is_empty(){ + if self.has_active_players(){ true } else { self.session.open_participation } } else { - !self.connected_players.is_empty() - }) & !self.connected_players.is_empty() + !self.has_active_players() + }) & !self.has_active_players() } #[inline] pub fn is_joinable(&self) -> bool{ From 6625dab9c1c4f756e41c7cf257a0910d62b3c250 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Sat, 8 Nov 2025 20:27:36 +0000 Subject: [PATCH 028/203] fix is_reachable --- rnex-core/src/nex/matchmake.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index f74be5d..a2f8c20 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -253,8 +253,8 @@ impl ExtendedMatchmakeSession{ self.session.open_participation } } else { - !self.has_active_players() - }) & !self.has_active_players() + self.has_active_players() + }) & self.has_active_players() } #[inline] pub fn is_joinable(&self) -> bool{ From 5782951e6893981b03cffe95698933b6276c61b9 Mon Sep 17 00:00:00 2001 From: Maple Date: Wed, 12 Nov 2025 22:41:34 +0100 Subject: [PATCH 029/203] optimize --- Cargo.lock | 245 ++++++++++ macros/src/lib.rs | 64 ++- macros/src/protos.rs | 2 + prudpv1/src/executables/proxy_insecure.rs | 4 +- prudpv1/src/executables/proxy_secure.rs | 4 +- rnex-core/Cargo.toml | 8 +- rnex-core/benches/rmc_serialization.rs | 99 ++++ .../executables/backend_server_insecure.rs | 2 +- rnex-core/src/kerberos/mod.rs | 4 +- rnex-core/src/lib.rs | 4 + rnex-core/src/main.rs | 447 ++++-------------- rnex-core/src/nex/auth_handler.rs | 2 + rnex-core/src/prudp/station_url.rs | 70 +-- rnex-core/src/rmc/structures/any.rs | 4 +- rnex-core/src/rmc/structures/buffer.rs | 16 +- rnex-core/src/rmc/structures/helpers.rs | 48 ++ rnex-core/src/rmc/structures/list.rs | 30 +- rnex-core/src/rmc/structures/mod.rs | 41 +- rnex-core/src/rmc/structures/networking.rs | 14 +- rnex-core/src/rmc/structures/primitives.rs | 213 +++++++-- rnex-core/src/rmc/structures/qbuffer.rs | 4 +- rnex-core/src/rmc/structures/qresult.rs | 4 +- rnex-core/src/rmc/structures/rmc_struct.rs | 104 +++- rnex-core/src/rmc/structures/string.rs | 32 +- rnex-core/src/rmc/structures/variant.rs | 4 +- 25 files changed, 962 insertions(+), 507 deletions(-) create mode 100644 rnex-core/benches/rmc_serialization.rs create mode 100644 rnex-core/src/rmc/structures/helpers.rs diff --git a/Cargo.lock b/Cargo.lock index 82797de..7965148 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,24 @@ dependencies = [ "libc", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + [[package]] name = "async-stream" version = "0.3.6" @@ -222,6 +240,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.2.31" @@ -257,6 +281,33 @@ dependencies = [ "windows-link", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.4.4" @@ -267,6 +318,31 @@ dependencies = [ "inout", ] +[[package]] +name = "clap" +version = "4.5.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + [[package]] name = "cookie" version = "0.18.1" @@ -294,6 +370,70 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "criterion" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1c047a62b0cc3e145fa84415a3191f628e980b194c2755aa12300a4e6cbd928" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "itertools", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b1bcc0dc7dfae599d84ad0b1a55f80cde8af3725da8313b528da95ef783e338" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + [[package]] name = "crypto-common" version = "0.1.6" @@ -626,6 +766,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1048,6 +1199,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" @@ -1308,6 +1468,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + [[package]] name = "openssl" version = "0.10.73" @@ -1454,6 +1620,34 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + [[package]] name = "potential_utf" version = "0.1.2" @@ -1572,6 +1766,26 @@ dependencies = [ "getrandom 0.2.16", ] +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "rc4" version = "0.1.0" @@ -1714,9 +1928,11 @@ dependencies = [ name = "rnex-core" version = "0.1.1" dependencies = [ + "anyhow", "async-trait", "bytemuck", "chrono", + "criterion", "ctrlc", "dotenv", "hex", @@ -1885,6 +2101,15 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.27" @@ -2242,6 +2467,16 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tokio" version = "1.47.1" @@ -2607,6 +2842,16 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 39639b3..67486ef 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -48,7 +48,7 @@ impl Parse for ProtoInputParams { fn gen_serialize_data_struct( s: DataStruct, struct_attr: Option<&Attribute>, -) -> (proc_macro2::TokenStream, proc_macro2::TokenStream) { +) -> (proc_macro2::TokenStream, proc_macro2::TokenStream, proc_macro2::TokenStream) { let serialize_base_content = { let mut serialize_content = quote! {}; @@ -119,6 +119,29 @@ fn gen_serialize_data_struct( } }; + let write_size = { + let mut size_content = quote! { 0 }; + + for f in &s.fields { + + + let ident = f.ident.as_ref().unwrap(); + let ty = &f.ty; + + size_content.append_all(quote! { + + rnex_core::rmc::structures::RmcSerialize::serialize_write_size(&self.#ident)? + }) + } + + size_content + }; + let write_size = if let Some(_) = struct_attr { + quote!{ #write_size + if rnex_core::config::FEATURE_HAS_STRUCT_HEADER{ 5 } else { 0 } } + } else { + write_size + }; + + // generate base with extends stuff let serialize_base_content = if let Some(attr) = struct_attr { @@ -143,9 +166,18 @@ fn gen_serialize_data_struct( quote! { #pre_inner - rnex_core::rmc::structures::rmc_struct::write_struct(writer, #version, |mut writer|{ - #serialize_base_content - })?; + rnex_core::rmc::structures::rmc_struct::write_struct( + writer, + #version, + rnex_core::rmc::structures::helpers::len_of_write( + |writer|{ + #serialize_base_content + } + ), + |writer|{ + #serialize_base_content + } + )?; Ok(()) } @@ -184,7 +216,13 @@ fn gen_serialize_data_struct( deserialize_base_content }; - (serialize_base_content, deserialize_base_content) + let write_size = quote!{ + fn serialize_write_size(&self) -> rnex_core::rmc::structures::Result{ + Ok(#write_size) + } + }; + + (serialize_base_content, deserialize_base_content, write_size) } #[proc_macro_derive(RmcSerialize, attributes(extends, rmc_struct))] @@ -210,7 +248,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { panic!("rmc struct type MUST be a struct"); };*/ - let (serialize_base_content, deserialize_base_content) = match derive_input.data { + let (serialize_base_content, deserialize_base_content, write_size) = match derive_input.data { Data::Struct(s) => gen_serialize_data_struct(s, struct_attr), Data::Enum(e) => { let Some(repr_attr) = repr_attr else { @@ -221,6 +259,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { let mut inner_match_de = quote! {}; let mut inner_match_se = quote! {}; + let mut inner_match_len = quote!{}; for variant in e.variants { let Some((_, val)) = variant.discriminant else { @@ -352,7 +391,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { Ok(val) }; - (serialize_base_content, deserialize_base_content) + (serialize_base_content, deserialize_base_content, quote!{}) } Data::Union(_) => { unimplemented!() @@ -365,15 +404,16 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { let tokens = quote! { impl rnex_core::rmc::structures::RmcSerialize for #ident{ - fn serialize(&self, writer: &mut dyn ::std::io::Write) -> rnex_core::rmc::structures::Result<()>{ + #[inline(always)] + fn serialize(&self, writer: &mut impl ::std::io::Write) -> rnex_core::rmc::structures::Result<()>{ #serialize_base_content - - } - - fn deserialize(reader: &mut dyn ::std::io::Read) -> rnex_core::rmc::structures::Result{ + #[inline(always)] + fn deserialize(reader: &mut impl ::std::io::Read) -> rnex_core::rmc::structures::Result{ #deserialize_base_content } + + #write_size } }; diff --git a/macros/src/protos.rs b/macros/src/protos.rs index a19f01e..7dd7bf1 100644 --- a/macros/src/protos.rs +++ b/macros/src/protos.rs @@ -55,6 +55,7 @@ impl RmcProtocolData{ let raw_name = Ident::new(&format!("raw_{}", name), name.span()); quote!{ + #[inline(always)] async fn #raw_name }.to_tokens(tokens); @@ -125,6 +126,7 @@ impl RmcProtocolData{ } quote!{ + #[inline(always)] async fn rmc_call_proto( &self, remote_response_connection: &rnex_core::util::SendingBufferConnection, diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index cbfacec..50446d5 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -31,7 +31,7 @@ async fn main() { let conn: SplittableBufferConnection = conn.into(); - conn.send(Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)).to_data()).await; + conn.send(Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)).to_data().unwrap()).await; let conn = new_rmc_gateway_connection(conn, |r| Arc::new(OnlyRemote::::new(r))); @@ -67,7 +67,7 @@ async fn main() { if let Err(e) = stream.send_buffer(&ConnectionInitData{ prudpsock_addr: conn.socket_addr, pid: conn.user_id - }.to_data()).await{ + }.to_data().unwrap()).await{ error!("error connecting to backend: {}", e); return; }; diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index b25a03a..d11b944 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -28,7 +28,7 @@ async fn main() { let conn: SplittableBufferConnection = conn.into(); - conn.send(Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)).to_data()).await; + conn.send(Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)).to_data().unwrap()).await; let conn = new_rmc_gateway_connection(conn, |r| Arc::new(OnlyRemote::::new(r))); @@ -67,7 +67,7 @@ async fn main() { if let Err(e) = stream.send_buffer(&ConnectionInitData{ prudpsock_addr: conn.socket_addr, pid: conn.user_id - }.to_data()).await{ + }.to_data().unwrap()).await{ error!("error connecting to backend: {}", e); return; }; diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 90ce871..b609afb 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -29,9 +29,15 @@ typenum = "1.18.0" reqwest = { version= "0.12.18", features = ["blocking"]} json = "0.12.4" ctrlc = "3.4.7" +criterion = "0.7.0" +anyhow = "1.0.100" +[features] +rmc_struct_header = [] - +[[bench]] +name = "rmc_serialization" +harness = false [[bin]] name = "backend_server_insecure" diff --git a/rnex-core/benches/rmc_serialization.rs b/rnex-core/benches/rmc_serialization.rs new file mode 100644 index 0000000..4b506f8 --- /dev/null +++ b/rnex-core/benches/rmc_serialization.rs @@ -0,0 +1,99 @@ +use std::hint::black_box; +use std::io::Cursor; +use std::ops::Deref; +use criterion::{criterion_group, criterion_main, Criterion}; +use once_cell::sync::Lazy; +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, Gathering, MatchmakeParam, MatchmakeSession, MatchmakeSessionSearchCriteria}; +use rnex_core::rmc::structures::RmcSerialize; +use rnex_core::rmc::structures::variant::Variant; + +static DUMMY: Lazy = Lazy::new(|| AutoMatchmakeParam{ + additional_participants: vec![1,2,3,4], + auto_matchmake_option: 10, + gid_for_participation_check: 9, + join_message: "hi".to_string(), + participation_count: 32, + target_gids: vec![45,2,51,1,1,1,1], + search_criteria: vec![MatchmakeSessionSearchCriteria{ + attribs: vec!["hi".to_string(), "ig".to_string(), "gotta put data here".to_string()], + exclude_locked: true, + exclude_non_host_pid: false, + exclude_system_password_set: true, + exclude_user_password_set: false, + game_mode: "some gamemode".to_string(), + matchmake_param: MatchmakeParam{ + params: vec![ + ("SR".to_string(), Variant::Bool(true)), + ("SR2".to_string(), Variant::Double(1.0)), + ("SR3".to_string(), Variant::SInt64(42)), + ("SR4".to_string(), Variant::String("test".to_string())) + ] + }, + matchmake_system_type: "some type".to_string(), + maximum_participants: "???".to_string(), + minimum_participants: "-99".to_string(), + refer_gid: 123, + selection_method: 9999999, + vacant_only: true, + vacant_participants: 1000 + }], + matchmake_session: MatchmakeSession{ + refer_gid: 10, + matchmake_system_type: 139, + matchmake_param: MatchmakeParam{ + params: vec![ + ("QSR".to_string(), Variant::Bool(false)), + ("SRQ2".to_string(), Variant::Double(1.1)), + ("SQR3".to_string(), Variant::SInt64(422)), + ("SDR4".to_string(), Variant::String("tetst".to_string())) + ] + }, + participation_count: 99, + application_buffer: vec![1,2,3,4,5,6,7,8,9], + attributes: vec![10,20,99,100000], + datetime: KerberosDateTime::now(), + gamemode: 111, + open_participation: false, + option0: 100, + progress_score: 1, + system_password_enabled: false, + user_password: "aaa".to_string(), + session_key: vec![91,123,5,2,1,2,4,124,4], + user_password_enabled: false, + gathering: Gathering{ + minimum_participants: 1, + maximum_participants: 12, + description: "aaargh".to_string(), + flags: 100, + host_pid: 999999919, + owner_pid: 138830, + participant_policy: 1, + policy_argument: 99837, + self_gid: 129, + state: 1389488 + } + } +}); + +static DUMMY_SER: Lazy> = Lazy::new(|| serialize_to_vec(DUMMY.deref())); + +fn serialize_to_vec(r: &impl RmcSerialize) -> Vec{ + let mut vec = r.to_data(); + + vec.unwrap() +} + +fn read_struct(r: &[u8]) -> T{ + T::deserialize(&mut Cursor::new(r)).unwrap() +} +fn matchmake_with_param(c: &mut Criterion) { + let raw = DUMMY.deref(); + let ser = DUMMY_SER.deref().as_slice(); + c.bench_function("mmparam: ser", |b| b.iter(move || serialize_to_vec(black_box(raw)))); + c.bench_function("mmparam: de", |b| b.iter(move || read_struct::(black_box(ser)))); +} + +criterion_group!(benches, matchmake_with_param); +criterion_main!(benches); + diff --git a/rnex-core/src/executables/backend_server_insecure.rs b/rnex-core/src/executables/backend_server_insecure.rs index 6b2625c..4cbe591 100644 --- a/rnex-core/src/executables/backend_server_insecure.rs +++ b/rnex-core/src/executables/backend_server_insecure.rs @@ -30,7 +30,7 @@ async fn main() { let conn: SplittableBufferConnection = conn.into(); - conn.send(DontRegister.to_data()).await; + conn.send(DontRegister.to_data().unwrap()).await; let conn = new_rmc_gateway_connection(conn, |r| Arc::new(OnlyRemote::::new(r))); diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index 09dc46c..a54764e 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -83,11 +83,11 @@ impl KerberosDateTime{ } impl RmcSerialize for KerberosDateTime{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(self.0.serialize(writer)?) } - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(Self(u64::deserialize(reader)?)) } } diff --git a/rnex-core/src/lib.rs b/rnex-core/src/lib.rs index 21b354a..4a4f1ef 100644 --- a/rnex-core/src/lib.rs +++ b/rnex-core/src/lib.rs @@ -24,3 +24,7 @@ pub mod rnex_proxy_common; pub mod util; pub mod executables; pub use macros::*; + +pub mod config{ + pub const FEATURE_HAS_STRUCT_HEADER: bool = cfg!(feature = "rmc_struct_header"); +} diff --git a/rnex-core/src/main.rs b/rnex-core/src/main.rs index 0af4975..cfa323d 100644 --- a/rnex-core/src/main.rs +++ b/rnex-core/src/main.rs @@ -20,6 +20,8 @@ use std::fs::File; use std::net::{Ipv4Addr}; use std::sync::Once; use std::{env, fs}; +use std::hint::black_box; +use criterion::{criterion_group, criterion_main, Criterion}; mod prudp; pub mod rmc; @@ -35,360 +37,111 @@ pub mod reggie; pub mod util; pub mod common; - - -static KERBEROS_SERVER_PASSWORD: Lazy = Lazy::new(|| { - env::var("AUTH_SERVER_PASSWORD") - .ok() - .unwrap_or("password".to_owned()) -}); - -static AUTH_SERVER_ACCOUNT: Lazy = - Lazy::new(|| Account::new(1, "Quazal Authentication", &KERBEROS_SERVER_PASSWORD)); -static SECURE_SERVER_ACCOUNT: Lazy = - Lazy::new(|| Account::new(2, "Quazal Rendez-Vous", &KERBEROS_SERVER_PASSWORD)); - -static AUTH_SERVER_PORT: Lazy = Lazy::new(|| { - env::var("AUTH_SERVER_PORT") - .ok() - .and_then(|s| s.parse().ok()) - .unwrap_or(10000) -}); -static SECURE_SERVER_PORT: Lazy = Lazy::new(|| { - env::var("SECURE_SERVER_PORT") - .ok() - .and_then(|s| s.parse().ok()) - .unwrap_or(10001) -}); - -static OWN_IP_PRIVATE: Lazy = Lazy::new(|| { - env::var("SERVER_IP") - .ok() - .and_then(|s| s.parse().ok()) - .expect("no private ip specified") -}); - -static OWN_IP_PUBLIC: Lazy = - Lazy::new(|| env::var("SERVER_IP_PUBLIC").unwrap_or(OWN_IP_PRIVATE.to_string())); - -static SECURE_STATION_URL: Lazy = Lazy::new(|| { - format!( - "prudps:/PID=2;sid=1;stream=10;type=2;address={};port={};CID=1", - *OWN_IP_PUBLIC, *SECURE_SERVER_PORT - ) -}); - -static FORCE_EXIT: Once = Once::new(); - -#[tokio::main] -async fn main() { - CombinedLogger::init(vec![ - TermLogger::new( - LevelFilter::Info, - Config::default(), - TerminalMode::Mixed, - ColorChoice::Auto, - ), - WriteLogger::new(LevelFilter::max(), Config::default(), { - fs::create_dir_all("log").unwrap(); - let date = Local::now().to_rfc3339_opts(SecondsFormat::Secs, false); - // this fixes windows being windows - let date = date.replace(":", "-"); - let filename = format!("{}.log", date); - if cfg!(windows) { - File::create(format!("log\\{}", filename)).unwrap() - } else { - File::create(format!("log/{}", filename)).unwrap() - } - }), - ]) - .unwrap(); - - ctrlc::set_handler(||{ - FORCE_EXIT.call_once_force(|_|{ - println!("attempting exit"); - }); - }).unwrap(); - - dotenv::dotenv().ok(); - - //start_servers().await; -} -/* - -struct AuthServer{ - router: Arc, - join_handle: JoinHandle<()>, - socket: Socket +pub mod config{ + pub const FEATURE_HAS_STRUCT_HEADER: bool = cfg!(feature = "rmc_struct_header"); } -async fn start_auth_server() -> AuthServer{ - info!("starting auth server on {}:{}", *OWN_IP_PRIVATE, *AUTH_SERVER_PORT); +use std::io::Cursor; +use std::ops::Deref; +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, Gathering, MatchmakeParam, MatchmakeSession, MatchmakeSessionSearchCriteria}; +use rnex_core::rmc::structures::RmcSerialize; +use rnex_core::rmc::structures::variant::Variant; - let (router, join_handle) = - Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT)).await - .expect("unable to startauth server"); - - info!("setting up endpoints"); - - // dont assign it to the name _ as that will make it drop right here and now - - let auth_protocol_config = AuthProtocolConfig{ - secure_server_account: &SECURE_SERVER_ACCOUNT, - build_name: "branch:origin/project/wup-agmj build:3_8_15_2004_0", - station_url: &SECURE_STATION_URL - }; - - let rmcserver = RMCProtocolServer::new(Box::new([ - Box::new(auth::bound_protocol(auth_protocol_config)) - ])); - - let socket = - Socket::new( - router.clone(), - VirtualPort::new(1,10), - "6f599f81", - Box::new(|_, count|{ - Box::pin( - async move { - - - let encryption_pairs = Vec::from_iter((0..=count).map(|_v| { - let rc4: Rc4 = Rc4::new_from_slice( "CD&ML".as_bytes()).unwrap(); - let cypher = Box::new(rc4); - let server_cypher: Box = cypher; - - let rc4: Rc4 = Rc4::new_from_slice( "CD&ML".as_bytes()).unwrap(); - let cypher = Box::new(rc4); - let client_cypher: Box = cypher; - - EncryptionPair{ - recv: client_cypher, - send: server_cypher - } - })); - - Some((Vec::new(), encryption_pairs, None)) - } - ) - }), - Box::new(move |packet, socket, connection|{ - let rmcserver = rmcserver.clone(); - Box::pin(async move { rmcserver.process_message(packet, socket, connection).await; }) - }) - ).await.expect("unable to create socket"); - - AuthServer{ - join_handle, - router, - socket, +static DUMMY: Lazy = Lazy::new(|| AutoMatchmakeParam{ + additional_participants: vec![1,2,3,4], + auto_matchmake_option: 10, + gid_for_participation_check: 9, + join_message: "hi".to_string(), + participation_count: 32, + target_gids: vec![45,2,51,1,1,1,1], + search_criteria: vec![MatchmakeSessionSearchCriteria{ + attribs: vec!["hi".to_string(), "ig".to_string(), "gotta put data here".to_string()], + exclude_locked: true, + exclude_non_host_pid: false, + exclude_system_password_set: true, + exclude_user_password_set: false, + game_mode: "some gamemode".to_string(), + matchmake_param: MatchmakeParam{ + params: vec![ + ("SR".to_string(), Variant::Bool(true)), + ("SR2".to_string(), Variant::Double(1.0)), + ("SR3".to_string(), Variant::SInt64(42)), + ("SR4".to_string(), Variant::String("test".to_string())) + ] + }, + matchmake_system_type: "some type".to_string(), + maximum_participants: "???".to_string(), + minimum_participants: "-99".to_string(), + refer_gid: 123, + selection_method: 9999999, + vacant_only: true, + vacant_participants: 1000 + }], + matchmake_session: MatchmakeSession{ + refer_gid: 10, + matchmake_system_type: 139, + matchmake_param: MatchmakeParam{ + params: vec![ + ("QSR".to_string(), Variant::Bool(false)), + ("SRQ2".to_string(), Variant::Double(1.1)), + ("SQR3".to_string(), Variant::SInt64(422)), + ("SDR4".to_string(), Variant::String("tetst".to_string())) + ] + }, + participation_count: 99, + application_buffer: vec![1,2,3,4,5,6,7,8,9], + attributes: vec![10,20,99,100000], + datetime: KerberosDateTime::now(), + gamemode: 111, + open_participation: false, + option0: 100, + progress_score: 1, + system_password_enabled: false, + user_password: "aaa".to_string(), + session_key: vec![91,123,5,2,1,2,4,124,4], + user_password_enabled: false, + gathering: Gathering{ + minimum_participants: 1, + maximum_participants: 12, + description: "aaargh".to_string(), + flags: 100, + host_pid: 999999919, + owner_pid: 138830, + participant_policy: 1, + policy_argument: 99837, + self_gid: 129, + state: 1389488 + } } +}); + +static DUMMY_SER: Lazy> = Lazy::new(|| serialize_to_vec(DUMMY.deref())); + +fn serialize_to_vec(r: &impl RmcSerialize) -> Vec{ + let mut vec = r.to_data(); + + vec.unwrap() } -struct SecureServer{ - router: Arc, - join_handle: JoinHandle<()>, - socket: Socket +fn read_struct(r: &[u8]) -> T{ + T::deserialize(&mut Cursor::new(r)).unwrap() +} +fn matchmake_with_param(c: &mut Criterion) { + let raw = DUMMY.deref(); + let ser = DUMMY_SER.deref().as_slice(); + c.bench_function("mmparam: ser", |b| b.iter(move || serialize_to_vec(black_box(raw)))); + c.bench_function("mmparam: de", |b| b.iter(move || read_struct::(black_box(ser)))); } -async fn start_secure_server() -> SecureServer{ - info!("starting secure server on {}:{}", *OWN_IP_PRIVATE, *SECURE_SERVER_PORT); +criterion_group!(benches, matchmake_with_param); +//criterion_main!(benches); - let (router, join_handle) = - Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SECURE_SERVER_PORT)).await - .expect("unable to startauth server"); - - info!("setting up endpoints"); - - let matchmake_data = Arc::new(RwLock::new( - MatchmakeData{ - matchmake_sessions: BTreeMap::new() - } - )); - - let rmcserver = RMCProtocolServer::new(Box::new([ - Box::new(block_if_maintenance), - Box::new(protocols::secure::bound_protocol()), - Box::new(protocols::matchmake::bound_protocol(matchmake_data.clone())), - Box::new(protocols::matchmake_extension::bound_protocol(matchmake_data)), - Box::new(protocols::nat_traversal::bound_protocol()) - ])); - - let socket = - Socket::new( - router.clone(), - VirtualPort::new(1,10), - "6f599f81", - Box::new(|p, count|{ - Box::pin( - async move { - let (session_key, pid, check_value) = read_secure_connection_data(&p.payload, &SECURE_SERVER_ACCOUNT)?; - - let check_value_response = check_value + 1; - - let data = bytemuck::bytes_of(&check_value_response); - - let mut response = Vec::new(); - - data.serialize(&mut response).ok()?; - - let encryption_pairs = generate_secure_encryption_pairs(session_key, count); - - Some((response, encryption_pairs, Some( - ActiveSecureConnectionData{ - pid, - session_key - } - ))) - } - ) - }), - Box::new(move |packet, socket, connection|{ - let rmcserver = rmcserver.clone(); - Box::pin(async move { rmcserver.process_message(packet, socket, connection).await; }) - }) - ).await.expect("unable to create socket"); - - SecureServer{ - join_handle, - router, - socket, +fn main(){ + for _ in 0..10000000 { + let v = serialize_to_vec(black_box(DUMMY.deref())); + let u = read_struct::(black_box(DUMMY_SER.deref().as_slice())); + black_box(v); + black_box(u); } -}*/ -/* -async fn start_auth() -> JoinHandle<()> { - tokio::spawn(async { - let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT)) - .await - .expect("unable to start router"); - - let mut socket_secure = router_secure - .add_socket(VirtualPort::new(1, 10), Unsecure( - "6f599f81" - )) - .await - .expect("unable to add socket"); - - // let conn = socket_secure.connect(auth_sockaddr).await.unwrap(); - - while !FORCE_EXIT.is_completed() { - let Some(conn) = socket_secure.accept().await else { - error!("server crashed"); - return; - }; - - info!("new connected user!"); - - let _ = new_rmc_gateway_connection(conn, |_| { - Arc::new(AuthHandler { - destination_server_acct: &SECURE_SERVER_ACCOUNT, - build_name: "branch:origin/project/wup-agmj build:3_8_15_2004_0", - station_url: &SECURE_STATION_URL, - }) - }); - } - }) -} - -async fn start_secure() -> JoinHandle<()> { - tokio::spawn(async { - let mmm = Arc::new(MatchmakeManager{ - gid_counter: AtomicU32::new(1), - sessions: Default::default(), - users: Default::default(), - rv_cid_counter: AtomicU32::new(1), - }); - - let weak_mmm = Arc::downgrade(&mmm); - - MatchmakeManager::initialize_garbage_collect_thread(weak_mmm).await; - - let web_server = web::start_web(mmm.clone()).await; - - let (router_secure, _) = - Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SECURE_SERVER_PORT)) - .await - .expect("unable to start router"); - - let mut socket_secure = router_secure - .add_socket( - VirtualPort::new(1, 10), - Secure( - "6f599f81", - &SECURE_SERVER_ACCOUNT - ), - ) - .await - .expect("unable to add socket"); - - // let conn = socket_secure.connect(auth_sockaddr).await.unwrap(); - - while !FORCE_EXIT.is_completed() { - let Some(conn) = socket_secure.accept().await else { - error!("server crashed"); - return; - }; - - info!("new connected user on secure :D!"); - - let ip = conn.socket_addr; - let pid = conn.user_id; - - let _ = new_rmc_gateway_connection(conn, |r| { - Arc::new_cyclic(|w| User { - ip, - pid, - this: w.clone(), - remote: RemoteConsole::new(r), - station_url: Default::default(), - matchmake_manager: mmm.clone() - }) - }); - } - }) -} - -async fn start_test() { - let addr = SocketAddrV4::new(*OWN_IP_PRIVATE, *SECURE_SERVER_PORT); - - let virt_addr = VirtualPort::new(1, 10); - let prudp_addr = PRUDPSockAddr::new(addr, virt_addr); - - let (router_test, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, 26969)) - .await - .expect("unable to start router"); - - let mut socket_secure = router_test - .add_socket(VirtualPort::new(1, 10), Unsecure("6f599f81")) - .await - .expect("unable to add socket"); - - let conn = socket_secure.connect(prudp_addr).await.unwrap(); - - let remote = new_rmc_gateway_connection(conn, |r| { - Arc::new(OnlyRemote::::new(r)) - }); - - tokio::time::sleep(Duration::from_secs(1)).await; - let urls = vec!["prudp:/address=192.168.178.45;port=60146;Pl=2;natf=0;natm=0;pmp=0;sid=15;upnp=0".to_owned()]; -} - -async fn start_servers() { - #[cfg(feature = "auth")] - let auth_server = start_auth().await; - #[cfg(feature = "secure")] - let secure_server = start_secure().await; - - - tokio::time::sleep(Duration::from_secs(1)).await; - - //start_test().await; - - - - #[cfg(feature = "auth")] - auth_server.await.expect("auth server crashed"); - #[cfg(feature = "secure")] - secure_server.await.expect("auth server crashed"); -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index 134c1bc..e5184d0 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -162,6 +162,8 @@ mod test { use rnex_core::rmc::structures::RmcSerialize; use rnex_core::rmc::response::RMCResponse; use std::io::Cursor; + + #[test] fn test() { diff --git a/rnex-core/src/prudp/station_url.rs b/rnex-core/src/prudp/station_url.rs index b2f70bb..a193b21 100644 --- a/rnex-core/src/prudp/station_url.rs +++ b/rnex-core/src/prudp/station_url.rs @@ -5,6 +5,7 @@ use std::io::Read; use crate::prudp::station_url::Type::{PRUDP, PRUDPS, UDP}; use crate::prudp::station_url::UrlOptions::{Address, ConnectionID, NatFiltering, NatMapping, NatType, Platform, PMP, Port, PrincipalID, RVConnectionID, StreamID, StreamType, UPNP, PID}; use crate::rmc::structures::Error::StationUrlInvalid; +use crate::rmc::structures::helpers::DummyFormatWriter; use crate::rmc::structures::RmcSerialize; #[derive(Clone, Copy, PartialEq, Eq)] pub enum Type{ @@ -135,59 +136,66 @@ impl TryFrom<&str> for StationUrl{ } } -impl<'a> Into for &'a StationUrl{ - fn into(self) -> String { - let mut url = match self.url_type{ +impl Display for StationUrl{ + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let url_type_str = match self.url_type{ UDP => "udp:/", PRUDP => "prudp:/", PRUDPS => "prudps:/" - }.to_owned(); + }; + write!(f, "{}",url_type_str)?; for option in &self.options{ match option{ - Address(v) => write!(url, "address={}", v).expect("failed to write"), - Port(v) => write!(url, "port={}", v).expect("failed to write"), - StreamType(v) => write!(url, "stream={}", v).expect("failed to write"), - StreamID(v) => write!(url, "sid={}", v).expect("failed to write"), - ConnectionID(v) => write!(url, "CID={}", v).expect("failed to write"), - PrincipalID(v) => write!(url, "PID={}", v).expect("failed to write"), - NatType(v) => write!(url, "type={}", v).expect("failed to write"), - NatMapping(v) => write!(url, "natm={}", v).expect("failed to write"), - NatFiltering(v) => write!(url, "natf={}", v).expect("failed to write"), - UPNP(v) => write!(url, "upnp={}", v).expect("failed to write"), - RVConnectionID(v) => write!(url, "RVCID={}", v).expect("failed to write"), - Platform(v) => write!(url, "pl={}", v).expect("failed to write"), - PMP(v) => write!(url, "pmp={}", v).expect("failed to write"), - PID(v) => write!(url, "PID={}", v).expect("failed to write"), + Address(v) => write!(f, "address={}", v)?, + Port(v) => write!(f, "port={}", v)?, + StreamType(v) => write!(f, "stream={}", v)?, + StreamID(v) => write!(f, "sid={}", v)?, + ConnectionID(v) => write!(f, "CID={}", v)?, + PrincipalID(v) => write!(f, "PID={}", v)?, + NatType(v) => write!(f, "type={}", v)?, + NatMapping(v) => write!(f, "natm={}", v)?, + NatFiltering(v) => write!(f, "natf={}", v)?, + UPNP(v) => write!(f, "upnp={}", v)?, + RVConnectionID(v) => write!(f, "RVCID={}", v)?, + Platform(v) => write!(f, "pl={}", v)?, + PMP(v) => write!(f, "pmp={}", v)?, + PID(v) => write!(f, "PID={}", v)?, } - write!(url, ";").expect("failed to write"); + write!(f, ";")?; } + Ok(()) + } +} + +impl<'a> Into for &'a StationUrl{ + fn into(self) -> String { + let mut url = self.to_string(); + url[0..url.len()-1].into() } } -impl Display for StationUrl{ - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let str: String = self.into(); - - write!(f, "{}", str) - } - - -} - impl RmcSerialize for StationUrl{ - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let str = String::deserialize(reader)?; Self::try_from(str.as_str()).map_err(|_| StationUrlInvalid) } - fn serialize(&self, writer: &mut dyn std::io::Write) -> crate::rmc::structures::Result<()> { + fn serialize(&self, writer: &mut impl std::io::Write) -> crate::rmc::structures::Result<()> { let str: String = self.into(); str.serialize(writer) } + + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + let mut dummy = DummyFormatWriter::new(); + + write!(&mut dummy, "{}", self)?; + + Ok(dummy.serialize_str_len()) + } } impl Debug for StationUrl{ diff --git a/rnex-core/src/rmc/structures/any.rs b/rnex-core/src/rmc/structures/any.rs index c1e68a4..e76b60a 100644 --- a/rnex-core/src/rmc/structures/any.rs +++ b/rnex-core/src/rmc/structures/any.rs @@ -9,7 +9,7 @@ pub struct Any{ } impl RmcSerialize for Any{ - fn serialize(&self, writer: &mut dyn Write) -> Result<()> { + fn serialize(&self, writer: &mut impl Write) -> Result<()> { self.name.serialize(writer)?; let u32_len = self.data.len() as u32; @@ -21,7 +21,7 @@ impl RmcSerialize for Any{ Ok(()) } - fn deserialize(mut reader: &mut dyn Read) -> Result { + fn deserialize(mut reader: &mut impl Read) -> Result { let name = String::deserialize(reader)?; // also length ? diff --git a/rnex-core/src/rmc/structures/buffer.rs b/rnex-core/src/rmc/structures/buffer.rs index 5db53cf..085f053 100644 --- a/rnex-core/src/rmc/structures/buffer.rs +++ b/rnex-core/src/rmc/structures/buffer.rs @@ -4,7 +4,7 @@ use crate::rmc::structures::RmcSerialize; impl<'a> RmcSerialize for &'a [u8]{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { let u32_size = self.len() as u32; writer.write(bytemuck::bytes_of(&u32_size))?; writer.write(self)?; @@ -13,17 +13,25 @@ impl<'a> RmcSerialize for &'a [u8]{ } /// DO NOT USE (also maybe split off the serialize and deserialize functions at some point) - fn deserialize(_reader: &mut dyn Read) -> crate::rmc::structures::Result { + fn deserialize(_reader: &mut impl Read) -> crate::rmc::structures::Result { panic!("cannot deserialize to a u8 slice reference (use this ONLY for writing)") } + + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(4 + self.len() as u32) + } } impl RmcSerialize for Box<[u8]>{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { (&self[..]).serialize(writer) } - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Vec::deserialize(reader).map(|v| v.into_boxed_slice()) } + + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + (&self[..]).serialize_write_size() + } } \ No newline at end of file diff --git a/rnex-core/src/rmc/structures/helpers.rs b/rnex-core/src/rmc/structures/helpers.rs new file mode 100644 index 0000000..eeadbd6 --- /dev/null +++ b/rnex-core/src/rmc/structures/helpers.rs @@ -0,0 +1,48 @@ +use std::{fmt, io}; + +pub struct DummyFormatWriter(u32); + +impl fmt::Write for DummyFormatWriter{ + fn write_str(&mut self, s: &str) -> fmt::Result { + self.0 += s.as_bytes().len() as u32; + Ok(()) + } +} + +impl DummyFormatWriter{ + pub const fn new() -> Self{ Self(0) } + pub const fn serialize_str_len(&self) -> u32 { + 2 + self.0 + 1 + } +} + +pub struct DummyWriter(u32); + +impl io::Write for DummyWriter{ + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0 += buf.len() as u32; + Ok(buf.len()) + } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.0 += buf.len() as u32; + Ok(()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl DummyWriter{ + pub const fn new() -> Self{ Self(0) } + pub const fn get_total_len(&self) -> u32{ + self.0 + } +} + + +pub fn len_of_write(f: impl FnOnce(&mut DummyWriter) -> anyhow::Result<()>) -> u32{ + let mut dummy = DummyWriter::new(); + f(&mut dummy).ok(); + dummy.get_total_len() +} \ No newline at end of file diff --git a/rnex-core/src/rmc/structures/list.rs b/rnex-core/src/rmc/structures/list.rs index f4843c1..980907d 100644 --- a/rnex-core/src/rmc/structures/list.rs +++ b/rnex-core/src/rmc/structures/list.rs @@ -9,7 +9,7 @@ use crate::rmc::structures::RmcSerialize; // this is also for implementing `Buffer` this is tecnically not the same as its handled internaly // probably but as it has the same mapping it doesn't matter and simplifies things impl RmcSerialize for Vec{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { let u32_len = self.len() as u32; writer.write_all(bytes_of(&u32_len))?; @@ -20,21 +20,27 @@ impl RmcSerialize for Vec{ Ok(()) } - fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result { + fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { let len: u32 = reader.read_struct(IS_BIG_ENDIAN)?; - let mut vec = Vec::with_capacity(len as usize); + //let mut vec = Vec::with_capacity(len as usize); - for _ in 0..len{ - vec.push(T::deserialize(reader)?); - } + let vec = (0..len).map(|_| T::deserialize(reader)).collect::, _>>()?; Ok(vec) } + + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + let mut val = 0u32; + for i in self{ + val += i.serialize_write_size()?; + } + Ok(4 + val) + } } impl RmcSerialize for [T; LEN]{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { for i in 0..LEN{ self[i].serialize(writer)?; } @@ -42,7 +48,7 @@ impl RmcSerialize for [T; LEN]{ Ok(()) } - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let mut arr = [const { MaybeUninit::::uninit() }; LEN]; for i in 0..LEN{ @@ -55,4 +61,12 @@ impl RmcSerialize for [T; LEN]{ Ok(arr) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + let mut val = 0u32; + for i in self{ + val += i.serialize_write_size()?; + } + Ok(val) + } } diff --git a/rnex-core/src/rmc/structures/mod.rs b/rnex-core/src/rmc/structures/mod.rs index 9d127f7..7a1610c 100644 --- a/rnex-core/src/rmc/structures/mod.rs +++ b/rnex-core/src/rmc/structures/mod.rs @@ -1,8 +1,8 @@ -use std::io; +use std::{fmt, io}; use std::io::{Read, Write}; use std::string::FromUtf8Error; use thiserror::Error; - +use crate::rmc::structures::helpers::DummyWriter; //ideas for the future: make a proc macro library which allows generation of struct reads #[derive(Error, Debug)] @@ -16,7 +16,9 @@ pub enum Error{ #[error("version mismatch: {0}")] VersionMismatch(u8), #[error("an error occurred reading the station url")] - StationUrlInvalid + StationUrlInvalid, + #[error("error formatting text: {0}")] + FormatError(#[from] fmt::Error) } pub type Result = std::result::Result; @@ -33,28 +35,43 @@ pub mod primitives; pub mod matchmake; pub mod variant; pub mod ranking; -mod networking; +pub mod networking; +pub mod helpers; pub trait RmcSerialize{ - fn serialize(&self, writer: &mut dyn Write) -> Result<()>; - fn deserialize(reader: &mut dyn Read) -> Result where Self: Sized; + fn serialize(&self, writer: &mut impl Write) -> Result<()>; + fn serialize_write_size(&self) -> Result{ + let mut dummy = DummyWriter::new(); - fn to_data(&self) -> Vec{ - let mut data = Vec::new(); + self.serialize(&mut dummy)?; - self.serialize(&mut data).expect("out of memory or something"); + Ok(dummy.get_total_len()) + } + fn deserialize(reader: &mut impl Read) -> Result where Self: Sized; - data + fn to_data(&self) -> Result>{ + let mut data = Vec::with_capacity( + self.serialize_write_size()? as usize + ); + + self.serialize(&mut data)?; + + debug_assert_eq!(self.serialize_write_size().unwrap(), data.len() as u32); + + Ok(data) } } impl RmcSerialize for (){ - fn serialize(&self, _writer: &mut dyn Write) -> Result<()> { + fn serialize(&self, _writer: &mut impl Write) -> Result<()> { Ok(()) } - fn deserialize(_reader: &mut dyn Read) -> Result { + fn deserialize(_reader: &mut impl Read) -> Result { Ok(()) } + fn serialize_write_size(&self) -> Result { + Ok(0) + } } \ No newline at end of file diff --git a/rnex-core/src/rmc/structures/networking.rs b/rnex-core/src/rmc/structures/networking.rs index 824a442..03627af 100644 --- a/rnex-core/src/rmc/structures/networking.rs +++ b/rnex-core/src/rmc/structures/networking.rs @@ -4,30 +4,36 @@ use rnex_core::prudp::virtual_port::VirtualPort; use crate::rmc::structures::RmcSerialize; impl RmcSerialize for SocketAddrV4{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.ip().to_bits().serialize(writer)?; self.port().serialize(writer)?; Ok(()) } - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let ip = u32::deserialize(reader)?; let port = u16::deserialize(reader)?; Ok(SocketAddrV4::new(Ipv4Addr::from_bits(ip), port)) } + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(6) + } } impl RmcSerialize for VirtualPort{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; Ok(()) } - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(Self(u8::deserialize(reader)?)) } + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(1) + } } \ No newline at end of file diff --git a/rnex-core/src/rmc/structures/primitives.rs b/rnex-core/src/rmc/structures/primitives.rs index 73985ed..65e732c 100644 --- a/rnex-core/src/rmc/structures/primitives.rs +++ b/rnex-core/src/rmc/structures/primitives.rs @@ -4,97 +4,146 @@ use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::rmc::structures::RmcSerialize; impl RmcSerialize for u8{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) } - fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(1) + } } impl RmcSerialize for i8{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) } - fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(1) + } } impl RmcSerialize for u16{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) } - - fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(2) + } } impl RmcSerialize for i16{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) } - - fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(2) + } } impl RmcSerialize for u32{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) } - - fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(4) + } } impl RmcSerialize for i32{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) } - - fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(4) + } } impl RmcSerialize for u64{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) } - - fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(8) + } } impl RmcSerialize for i64{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) } - - fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(8) + } } impl RmcSerialize for f64{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) } - fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(8) + } } impl RmcSerialize for bool{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { match self{ true => writer.write_all(&[1])?, false => writer.write_all(&[0])?, @@ -102,54 +151,77 @@ impl RmcSerialize for bool{ Ok(()) } - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(u8::deserialize(reader)? != 0) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(1) + } } impl RmcSerialize for (T, U){ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; self.1.serialize(writer)?; Ok(()) } - - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let first = T::deserialize(reader)?; let second = U::deserialize(reader)?; Ok((first, second)) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok( + self.0.serialize_write_size()? + + self.1.serialize_write_size()? + ) + } } impl RmcSerialize for (T, U, V){ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; self.1.serialize(writer)?; self.2.serialize(writer)?; Ok(()) } - - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let first = T::deserialize(reader)?; let second = U::deserialize(reader)?; let third = V::deserialize(reader)?; Ok((first, second, third)) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok( + self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()? + ) + } } impl RmcSerialize for (T, U, V, W){ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; self.1.serialize(writer)?; self.2.serialize(writer)?; self.3.serialize(writer)?; Ok(()) } - - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let first = T::deserialize(reader)?; let second = U::deserialize(reader)?; let third = V::deserialize(reader)?; @@ -157,10 +229,20 @@ impl RmcSeri Ok((first, second, third, fourth)) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok( + self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()? + + self.3.serialize_write_size()? + ) + } } impl RmcSerialize for (T, U, V, W, X){ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; self.1.serialize(writer)?; self.2.serialize(writer)?; @@ -170,7 +252,8 @@ impl crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let first = T::deserialize(reader)?; let second = U::deserialize(reader)?; let third = V::deserialize(reader)?; @@ -179,10 +262,21 @@ impl crate::rmc::structures::Result { + Ok( + self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()? + + self.2.serialize_write_size()? + + self.3.serialize_write_size()? + ) + } } impl RmcSerialize for (T, U, V, W, X, Y){ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; self.1.serialize(writer)?; self.2.serialize(writer)?; @@ -193,7 +287,8 @@ impl crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let first = T::deserialize(reader)?; let second = U::deserialize(reader)?; let third = V::deserialize(reader)?; @@ -203,10 +298,22 @@ impl crate::rmc::structures::Result { + Ok( + self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()? + + self.3.serialize_write_size()? + + self.4.serialize_write_size()? + + self.5.serialize_write_size()? + ) + } } impl RmcSerialize for (T, U, V, W, X, Y, Z){ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; self.1.serialize(writer)?; self.2.serialize(writer)?; @@ -217,8 +324,8 @@ impl crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let first = T::deserialize(reader)?; let second = U::deserialize(reader)?; let third = V::deserialize(reader)?; @@ -229,13 +336,31 @@ impl crate::rmc::structures::Result { + Ok( + self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()? + + self.3.serialize_write_size()? + + self.4.serialize_write_size()? + + self.5.serialize_write_size()? + + self.6.serialize_write_size()? + ) + } } impl RmcSerialize for Box{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.as_ref().serialize(writer) } - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + #[inline(always)] + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { T::deserialize(reader).map(Box::new) } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + T::serialize_write_size(self.as_ref()) + } } \ No newline at end of file diff --git a/rnex-core/src/rmc/structures/qbuffer.rs b/rnex-core/src/rmc/structures/qbuffer.rs index 8fbfd5e..d459091 100644 --- a/rnex-core/src/rmc/structures/qbuffer.rs +++ b/rnex-core/src/rmc/structures/qbuffer.rs @@ -8,7 +8,7 @@ use crate::rmc::structures::{Result, RmcSerialize}; pub struct QBuffer(pub Vec); impl RmcSerialize for QBuffer{ - fn serialize(&self, writer: &mut dyn Write) -> Result<()> { + fn serialize(&self, writer: &mut impl Write) -> Result<()> { let len_u16 = self.0.len() as u16; writer.write(bytes_of(&len_u16))?; @@ -17,7 +17,7 @@ impl RmcSerialize for QBuffer{ Ok(()) } - fn deserialize(mut reader: &mut dyn Read) -> Result { + fn deserialize(mut reader: &mut impl Read) -> Result { let size: u16 = reader.read_struct(IS_BIG_ENDIAN)?; let mut vec = vec![0; size as usize]; diff --git a/rnex-core/src/rmc/structures/qresult.rs b/rnex-core/src/rmc/structures/qresult.rs index 77ad70e..c614080 100644 --- a/rnex-core/src/rmc/structures/qresult.rs +++ b/rnex-core/src/rmc/structures/qresult.rs @@ -26,12 +26,12 @@ impl QResult{ } impl RmcSerialize for QResult{ - fn serialize(&self, writer: &mut dyn Write) -> Result<()> { + fn serialize(&self, writer: &mut impl Write) -> Result<()> { writer.write(bytes_of(self))?; Ok(()) } - fn deserialize(mut reader: &mut dyn Read) -> Result { + fn deserialize(mut reader: &mut impl Read) -> Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } } \ No newline at end of file diff --git a/rnex-core/src/rmc/structures/rmc_struct.rs b/rnex-core/src/rmc/structures/rmc_struct.rs index 071cfdb..670b1e0 100644 --- a/rnex-core/src/rmc/structures/rmc_struct.rs +++ b/rnex-core/src/rmc/structures/rmc_struct.rs @@ -1,6 +1,12 @@ -use std::io::{Cursor, Read, Write}; +use std::any::Any; +use std::cmp::max; +use std::fmt::Arguments; +use std::io; +use std::io::{Cursor, ErrorKind, IoSlice, Read, Write}; +use std::ops::Sub; use bytemuck::bytes_of; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; +use crate::rmc::structures; use crate::rmc::structures::Error::VersionMismatch; use crate::rmc::structures::Result; @@ -10,35 +16,97 @@ struct StructureHeader{ length: u32 } -pub fn write_struct(writer: &mut dyn Write, version: u8, pred: impl FnOnce(&mut Vec) -> Result<()> ) -> Result<()> { +#[cfg(feature = "rmc_struct_header")] +pub const HEADER_SIZE: u32 = 0; +#[cfg(not(feature = "rmc_struct_header"))] +pub const HEADER_SIZE: u32 = 5; + +pub struct OnlyWriteVec<'a>(&'a mut Vec); + +impl Write for OnlyWriteVec<'_> { + fn flush(&mut self) -> io::Result<()> { + self.0.flush() + } + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0.write(buf) + } + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.0.write_all(buf) + } + fn write_fmt(&mut self, args: Arguments<'_>) -> io::Result<()> { + self.0.write_fmt(args) + } + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + self.0.write_vectored(bufs) + } +} + +#[cfg(feature = "rmc_struct_header")] +pub fn write_struct(writer: &mut T, version: u8, inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> { writer.write_all(&[version])?; - let mut scratch_space: Vec = Vec::new(); + writer.write_all(bytes_of(&inner_size))?; - (pred)(&mut scratch_space)?; - - let u32_size = scratch_space.len() as u32; - - writer.write_all(bytes_of(&u32_size))?; - writer.write_all(&scratch_space)?; + (pred)(writer)?; Ok(()) } -pub fn read_struct(mut reader: &mut dyn Read, version: u8, pred: impl FnOnce(&mut Cursor>) -> Result) -> Result { + + +#[cfg(not(feature = "rmc_struct_header"))] +pub fn write_struct(writer: &mut T, version: u8, _inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> { + pred(writer) +} + + +pub struct SubRead<'a, T: Read>{ + left_to_read: usize, + origin: &'a mut T +} + +impl<'a, T: Read> SubRead<'a, T>{ + pub const fn new(origin: &'a mut T, left_to_read: usize) -> Self{ + Self{ + left_to_read, + origin + } + } +} + +impl Read for SubRead<'_, T>{ + #[inline(always)] + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let max_read = max(self.left_to_read, buf.len()); + let read = self.origin.read(&mut buf[..max_read])?; + self.left_to_read -= read; + Ok(read) + } + + #[inline(always)] + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + if buf.len() > self.left_to_read{ + return Err(io::Error::new(ErrorKind::UnexpectedEof, "Would run over end of SubRead")); + } + self.left_to_read -= buf.len(); + self.origin.read_exact(buf) + } +} + +#[cfg(feature = "rmc_struct_header")] +pub fn read_struct(mut reader: &mut R, version: u8, pred: impl FnOnce(&mut SubRead) -> Result) -> Result { let ver: u8 = reader.read_struct(IS_BIG_ENDIAN)?; - if ver != version{ + if ver != version { return Err(VersionMismatch(ver)); } let size: u32 = reader.read_struct(IS_BIG_ENDIAN)?; - let mut vec = vec![0u8; size as usize]; + Ok(pred(&mut SubRead::new(reader, size as usize))?) +} - reader.read_exact(&mut vec)?; - - let mut cursor = Cursor::new(vec); - - Ok(pred(&mut cursor)?) -} \ No newline at end of file +#[cfg(not(feature = "rmc_struct_header"))] +pub fn read_struct(mut reader: &mut R, version: u8, pred: impl FnOnce(&mut R) -> Result) -> Result { + Ok(pred(&mut reader)?) +} diff --git a/rnex-core/src/rmc/structures/string.rs b/rnex-core/src/rmc/structures/string.rs index d25bc81..e090957 100644 --- a/rnex-core/src/rmc/structures/string.rs +++ b/rnex-core/src/rmc/structures/string.rs @@ -1,39 +1,49 @@ use std::io::{Read, Write}; use bytemuck::bytes_of; use log::error; +use rocket::form::validate::Len; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use super::{Result, RmcSerialize}; impl RmcSerialize for String{ - fn deserialize(mut reader: &mut dyn Read) -> Result { + fn deserialize(mut reader: &mut impl Read) -> Result { let len: u16 = reader.read_struct(IS_BIG_ENDIAN)?; - let mut data = vec![0; len as usize - 1]; + if len == 0{ + return Ok("".to_string()); + } + let mut data = vec![0; len as usize]; reader.read_exact(&mut data)?; - - let null: u8 = reader.read_struct(IS_BIG_ENDIAN)?; - if null != 0{ + if *data.last().unwrap() != 0{ error!("unable to find null terminator... continuing anyways"); } + data.pop(); Ok(String::from_utf8(data)?) } - fn serialize(&self, writer: &mut dyn Write) -> Result<()> { + fn serialize(&self, writer: &mut impl Write) -> Result<()> { (&self[..]).serialize(writer) } + fn serialize_write_size(&self) -> Result { + (&self[..]).serialize_write_size() + } } impl RmcSerialize for &str{ - fn deserialize(_reader: &mut dyn Read) -> Result { + fn deserialize(_reader: &mut impl Read) -> Result { panic!("cannot serialize to &str") } - fn serialize(&self, writer: &mut dyn Write) -> Result<()> { + fn serialize(&self, writer: &mut impl Write) -> Result<()> { let u16_len: u16 = (self.len() + 1) as u16; - writer.write(bytes_of(&u16_len))?; + writer.write_all(bytes_of(&u16_len))?; - writer.write(self.as_bytes())?; - writer.write(&[0])?; + writer.write_all(self.as_bytes())?; + writer.write_all(&[0])?; Ok(()) } + #[inline(always)] + fn serialize_write_size(&self) -> Result { + Ok(2 + self.as_bytes().len() as u32 + 1) + } } diff --git a/rnex-core/src/rmc/structures/variant.rs b/rnex-core/src/rmc/structures/variant.rs index ebd25b8..6056f3f 100644 --- a/rnex-core/src/rmc/structures/variant.rs +++ b/rnex-core/src/rmc/structures/variant.rs @@ -16,7 +16,7 @@ pub enum Variant{ } impl RmcSerialize for Variant{ - fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> { + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { match self{ Variant::None => { writer.write_all(&[0])?; @@ -50,7 +50,7 @@ impl RmcSerialize for Variant{ Ok(()) } - fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { match u8::deserialize(reader)?{ 0 => Ok(Variant::None), 1 => Ok(Variant::SInt64(i64::deserialize(reader)?)), From 367a8fb553d3096628a1a3b17aa43b67ed336735 Mon Sep 17 00:00:00 2001 From: Maple Date: Thu, 13 Nov 2025 08:39:39 +0100 Subject: [PATCH 030/203] fix dockerfile --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index f1ea22f..a140f56 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,8 +10,8 @@ COPY . . RUN git submodule update --init --recursive -RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo test --target x86_64-unknown-linux-musl -RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --target x86_64-unknown-linux-musl # +RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo test --features rmc_struct_header --target x86_64-unknown-linux-musl +RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --features rmc_struct_header --release --target x86_64-unknown-linux-musl # FROM scratch AS node-holder COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/edge_node_holder_server /edge_node_holder_server From 11ba2b147047df77068ec7fafc84bc8408288c1c Mon Sep 17 00:00:00 2001 From: Maple Date: Thu, 13 Nov 2025 09:51:05 +0100 Subject: [PATCH 031/203] reduce dependency bloat --- .gitmodules | 3 - Cargo.lock | 2039 +----------------------- grpc-protobufs | 1 - rnex-core/Cargo.toml | 10 +- rnex-core/src/executables/common.rs | 7 +- rnex-core/src/grpc/account.rs | 29 +- rnex-core/src/grpc/mod.rs | 4 +- rnex-core/src/lib.rs | 1 - rnex-core/src/main.rs | 1 - rnex-core/src/rmc/structures/string.rs | 1 - rnex-core/src/web/mod.rs | 92 -- 11 files changed, 106 insertions(+), 2082 deletions(-) delete mode 100644 .gitmodules delete mode 160000 grpc-protobufs delete mode 100644 rnex-core/src/web/mod.rs diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 64cd88d..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "grpc-protobufs"] - path = grpc-protobufs - url = https://github.com/PretendoNetwork/grpc-protobufs.git diff --git a/Cargo.lock b/Cargo.lock index 7965148..7ed1c06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,28 +59,6 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "async-trait" version = "0.1.88" @@ -92,80 +70,12 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "atomic" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" - -[[package]] -name = "atomic" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - [[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "axum" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" -dependencies = [ - "async-trait", - "axum-core", - "bytes", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower 0.5.2", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "mime", - "pin-project-lite", - "rustversion", - "sync_wrapper", - "tower-layer", - "tower-service", -] - [[package]] name = "backtrace" version = "0.3.75" @@ -178,7 +88,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -187,12 +97,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "binascii" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" - [[package]] name = "bitflags" version = "2.9.1" @@ -261,12 +165,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - [[package]] name = "chrono" version = "0.4.41" @@ -343,33 +241,21 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" -[[package]] -name = "cookie" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + [[package]] name = "criterion" version = "0.7.0" @@ -444,16 +330,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "ctrlc" -version = "3.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73" -dependencies = [ - "nix", - "windows-sys 0.59.0", -] - [[package]] name = "deranged" version = "0.4.0" @@ -463,39 +339,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "devise" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1d90b0c4c777a2cad215e3c7be59ac7c15adf45cf76317009b7d096d46f651d" -dependencies = [ - "devise_codegen", - "devise_core", -] - -[[package]] -name = "devise_codegen" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71b28680d8be17a570a2334922518be6adc3f58ecc880cbb404eaeb8624fd867" -dependencies = [ - "devise_core", - "quote", -] - -[[package]] -name = "devise_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b035a542cf7abf01f2e3c4d5a7acbaebfefe120ae4efc7bde3df98186e4b8af7" -dependencies = [ - "bitflags", - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 2.0.104", -] - [[package]] name = "digest" version = "0.10.7" @@ -507,17 +350,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "dotenv" version = "0.15.0" @@ -531,48 +363,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] -name = "encoding_rs" -version = "0.8.35" +name = "flate2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "figment" -version = "0.10.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" -dependencies = [ - "atomic 0.6.1", - "pear", - "serde", - "toml", - "uncased", - "version_check", + "crc32fast", + "miniz_oxide", ] [[package]] @@ -581,108 +378,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generator" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" -dependencies = [ - "cc", - "libc", - "log", - "rustversion", - "windows", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -701,19 +396,7 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.1+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", + "wasi", ] [[package]] @@ -722,50 +405,6 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" -[[package]] -name = "glob" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" - -[[package]] -name = "h2" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.10.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "h2" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http 1.3.1", - "indexmap 2.10.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "half" version = "2.7.1" @@ -777,24 +416,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - [[package]] name = "hex" version = "0.4.3" @@ -810,17 +431,6 @@ dependencies = [ "digest", ] -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http" version = "1.3.1" @@ -832,168 +442,12 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http 1.3.1", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http 1.3.1", - "http-body 1.0.1", - "pin-project-lite", -] - [[package]] name = "httparse" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "0.14.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.27", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.5.10", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "h2 0.4.11", - "http 1.3.1", - "http-body 1.0.1", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http 1.3.1", - "hyper 1.6.0", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", -] - -[[package]] -name = "hyper-timeout" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" -dependencies = [ - "hyper 1.6.0", - "hyper-util", - "pin-project-lite", - "tokio", - "tower-service", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper 1.6.0", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" -dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "hyper 1.6.0", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2 0.6.0", - "system-configuration", - "tokio", - "tower-service", - "tracing", - "windows-registry", -] - [[package]] name = "iana-time-zone" version = "0.1.63" @@ -1018,140 +472,6 @@ dependencies = [ "cc", ] -[[package]] -name = "icu_collections" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" - -[[package]] -name = "icu_provider" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" -dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" -dependencies = [ - "equivalent", - "hashbrown 0.15.4", - "serde", -] - -[[package]] -name = "inlinable_string" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" - [[package]] name = "inout" version = "0.1.4" @@ -1172,33 +492,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "is-terminal" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.59.0", -] - [[package]] name = "itertools" version = "0.13.0" @@ -1230,30 +523,12 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - -[[package]] -name = "litemap" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" - [[package]] name = "lock_api" version = "0.4.13" @@ -1270,21 +545,6 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" -[[package]] -name = "loom" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "serde", - "serde_json", - "tracing", - "tracing-subscriber", -] - [[package]] name = "macros" version = "0.0.0" @@ -1304,21 +564,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - [[package]] name = "md-5" version = "0.10.6" @@ -1335,12 +580,6 @@ version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "miniz_oxide" version = "0.8.9" @@ -1348,6 +587,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -1357,68 +597,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "windows-sys 0.59.0", ] -[[package]] -name = "multer" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http 1.3.1", - "httparse", - "memchr", - "mime", - "spin", - "tokio", - "tokio-util", - "version_check", -] - -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nix" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" -dependencies = [ - "bitflags", - "cfg-if", - "cfg_aliases", - "libc", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - [[package]] name = "num-conv" version = "0.1.0" @@ -1434,16 +616,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "num_threads" version = "0.1.7" @@ -1474,56 +646,6 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" -[[package]] -name = "openssl" -version = "0.10.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-sys" -version = "0.9.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "parking_lot" version = "0.12.4" @@ -1544,7 +666,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -1553,73 +675,18 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pear" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467" -dependencies = [ - "inlinable_string", - "pear_codegen", - "yansi", -] - -[[package]] -name = "pear_codegen" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147" -dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 2.0.104", -] - [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "pin-project-lite" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - [[package]] name = "plotters" version = "0.3.7" @@ -1648,15 +715,6 @@ dependencies = [ "plotters-backend", ] -[[package]] -name = "potential_utf" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" -dependencies = [ - "zerovec", -] - [[package]] name = "powerfmt" version = "0.2.0" @@ -1681,28 +739,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "proc-macro2-diagnostics" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", - "version_check", - "yansi", -] - -[[package]] -name = "prost" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" -dependencies = [ - "bytes", -] - [[package]] name = "prudpv1" version = "0.1.0" @@ -1730,12 +766,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - [[package]] name = "rand" version = "0.8.5" @@ -1763,7 +793,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom", ] [[package]] @@ -1804,26 +834,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "ref-cast" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "regex" version = "1.11.1" @@ -1832,17 +842,8 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] @@ -1853,63 +854,15 @@ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "reqwest" -version = "0.12.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.4.11", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "hyper 1.6.0", - "hyper-rustls", - "hyper-tls", - "hyper-util", - "js-sys", - "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-native-tls", - "tower 0.5.2", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "ring" version = "0.17.14" @@ -1918,7 +871,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom", "libc", "untrusted", "windows-sys 0.52.0", @@ -1929,11 +882,9 @@ name = "rnex-core" version = "0.1.1" dependencies = [ "anyhow", - "async-trait", "bytemuck", "chrono", "criterion", - "ctrlc", "dotenv", "hex", "hmac", @@ -1945,124 +896,29 @@ dependencies = [ "paste", "rand", "rc4", - "reqwest", - "rocket", "simplelog", "thiserror", "tokio", - "tonic", "typenum", + "ureq", "v-byte-helpers", ] -[[package]] -name = "rocket" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a516907296a31df7dc04310e7043b61d71954d703b603cc6867a026d7e72d73f" -dependencies = [ - "async-stream", - "async-trait", - "atomic 0.5.3", - "binascii", - "bytes", - "either", - "figment", - "futures", - "indexmap 2.10.0", - "log", - "memchr", - "multer", - "num_cpus", - "parking_lot", - "pin-project-lite", - "rand", - "ref-cast", - "rocket_codegen", - "rocket_http", - "serde", - "serde_json", - "state", - "tempfile", - "time", - "tokio", - "tokio-stream", - "tokio-util", - "ubyte", - "version_check", - "yansi", -] - -[[package]] -name = "rocket_codegen" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46" -dependencies = [ - "devise", - "glob", - "indexmap 2.10.0", - "proc-macro2", - "quote", - "rocket_http", - "syn 2.0.104", - "unicode-xid", - "version_check", -] - -[[package]] -name = "rocket_http" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e274915a20ee3065f611c044bd63c40757396b6dbc057d6046aec27f14f882b9" -dependencies = [ - "cookie", - "either", - "futures", - "http 0.2.12", - "hyper 0.14.32", - "indexmap 2.10.0", - "log", - "memchr", - "pear", - "percent-encoding", - "pin-project-lite", - "ref-cast", - "serde", - "smallvec", - "stable-pattern", - "state", - "time", - "tokio", - "uncased", -] - [[package]] name = "rustc-demangle" version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" -[[package]] -name = "rustix" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.60.2", -] - [[package]] name = "rustls" version = "0.23.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ + "log", "once_cell", + "ring", "rustls-pki-types", "rustls-webpki", "subtle", @@ -2110,50 +966,12 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "schannel" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "serde" version = "1.0.219" @@ -2186,36 +1004,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "shlex" version = "1.3.0" @@ -2231,6 +1019,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "simplelog" version = "0.12.2" @@ -2254,16 +1048,6 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "socket2" version = "0.6.0" @@ -2274,36 +1058,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "stable-pattern" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" -dependencies = [ - "memchr", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "state" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" -dependencies = [ - "loom", -] - [[package]] name = "subtle" version = "2.6.1" @@ -2332,60 +1086,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tempfile" -version = "3.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" -dependencies = [ - "fastrand", - "getrandom 0.3.3", - "once_cell", - "rustix", - "windows-sys 0.59.0", -] - [[package]] name = "termcolor" version = "1.4.1" @@ -2415,15 +1115,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - [[package]] name = "time" version = "0.3.41" @@ -2457,16 +1148,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tinystr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" -dependencies = [ - "displaydoc", - "zerovec", -] - [[package]] name = "tinytemplate" version = "1.2.1" @@ -2492,7 +1173,7 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "slab", - "socket2 0.6.0", + "socket2", "tokio-macros", "windows-sys 0.59.0", ] @@ -2508,290 +1189,18 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap 2.10.0", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "tonic" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64", - "bytes", - "h2 0.4.11", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "hyper 1.6.0", - "hyper-timeout", - "hyper-util", - "percent-encoding", - "pin-project", - "prost", - "socket2 0.5.10", - "tokio", - "tokio-stream", - "tower 0.4.13", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-http" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" -dependencies = [ - "bitflags", - "bytes", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "iri-string", - "pin-project-lite", - "tower 0.5.2", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - [[package]] name = "typenum" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" -[[package]] -name = "ubyte" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f720def6ce1ee2fc44d40ac9ed6d3a59c361c80a75a7aa8e75bb9baed31cf2ea" -dependencies = [ - "serde", -] - -[[package]] -name = "uncased" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" -dependencies = [ - "serde", - "version_check", -] - [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "untrusted" version = "0.9.0" @@ -2799,21 +1208,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] -name = "url" -version = "2.5.4" +name = "ureq" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "d39cb1dbab692d82a977c0392ffac19e188bd9186a9f32806f0aaa859d75585a" dependencies = [ - "form_urlencoded", - "idna", + "base64", + "flate2", + "log", "percent-encoding", + "rustls", + "rustls-pki-types", + "ureq-proto", + "utf-8", + "webpki-roots", ] [[package]] -name = "utf8_iter" -version = "1.0.4" +name = "ureq-proto" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2" +dependencies = [ + "base64", + "http", + "httparse", + "log", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "v-byte-helpers" @@ -2824,18 +1251,6 @@ dependencies = [ "macros 0.1.1", ] -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.5" @@ -2852,30 +1267,12 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[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 = "wasm-bindgen" version = "0.2.100" @@ -2902,19 +1299,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.100" @@ -2958,21 +1342,14 @@ dependencies = [ ] [[package]] -name = "winapi" -version = "0.3.9" +name = "webpki-roots" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "rustls-pki-types", ] -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" version = "0.1.9" @@ -2982,21 +1359,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-core" version = "0.61.2" @@ -3038,17 +1400,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" -[[package]] -name = "windows-registry" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" -dependencies = [ - "windows-link", - "windows-result", - "windows-strings", -] - [[package]] name = "windows-result" version = "0.3.4" @@ -3073,7 +1424,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -3082,31 +1433,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.3", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -3115,228 +1442,64 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "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", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows-targets" -version = "0.53.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "winnow" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen-rt" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] - -[[package]] -name = "writeable" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" - -[[package]] -name = "yansi" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" -dependencies = [ - "is-terminal", -] - -[[package]] -name = "yoke" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", - "synstructure", -] - [[package]] name = "zerocopy" version = "0.8.26" @@ -3357,62 +1520,8 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", - "synstructure", -] - [[package]] name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] diff --git a/grpc-protobufs b/grpc-protobufs deleted file mode 160000 index 405fe9b..0000000 --- a/grpc-protobufs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 405fe9b47b416e76b21d7087b2ed11606deccfcf diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index b609afb..cd52ec6 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -18,19 +18,17 @@ rand = "0.8.5" hmac = "0.12.1" md-5 = "^0.10.6" tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "net", "sync", "fs"] } -tonic = "0.12.3" hex = "0.4.3" macros = { path = "../macros" } -rocket = { version = "0.5.1", features = ["json", "serde_json"] } -async-trait = "0.1.86" paste = "1.0.15" typenum = "1.18.0" -reqwest = { version= "0.12.18", features = ["blocking"]} json = "0.12.4" -ctrlc = "3.4.7" -criterion = "0.7.0" anyhow = "1.0.100" +ureq = "3.1.4" + +[dev-dependencies] +criterion = "0.7.0" [features] rmc_struct_header = [] diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index 73571d7..7a55f24 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -19,8 +19,11 @@ const IP_REQ_SERVICE_URL: &str = "https://ipinfo.io/ip"; fn try_get_ip() -> Result> { - let req = reqwest::blocking::get(IP_REQ_SERVICE_URL)?; - Ok(req.text()?.parse()?) + let mut req = ureq::get(IP_REQ_SERVICE_URL) + .call()?; + + + Ok(req.body_mut().read_to_string()?.parse()?) } pub static OWN_IP_PRIVATE: Lazy = Lazy::new(|| { diff --git a/rnex-core/src/grpc/account.rs b/rnex-core/src/grpc/account.rs index 5f49cbd..5314006 100644 --- a/rnex-core/src/grpc/account.rs +++ b/rnex-core/src/grpc/account.rs @@ -1,11 +1,11 @@ use std::{env, result}; use std::array::TryFromSliceError; +use std::ops::Deref; use std::str::FromStr; use json::{object, JsonValue}; use once_cell::sync::Lazy; -use reqwest::{Body, Method, Url}; -use reqwest::header::HeaderValue; use thiserror::Error; +use tokio::task::{spawn_blocking, JoinError}; use crate::grpc::account::Error::SomethingHappened; static API_KEY: Lazy = Lazy::new(||{ let key = env::var("ACCOUNT_GQL_API_KEY") @@ -26,27 +26,38 @@ static CLIENT_URI: Lazy = Lazy::new(||{ #[derive(Error, Debug)] pub enum Error{ #[error(transparent)] - Creation(#[from] reqwest::Error), + RequestError(#[from] ureq::Error), #[error(transparent)] Json(#[from] json::Error), - #[error(transparent)] - Status(#[from] tonic::Status), + //#[error(transparent)] + //Status(#[from] tonic::Status), #[error("invalid password size: {0}")] PasswordConversion(#[from] TryFromSliceError), #[error("something happened")] - SomethingHappened + SomethingHappened, + #[error("error joining blocking task: {0}")] + Join(#[from] JoinError) } pub type Result = result::Result; -pub struct Client(reqwest::Client); +pub struct Client;//(reqwest::Client); impl Client{ pub async fn new() -> Result { - Ok(Self(reqwest::ClientBuilder::new().build()?)) + //Ok(Self(reqwest::ClientBuilder::new().build()?)) + Ok(Self) } async fn do_request(&self, request_data: JsonValue) -> Result{ + let mut request = ureq::post(CLIENT_URI.as_str()) + .header("X-API-Key", API_KEY.deref()) + .content_type("application/json"); + let mut response = spawn_blocking(move || request.send(request_data.to_string())).await??; + + let str_body = response.body_mut().read_to_string()?; + Ok(json::parse(&str_body)?) + /* let mut request = reqwest::Request::new(Method::POST, Url::from_str(CLIENT_URI.as_str()).unwrap()); *(request.body_mut()) = Some(Body::from(request_data.to_string())); @@ -56,6 +67,8 @@ impl Client{ let response = self.0.execute(request).await?; Ok(json::parse(&response.text().await?)?) + + */ } pub async fn get_nex_password(&mut self , pid: u32) -> Result<[u8; 16]>{ diff --git a/rnex-core/src/grpc/mod.rs b/rnex-core/src/grpc/mod.rs index 31831f8..c96ccfe 100644 --- a/rnex-core/src/grpc/mod.rs +++ b/rnex-core/src/grpc/mod.rs @@ -2,7 +2,7 @@ //! before account rs is finished. //! //! This WILL be deprecated as soon as account rs is in a stable state. -use tonic::{Request, Status}; +//use tonic::{Request, Status}; -type InterceptorFunc = Box) -> Result, Status> + Send>; +//type InterceptorFunc = Box) -> Result, Status> + Send>; pub mod account; \ No newline at end of file diff --git a/rnex-core/src/lib.rs b/rnex-core/src/lib.rs index 4a4f1ef..3920565 100644 --- a/rnex-core/src/lib.rs +++ b/rnex-core/src/lib.rs @@ -17,7 +17,6 @@ pub mod kerberos; pub mod nex; pub mod result; pub mod versions; -pub mod web; pub mod common; pub mod reggie; pub mod rnex_proxy_common; diff --git a/rnex-core/src/main.rs b/rnex-core/src/main.rs index cfa323d..9ff052f 100644 --- a/rnex-core/src/main.rs +++ b/rnex-core/src/main.rs @@ -32,7 +32,6 @@ mod kerberos; mod nex; mod result; mod versions; -mod web; pub mod reggie; pub mod util; pub mod common; diff --git a/rnex-core/src/rmc/structures/string.rs b/rnex-core/src/rmc/structures/string.rs index e090957..12123fd 100644 --- a/rnex-core/src/rmc/structures/string.rs +++ b/rnex-core/src/rmc/structures/string.rs @@ -1,7 +1,6 @@ use std::io::{Read, Write}; use bytemuck::bytes_of; use log::error; -use rocket::form::validate::Len; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use super::{Result, RmcSerialize}; diff --git a/rnex-core/src/web/mod.rs b/rnex-core/src/web/mod.rs deleted file mode 100644 index 9412967..0000000 --- a/rnex-core/src/web/mod.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::sync::Arc; -use async_trait::async_trait; -use rocket::{get, routes, Request, State}; -use rocket::request::{FromRequest, Outcome}; -use rocket::serde::json::Json; -use tokio::task::JoinHandle; -use crate::nex::matchmake::MatchmakeManager; -use crate::rmc::protocols::notifications::NotificationEvent; - -struct RnexApiAuth; - -#[async_trait] -impl<'r> FromRequest<'r> for RnexApiAuth{ - - type Error = (); - async fn from_request<'a>(_request: &'r Request<'a>) -> Outcome { - Outcome::Success(RnexApiAuth) - } -} - - -#[get("/gatherings")] -async fn gatherings(mmm: &State>) -> Json>{ - let matches = mmm.sessions.read().await; - - Json(matches.keys().map(|v| *v).collect()) -} - -#[get("/gathering//players")] -async fn players_in_match(mmm: &State>, gid: u32) -> Option>>{ - let mmm = mmm.sessions.read().await; - - let gathering = mmm.get(&gid)?; - - let gathering = gathering.clone(); - - drop(mmm); - - let gathering = gathering.lock().await; - - Some(Json(gathering.connected_players.iter().filter_map(|p| p.upgrade()).map(|p| p.pid).collect())) -} -/* -#[get("/player//disconnect")] -async fn disconnect_player(_auth: RnexApiAuth, mmm: &State>, pid: u32) -> Option<()>{ - // this doesnt work and is broken, there might be some other way to remotely close gatherings... - // also if anyone gets this working change it to POST cause the only reason its get is because - // that makes testing it easier - let mmm = mmm.users.read().await; - - for player in mmm.values().filter_map(|p| p.upgrade()).filter(|p| p.pid == pid) { - player.remote.get_connection().0.close_connection().await; - } - - - Some(()) -}*/ - -#[get("/gathering//close")] -async fn close_gathering(_auth: RnexApiAuth, mmm: &State>, gid: u32) -> Option<()>{ - // this doesnt work and is broken, there might be some other way to remotely close gatherings... - // also if anyone gets this working change it to POST cause the only reason its get is because - // that makes testing it easier - let mmm = mmm.sessions.read().await; - - let gathering = mmm.get(&gid)?; - - let gathering = gathering.clone(); - - drop(mmm); - - let gathering = gathering.lock().await; - - gathering.broadcast_notification(&NotificationEvent{ - pid_source: gathering.session.gathering.owner_pid, - notif_type: 109000, - param_1: gathering.session.gathering.self_gid, - ..Default::default() - }).await; - - Some(()) -} - -pub async fn start_web(mgr: Arc) -> JoinHandle<()> { - tokio::spawn(async move { - rocket::build() - .mount("/", routes![gatherings, players_in_match, close_gathering]) - .manage(mgr) - .launch().await - .expect("unable to start webserver"); - }) -} \ No newline at end of file From 755e5c47470e53e691117370481546fbd1be929d Mon Sep 17 00:00:00 2001 From: Maple Date: Thu, 13 Nov 2025 10:06:58 +0100 Subject: [PATCH 032/203] fix warnings and criterion in main --- macros/src/lib.rs | 3 +-- rnex-core/src/grpc/account.rs | 3 +-- rnex-core/src/kerberos/mod.rs | 1 - rnex-core/src/main.rs | 21 +-------------------- rnex-core/src/nex/auth_handler.rs | 4 ++-- rnex-core/src/prudp/station_url.rs | 5 ++--- rnex-core/src/rmc/response.rs | 2 +- rnex-core/src/rmc/structures/any.rs | 2 +- rnex-core/src/rmc/structures/list.rs | 2 +- rnex-core/src/rmc/structures/primitives.rs | 18 +++++++++--------- rnex-core/src/rmc/structures/qbuffer.rs | 2 +- rnex-core/src/rmc/structures/qresult.rs | 2 +- rnex-core/src/rmc/structures/ranking.rs | 1 - rnex-core/src/rmc/structures/rmc_struct.rs | 21 +++++++++++---------- rnex-core/src/rmc/structures/string.rs | 2 +- 15 files changed, 33 insertions(+), 56 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 67486ef..d088561 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -126,7 +126,6 @@ fn gen_serialize_data_struct( let ident = f.ident.as_ref().unwrap(); - let ty = &f.ty; size_content.append_all(quote! { + rnex_core::rmc::structures::RmcSerialize::serialize_write_size(&self.#ident)? @@ -259,7 +258,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { let mut inner_match_de = quote! {}; let mut inner_match_se = quote! {}; - let mut inner_match_len = quote!{}; + //let mut inner_match_len = quote!{}; for variant in e.variants { let Some((_, val)) = variant.discriminant else { diff --git a/rnex-core/src/grpc/account.rs b/rnex-core/src/grpc/account.rs index 5314006..a70149f 100644 --- a/rnex-core/src/grpc/account.rs +++ b/rnex-core/src/grpc/account.rs @@ -1,7 +1,6 @@ use std::{env, result}; use std::array::TryFromSliceError; use std::ops::Deref; -use std::str::FromStr; use json::{object, JsonValue}; use once_cell::sync::Lazy; use thiserror::Error; @@ -50,7 +49,7 @@ impl Client{ } async fn do_request(&self, request_data: JsonValue) -> Result{ - let mut request = ureq::post(CLIENT_URI.as_str()) + let request = ureq::post(CLIENT_URI.as_str()) .header("X-API-Key", API_KEY.deref()) .content_type("application/json"); let mut response = spawn_blocking(move || request.send(request_data.to_string())).await??; diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index a54764e..b118651 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -158,7 +158,6 @@ impl Ticket{ #[cfg(test)] mod test{ - use chrono::{Datelike, Utc}; use crate::kerberos::KerberosDateTime; #[test] diff --git a/rnex-core/src/main.rs b/rnex-core/src/main.rs index 9ff052f..eda5915 100644 --- a/rnex-core/src/main.rs +++ b/rnex-core/src/main.rs @@ -10,18 +10,8 @@ extern crate self as rust_nex; -use crate::nex::account::Account; -use chrono::{Local, SecondsFormat}; use once_cell::sync::Lazy; -use simplelog::{ - ColorChoice, CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode, WriteLogger, -}; -use std::fs::File; -use std::net::{Ipv4Addr}; -use std::sync::Once; -use std::{env, fs}; use std::hint::black_box; -use criterion::{criterion_group, criterion_main, Criterion}; mod prudp; pub mod rmc; @@ -118,7 +108,7 @@ static DUMMY: Lazy = Lazy::new(|| AutoMatchmakeParam{ static DUMMY_SER: Lazy> = Lazy::new(|| serialize_to_vec(DUMMY.deref())); fn serialize_to_vec(r: &impl RmcSerialize) -> Vec{ - let mut vec = r.to_data(); + let vec = r.to_data(); vec.unwrap() } @@ -126,15 +116,6 @@ fn serialize_to_vec(r: &impl RmcSerialize) -> Vec{ fn read_struct(r: &[u8]) -> T{ T::deserialize(&mut Cursor::new(r)).unwrap() } -fn matchmake_with_param(c: &mut Criterion) { - let raw = DUMMY.deref(); - let ser = DUMMY_SER.deref().as_slice(); - c.bench_function("mmparam: ser", |b| b.iter(move || serialize_to_vec(black_box(raw)))); - c.bench_function("mmparam: de", |b| b.iter(move || read_struct::(black_box(ser)))); -} - -criterion_group!(benches, matchmake_with_param); -//criterion_main!(benches); fn main(){ for _ in 0..10000000 { diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index e5184d0..9b67fca 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -171,14 +171,14 @@ mod test { let stuff = hex::decode("200100000a0106000000028000000100010051b3995774000000a6321c7f78847c1c5e9fb825eb26bd91841f1a40d92fc694159666119cb13527f1463ac48ad42a63e6613ede67041554b1770978112e6f1f3e177a2bfc75933216dbe38f70133a1eb28e2ae32a4b5c4b0c3e3efd4c02907992e259b257270b57a9dbe7792f4721b07f8fafb9e32d50f2555c616a015c0000004b007072756470733a2f5049443d323b7369643d313b73747265616d3d31303b747970653d323b616464726573733d322e3234332e39352e3131333b706f72743d31303030313b4349443d3100000000000100002c153ba51f00000033006272616e63683a6f726967696e2f70726f6a6563742f7775702d61676d6a206275696c643a335f385f31355f323030345f3000").unwrap(); let stuff = RMCResponse::new(&mut Cursor::new(stuff)).unwrap(); - let rnex_core::rmc::response::RMCResponseResult::Success { call_id, method_id, data: stuff} = stuff.response_result else { + let rnex_core::rmc::response::RMCResponseResult::Success { .. } = stuff.response_result else { panic!() }; // let stuff = hex::decode("0100010051B399577400000085F1736FCFBE93660275A3FE36FED6C2EFC57222AC99A9219CF54170A415B02DF1463AC48AD42A6307813FDE67041554B177097832ED000F892D9551A09F88E9CB0388DC1BC9527CC7384556A3287B2A349ABBF7E34A5A3EC14C2287CC7F78DA616BC3B03A035347FBD2E9A505C8EF42447CD809015F0000004E007072756470733A2F73747265616D3D31303B747970653D323B616464726573733D3139322E3136382E3137382E3132303B706F72743D31303030313B4349443D313B5049443D323B7369643D310000000000010000CDF53AA51F00000033006272616E63683A6F726967696E2F70726F6A6563742F7775702D61676D6A206275696C643A335F385F31355F323030345F3000").unwrap(); - // let stuff = hex::decode("0100010051b399577400000037d3d4814d2b16dd546c94a75d32637b45f856b5abe73cf26cfaa235c5f2c1cef1463ac48ad42a637d873fde67041554b177097880cfa7e10bb810eaf686bfb0a0cf3d65b1f476ebc046d0855327986f557dca14fbb8594883c186b863f2206f22baa0309dbcc81da2f883cb2cdc12628ec7fced015c0000004b007072756470733a2f5049443d323b7369643d313b73747265616d3d31303b747970653d323b616464726573733d322e3234332e39352e3131333b706f72743d31303030313b4349443d310000000000010000b7f33aa51f00000033006272616e63683a6f726967696e2f70726f6a6563742f7775702d61676d6a206275696c643a335f385f31355f323030345f3000").unwrap(); + let stuff = hex::decode("0100010051b399577400000037d3d4814d2b16dd546c94a75d32637b45f856b5abe73cf26cfaa235c5f2c1cef1463ac48ad42a637d873fde67041554b177097880cfa7e10bb810eaf686bfb0a0cf3d65b1f476ebc046d0855327986f557dca14fbb8594883c186b863f2206f22baa0309dbcc81da2f883cb2cdc12628ec7fced015c0000004b007072756470733a2f5049443d323b7369643d313b73747265616d3d31303b747970653d323b616464726573733d322e3234332e39352e3131333b706f72743d31303030313b4349443d310000000000010000b7f33aa51f00000033006272616e63683a6f726967696e2f70726f6a6563742f7775702d61676d6a206275696c643a335f385f31355f323030345f3000").unwrap(); let data = <(QResult, u32, Vec, ConnectionData, String) as RmcSerialize>::deserialize( &mut Cursor::new(stuff), diff --git a/rnex-core/src/prudp/station_url.rs b/rnex-core/src/prudp/station_url.rs index a193b21..a4665c2 100644 --- a/rnex-core/src/prudp/station_url.rs +++ b/rnex-core/src/prudp/station_url.rs @@ -170,9 +170,8 @@ impl Display for StationUrl{ impl<'a> Into for &'a StationUrl{ fn into(self) -> String { - let mut url = self.to_string(); - - + let url = self.to_string(); + url[0..url.len()-1].into() } } diff --git a/rnex-core/src/rmc/response.rs b/rnex-core/src/rmc/response.rs index a732853..c994f8b 100644 --- a/rnex-core/src/rmc/response.rs +++ b/rnex-core/src/rmc/response.rs @@ -471,7 +471,7 @@ mod test { #[test] fn test() { - let mut data_orig = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 69, 4, 20]; + let data_orig = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 69, 4, 20]; let mut data = data_orig; let mut rc4: Rc4 = diff --git a/rnex-core/src/rmc/structures/any.rs b/rnex-core/src/rmc/structures/any.rs index e76b60a..b60ca8a 100644 --- a/rnex-core/src/rmc/structures/any.rs +++ b/rnex-core/src/rmc/structures/any.rs @@ -21,7 +21,7 @@ impl RmcSerialize for Any{ Ok(()) } - fn deserialize(mut reader: &mut impl Read) -> Result { + fn deserialize(reader: &mut impl Read) -> Result { let name = String::deserialize(reader)?; // also length ? diff --git a/rnex-core/src/rmc/structures/list.rs b/rnex-core/src/rmc/structures/list.rs index 980907d..890be9a 100644 --- a/rnex-core/src/rmc/structures/list.rs +++ b/rnex-core/src/rmc/structures/list.rs @@ -20,7 +20,7 @@ impl RmcSerialize for Vec{ Ok(()) } - fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let len: u32 = reader.read_struct(IS_BIG_ENDIAN)?; //let mut vec = Vec::with_capacity(len as usize); diff --git a/rnex-core/src/rmc/structures/primitives.rs b/rnex-core/src/rmc/structures/primitives.rs index 65e732c..8918968 100644 --- a/rnex-core/src/rmc/structures/primitives.rs +++ b/rnex-core/src/rmc/structures/primitives.rs @@ -10,7 +10,7 @@ impl RmcSerialize for u8{ } #[inline(always)] - fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } #[inline(always)] @@ -26,7 +26,7 @@ impl RmcSerialize for i8{ } #[inline(always)] - fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } #[inline(always)] @@ -41,7 +41,7 @@ impl RmcSerialize for u16{ Ok(writer.write_all(bytes_of(self))?) } #[inline(always)] - fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } #[inline(always)] @@ -56,7 +56,7 @@ impl RmcSerialize for i16{ Ok(writer.write_all(bytes_of(self))?) } #[inline(always)] - fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } #[inline(always)] @@ -71,7 +71,7 @@ impl RmcSerialize for u32{ Ok(writer.write_all(bytes_of(self))?) } #[inline(always)] - fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } #[inline(always)] @@ -86,7 +86,7 @@ impl RmcSerialize for i32{ Ok(writer.write_all(bytes_of(self))?) } #[inline(always)] - fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } #[inline(always)] @@ -101,7 +101,7 @@ impl RmcSerialize for u64{ Ok(writer.write_all(bytes_of(self))?) } #[inline(always)] - fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } #[inline(always)] @@ -116,7 +116,7 @@ impl RmcSerialize for i64{ Ok(writer.write_all(bytes_of(self))?) } #[inline(always)] - fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } #[inline(always)] @@ -132,7 +132,7 @@ impl RmcSerialize for f64{ } #[inline(always)] - fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } #[inline(always)] diff --git a/rnex-core/src/rmc/structures/qbuffer.rs b/rnex-core/src/rmc/structures/qbuffer.rs index d459091..fb30e64 100644 --- a/rnex-core/src/rmc/structures/qbuffer.rs +++ b/rnex-core/src/rmc/structures/qbuffer.rs @@ -17,7 +17,7 @@ impl RmcSerialize for QBuffer{ Ok(()) } - fn deserialize(mut reader: &mut impl Read) -> Result { + fn deserialize(reader: &mut impl Read) -> Result { let size: u16 = reader.read_struct(IS_BIG_ENDIAN)?; let mut vec = vec![0; size as usize]; diff --git a/rnex-core/src/rmc/structures/qresult.rs b/rnex-core/src/rmc/structures/qresult.rs index c614080..312540a 100644 --- a/rnex-core/src/rmc/structures/qresult.rs +++ b/rnex-core/src/rmc/structures/qresult.rs @@ -31,7 +31,7 @@ impl RmcSerialize for QResult{ Ok(()) } - fn deserialize(mut reader: &mut impl Read) -> Result { + fn deserialize(reader: &mut impl Read) -> Result { Ok(reader.read_struct(IS_BIG_ENDIAN)?) } } \ No newline at end of file diff --git a/rnex-core/src/rmc/structures/ranking.rs b/rnex-core/src/rmc/structures/ranking.rs index afb0698..9602553 100644 --- a/rnex-core/src/rmc/structures/ranking.rs +++ b/rnex-core/src/rmc/structures/ranking.rs @@ -25,7 +25,6 @@ struct UserData{ mod test{ use std::io::Cursor; use bytemuck::from_bytes; - use tokio::io::AsyncReadExt; use crate::rmc::structures::ranking::{UploadCompetitionData, UserData}; use rnex_core::rmc::structures::RmcSerialize; diff --git a/rnex-core/src/rmc/structures/rmc_struct.rs b/rnex-core/src/rmc/structures/rmc_struct.rs index 670b1e0..52184bb 100644 --- a/rnex-core/src/rmc/structures/rmc_struct.rs +++ b/rnex-core/src/rmc/structures/rmc_struct.rs @@ -1,15 +1,11 @@ -use std::any::Any; + use std::cmp::max; use std::fmt::Arguments; use std::io; -use std::io::{Cursor, ErrorKind, IoSlice, Read, Write}; -use std::ops::Sub; -use bytemuck::bytes_of; -use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -use crate::rmc::structures; -use crate::rmc::structures::Error::VersionMismatch; +use std::io::{ErrorKind, IoSlice, Read, Write}; use crate::rmc::structures::Result; + #[repr(C, packed)] struct StructureHeader{ version: u8, @@ -43,6 +39,8 @@ impl Write for OnlyWriteVec<'_> { #[cfg(feature = "rmc_struct_header")] pub fn write_struct(writer: &mut T, version: u8, inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> { + use bytemuck::bytes_of; + writer.write_all(&[version])?; writer.write_all(bytes_of(&inner_size))?; @@ -55,7 +53,7 @@ pub fn write_struct(writer: &mut T, version: u8, inner_size: u32, pred #[cfg(not(feature = "rmc_struct_header"))] -pub fn write_struct(writer: &mut T, version: u8, _inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> { +pub fn write_struct(writer: &mut T, _version: u8, _inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> { pred(writer) } @@ -94,7 +92,10 @@ impl Read for SubRead<'_, T>{ } #[cfg(feature = "rmc_struct_header")] -pub fn read_struct(mut reader: &mut R, version: u8, pred: impl FnOnce(&mut SubRead) -> Result) -> Result { +pub fn read_struct(reader: &mut R, version: u8, pred: impl FnOnce(&mut SubRead) -> Result) -> Result { + use crate::rmc::structures::Error::VersionMismatch; + use v_byte_helpers::ReadExtensions; + use v_byte_helpers::IS_BIG_ENDIAN; let ver: u8 = reader.read_struct(IS_BIG_ENDIAN)?; if ver != version { @@ -107,6 +108,6 @@ pub fn read_struct(mut reader: &mut R, version: u8, pred: imp } #[cfg(not(feature = "rmc_struct_header"))] -pub fn read_struct(mut reader: &mut R, version: u8, pred: impl FnOnce(&mut R) -> Result) -> Result { +pub fn read_struct(mut reader: &mut R, _version: u8, pred: impl FnOnce(&mut R) -> Result) -> Result { Ok(pred(&mut reader)?) } diff --git a/rnex-core/src/rmc/structures/string.rs b/rnex-core/src/rmc/structures/string.rs index 12123fd..1231956 100644 --- a/rnex-core/src/rmc/structures/string.rs +++ b/rnex-core/src/rmc/structures/string.rs @@ -5,7 +5,7 @@ use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use super::{Result, RmcSerialize}; impl RmcSerialize for String{ - fn deserialize(mut reader: &mut impl Read) -> Result { + fn deserialize(reader: &mut impl Read) -> Result { let len: u16 = reader.read_struct(IS_BIG_ENDIAN)?; if len == 0{ return Ok("".to_string()); From 31d495c932bc17db84ed0a6d182943961c809c74 Mon Sep 17 00:00:00 2001 From: Maple Date: Thu, 13 Nov 2025 14:06:08 +0100 Subject: [PATCH 033/203] add editions --- .ci-scripts/make-edition.sh | 16 ++ .dockerignore | 10 +- .gitlab-ci.yml | 30 ++-- Cargo.lock | 310 ------------------------------------ Dockerfile | 12 +- build-edition.sh | 11 ++ buildscripts/common.sh | 9 ++ editions.yaml | 10 ++ rnex-core/Cargo.toml | 2 +- test-edition.sh | 11 ++ 10 files changed, 85 insertions(+), 336 deletions(-) create mode 100644 .ci-scripts/make-edition.sh create mode 100644 build-edition.sh create mode 100644 buildscripts/common.sh create mode 100644 editions.yaml create mode 100644 test-edition.sh diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh new file mode 100644 index 0000000..5f8694c --- /dev/null +++ b/.ci-scripts/make-edition.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +export EDITION=$1 + +podman build -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . +podman push "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" +podman build -t "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" --target=node-holder . +podman build -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" --target=proxy-secure . +podman build -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" --target=proxy-insecure . +podman build -t "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" --target=backend-auth . +podman build -t "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" --target=backend-secure . +podman push "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" +podman push "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" +podman push "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" +podman push "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" +podman push "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" \ No newline at end of file diff --git a/.dockerignore b/.dockerignore index 0d95126..4e09ffe 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,10 @@ .env -target \ No newline at end of file +target +.dockerignore +Dockerfile +CODE_OF_CONDUCT.md +CONTRIBUTING.md +README.md +.gitignore +LICENSE +.devcontainer.json \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 24011c9..fad0b25 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,28 +1,20 @@ default: image: quay.io/podman/stable + before_script: + - git submodule update --init + - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY variables: DOCKER_TLS_CERTDIR: "/certs" IMAGE_TAG: "${CI_COMMIT_REF_SLUG}" stages: - - test - - build-and-push-image + - build_and_test -build-and-push-image: - stage: build-and-push-image - script: - - git submodule update --init - - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - - podman build -t "$CI_REGISTRY_IMAGE/dev-container:latest" --target=dev-container . - - podman push "$CI_REGISTRY_IMAGE/dev-container:latest" - - podman build -t "$CI_REGISTRY_IMAGE/node-holder:$CI_COMMIT_SHORT_SHA" --target=node-holder . - - podman build -t "$CI_REGISTRY_IMAGE/proxy-secure-v1:$CI_COMMIT_SHORT_SHA" --target=proxy-secure-v1 . - - podman build -t "$CI_REGISTRY_IMAGE/proxy-insecure-v1:$CI_COMMIT_SHORT_SHA" --target=proxy-insecure-v1 . - - podman build -t "$CI_REGISTRY_IMAGE/backend-auth:$CI_COMMIT_SHORT_SHA" --target=backend-auth . - - podman build -t "$CI_REGISTRY_IMAGE/backend-secure:$CI_COMMIT_SHORT_SHA" --target=backend-secure . - - podman push "$CI_REGISTRY_IMAGE/node-holder:$CI_COMMIT_SHORT_SHA" - - podman push "$CI_REGISTRY_IMAGE/proxy-secure-v1:$CI_COMMIT_SHORT_SHA" - - podman push "$CI_REGISTRY_IMAGE/proxy-insecure-v1:$CI_COMMIT_SHORT_SHA" - - podman push "$CI_REGISTRY_IMAGE/backend-auth:$CI_COMMIT_SHORT_SHA" - - podman push "$CI_REGISTRY_IMAGE/backend-secure:$CI_COMMIT_SHORT_SHA" +splatoon: + stage: build_and_test + script: ./.ci-scripts/make-edition.sh splatoon + +friends: + stage: build_and_test + script: ./.ci-scripts/make-edition.sh friends diff --git a/Cargo.lock b/Cargo.lock index 7ed1c06..fe55a2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,15 +17,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - [[package]] name = "android-tzdata" version = "0.1.1" @@ -41,18 +32,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - -[[package]] -name = "anstyle" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" - [[package]] name = "anyhow" version = "1.0.100" @@ -144,12 +123,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - [[package]] name = "cc" version = "1.2.31" @@ -179,33 +152,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "ciborium" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" - -[[package]] -name = "ciborium-ll" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" -dependencies = [ - "ciborium-io", - "half", -] - [[package]] name = "cipher" version = "0.4.4" @@ -216,31 +162,6 @@ dependencies = [ "inout", ] -[[package]] -name = "clap" -version = "4.5.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" -dependencies = [ - "clap_builder", -] - -[[package]] -name = "clap_builder" -version = "4.5.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" -dependencies = [ - "anstyle", - "clap_lex", -] - -[[package]] -name = "clap_lex" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -256,70 +177,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "criterion" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1c047a62b0cc3e145fa84415a3191f628e980b194c2755aa12300a4e6cbd928" -dependencies = [ - "anes", - "cast", - "ciborium", - "clap", - "criterion-plot", - "itertools", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b1bcc0dc7dfae599d84ad0b1a55f80cde8af3725da8313b528da95ef783e338" -dependencies = [ - "cast", - "itertools", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - [[package]] name = "crypto-common" version = "0.1.6" @@ -356,12 +213,6 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - [[package]] name = "flate2" version = "1.1.5" @@ -405,17 +256,6 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" -[[package]] -name = "half" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" -dependencies = [ - "cfg-if", - "crunchy", - "zerocopy", -] - [[package]] name = "hex" version = "0.4.3" @@ -492,15 +332,6 @@ dependencies = [ "libc", ] -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.15" @@ -640,12 +471,6 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "oorandom" -version = "11.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" - [[package]] name = "parking_lot" version = "0.12.4" @@ -687,34 +512,6 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" -[[package]] -name = "plotters" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" - -[[package]] -name = "plotters-svg" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" -dependencies = [ - "plotters-backend", -] - [[package]] name = "powerfmt" version = "0.2.0" @@ -796,26 +593,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rayon" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "rc4" version = "0.1.0" @@ -834,35 +611,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - [[package]] name = "ring" version = "0.17.14" @@ -884,7 +632,6 @@ dependencies = [ "anyhow", "bytemuck", "chrono", - "criterion", "dotenv", "hex", "hmac", @@ -951,21 +698,6 @@ version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -992,18 +724,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "serde_json" -version = "1.0.142" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - [[package]] name = "shlex" version = "1.3.0" @@ -1148,16 +868,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "tokio" version = "1.47.1" @@ -1257,16 +967,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -1331,16 +1031,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "web-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "webpki-roots" version = "1.0.4" diff --git a/Dockerfile b/Dockerfile index a140f56..87f5167 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM rust:alpine AS build-container -RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static +RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static yq bash FROM build-container AS builder @@ -8,23 +8,25 @@ WORKDIR /app COPY . . +ARG EDITION=splatoon + RUN git submodule update --init --recursive -RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo test --features rmc_struct_header --target x86_64-unknown-linux-musl -RUN OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --features rmc_struct_header --release --target x86_64-unknown-linux-musl # +RUN ./test-edition.sh +RUN ./build-edition.sh FROM scratch AS node-holder COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/edge_node_holder_server /edge_node_holder_server ENTRYPOINT ["/edge_node_holder_server"] -FROM alpine:latest AS proxy-insecure-v1 +FROM alpine:latest AS proxy-insecure COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_insecure /proxy_insecure RUN apk add --no-cache ca-certificates RUN update-ca-certificates ENTRYPOINT ["/proxy_insecure"] -FROM alpine:latest AS proxy-secure-v1 +FROM alpine:latest AS proxy-secure COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_secure /proxy_secure RUN apk add --no-cache ca-certificates RUN update-ca-certificates diff --git a/build-edition.sh b/build-edition.sh new file mode 100644 index 0000000..7b1cfc0 --- /dev/null +++ b/build-edition.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +if [ -z ${EDITION+x} ]; then + EDITION=$1 +fi + +# comma seperated list of features for the specified version +source ./buildscripts/common.sh +echo FEATURES: +echo $EDITION_FEATURES + +OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl \ No newline at end of file diff --git a/buildscripts/common.sh b/buildscripts/common.sh new file mode 100644 index 0000000..27fd8cd --- /dev/null +++ b/buildscripts/common.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +TMP_FEATURES_TRAILINGCOMMA=$(yq ea ".$EDITION.features" editions.yaml | sed 's/- //g' | tr '\n' ',') +export EDITION_FEATURES=${TMP_FEATURES_TRAILINGCOMMA::-1} +SETTINGS=$(yq ea ".$EDITION.settings" editions.yaml | yq 'keys[]') +IFS=$'\n' +while IFS=$'\n' read -r KEY; do + VAL=$(yq ea ".$EDITION.settings.$KEY" editions.yaml) + declare "$KEY=$VAL" +done <<< "$SETTINGS" \ No newline at end of file diff --git a/editions.yaml b/editions.yaml new file mode 100644 index 0000000..9ed8552 --- /dev/null +++ b/editions.yaml @@ -0,0 +1,10 @@ +splatoon: + features: + - rmc_struct_header + settings: + AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" + OTHER_ONE: "lol" +friends: + features: + - friends + settings: {} \ No newline at end of file diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index cd52ec6..554a8d9 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -28,7 +28,7 @@ anyhow = "1.0.100" ureq = "3.1.4" [dev-dependencies] -criterion = "0.7.0" +# criterion = "0.7.0" [features] rmc_struct_header = [] diff --git a/test-edition.sh b/test-edition.sh new file mode 100644 index 0000000..d483592 --- /dev/null +++ b/test-edition.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +if [ -z ${EDITION+x} ]; then + EDITION=$1 +fi + +# comma seperated list of features for the specified version +source ./buildscripts/common.sh +echo FEATURES: +echo $EDITION_FEATURES + +OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo test --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl \ No newline at end of file From 08a6938d3c354eccb55f163b986c5189e31efe39 Mon Sep 17 00:00:00 2001 From: Maple Date: Thu, 13 Nov 2025 14:14:13 +0100 Subject: [PATCH 034/203] fix ci --- .ci-scripts/make-edition.sh | 0 build-edition.sh | 0 buildscripts/common.sh | 0 editions.yaml | 3 +-- test-edition.sh | 0 5 files changed, 1 insertion(+), 2 deletions(-) mode change 100644 => 100755 .ci-scripts/make-edition.sh mode change 100644 => 100755 build-edition.sh mode change 100644 => 100755 buildscripts/common.sh mode change 100644 => 100755 test-edition.sh diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh old mode 100644 new mode 100755 diff --git a/build-edition.sh b/build-edition.sh old mode 100644 new mode 100755 diff --git a/buildscripts/common.sh b/buildscripts/common.sh old mode 100644 new mode 100755 diff --git a/editions.yaml b/editions.yaml index 9ed8552..033c77e 100644 --- a/editions.yaml +++ b/editions.yaml @@ -3,8 +3,7 @@ splatoon: - rmc_struct_header settings: AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" - OTHER_ONE: "lol" friends: features: - friends - settings: {} \ No newline at end of file + settings: {} diff --git a/test-edition.sh b/test-edition.sh old mode 100644 new mode 100755 From 10dd91b1f5771b10cee2580b2c1086f81cb1b11a Mon Sep 17 00:00:00 2001 From: Maple Date: Thu, 13 Nov 2025 14:34:11 +0100 Subject: [PATCH 035/203] add edition to ci --- .ci-scripts/make-edition.sh | 16 ++++++++-------- Dockerfile | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh index 5f8694c..cb01c79 100755 --- a/.ci-scripts/make-edition.sh +++ b/.ci-scripts/make-edition.sh @@ -1,16 +1,16 @@ #!/usr/bin/env bash -export EDITION=$1 +export BA="--build-arg EDITION=$1" -podman build -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . +podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . podman push "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" -podman build -t "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" --target=node-holder . -podman build -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" --target=proxy-secure . -podman build -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" --target=proxy-insecure . -podman build -t "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" --target=backend-auth . -podman build -t "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" --target=backend-secure . +podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" --target=node-holder . +podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" --target=proxy-secure . +podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" --target=proxy-insecure . +podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" --target=backend-auth . +podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" --target=backend-secure . podman push "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" podman push "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" podman push "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" podman push "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" -podman push "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" \ No newline at end of file +podman push "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" diff --git a/Dockerfile b/Dockerfile index 87f5167..2baa33b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ WORKDIR /app COPY . . -ARG EDITION=splatoon +ARG EDITION RUN git submodule update --init --recursive From 5954ea434c09ba30790c15f0749796be15e60ce6 Mon Sep 17 00:00:00 2001 From: Maple Date: Thu, 13 Nov 2025 14:36:40 +0100 Subject: [PATCH 036/203] fix ci --- .ci-scripts/make-edition.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh index cb01c79..f595e5e 100755 --- a/.ci-scripts/make-edition.sh +++ b/.ci-scripts/make-edition.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash +export EDITION=$1 export BA="--build-arg EDITION=$1" podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . From 4d4fc6c7bfb6a71a4d02fb94ebdae4b7c4b56d3c Mon Sep 17 00:00:00 2001 From: Maple Date: Wed, 7 Jan 2026 20:33:29 +0100 Subject: [PATCH 037/203] start work on prudp v0 --- Cargo.lock | 32 +++++++++- Cargo.toml | 5 +- flake.lock | 61 +++++++++++++++++++ flake.nix | 28 +++++++++ perf.data | Bin 0 -> 1541812 bytes prudpv0/Cargo.toml | 7 +++ prudpv0/src/lib.rs | 0 prudpv1/Cargo.toml | 4 +- prudpv1/src/prudp/packet/v1/sanity_checks.rs | 12 ++++ shell.nix | 18 ++++++ 10 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 perf.data create mode 100644 prudpv0/Cargo.toml create mode 100644 prudpv0/src/lib.rs create mode 100644 prudpv1/src/prudp/packet/v1/sanity_checks.rs create mode 100644 shell.nix diff --git a/Cargo.lock b/Cargo.lock index fe55a2d..73c30a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -395,6 +395,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "macros" +version = "0.1.1" +source = "git+https://github.com/RusticMaple/VByteMacros#e2f31bded8c5591e847ba03faf79ae0351e43e69" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "md-5" version = "0.10.6" @@ -536,6 +546,13 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prudpv0" +version = "0.1.0" +dependencies = [ + "rnex-core", +] + [[package]] name = "prudpv1" version = "0.1.0" @@ -551,7 +568,7 @@ dependencies = [ "thiserror", "tokio", "typenum", - "v-byte-helpers", + "v-byte-helpers 0.1.1 (git+https://github.com/RusticMaple/VByteMacros)", ] [[package]] @@ -648,7 +665,7 @@ dependencies = [ "tokio", "typenum", "ureq", - "v-byte-helpers", + "v-byte-helpers 0.1.1 (git+https://github.com/DJMrTV/VByteMacros)", ] [[package]] @@ -958,7 +975,16 @@ version = "0.1.1" source = "git+https://github.com/DJMrTV/VByteMacros#e2f31bded8c5591e847ba03faf79ae0351e43e69" dependencies = [ "bytemuck", - "macros 0.1.1", + "macros 0.1.1 (git+https://github.com/DJMrTV/VByteMacros)", +] + +[[package]] +name = "v-byte-helpers" +version = "0.1.1" +source = "git+https://github.com/RusticMaple/VByteMacros#e2f31bded8c5591e847ba03faf79ae0351e43e69" +dependencies = [ + "bytemuck", + "macros 0.1.1 (git+https://github.com/RusticMaple/VByteMacros)", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 9c63a93..d020704 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,5 +3,6 @@ resolver = "3" members = [ "macros", "rnex-core", - "prudpv1" -] \ No newline at end of file + "prudpv1", + "prudpv0" +] diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..7826732 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1767609335, + "narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "250481aafeb741edfe23d29195671c19b36b6dca", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1767640445, + "narHash": "sha256-UWYqmD7JFBEDBHWYcqE6s6c77pWdcU/i+bwD6XxMb8A=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "9f0c42f8bc7151b8e7e5840fb3bd454ad850d8c5", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1765674936, + "narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..0863018 --- /dev/null +++ b/flake.nix @@ -0,0 +1,28 @@ +{ + description = "rust nex server"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; + }; + + outputs = + inputs@{ + self, + nixpkgs, + flake-parts, + }: + flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + perSystem = + { pkgs, lib, ... }: + rec { + devShells.default = import ./shell.nix { inherit pkgs; }; + }; + }; +} diff --git a/perf.data b/perf.data new file mode 100644 index 0000000000000000000000000000000000000000..2cf011f2aead2710a3b379f9beeaec082efbec18 GIT binary patch literal 1541812 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'@xPd1 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

j81RpU3m_-J_3) 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 YS(dmz)sJ)B|0XtXKPk2+G3N*V5A-jpKmY&$ literal 0 HcmV?d00001 diff --git a/prudpv0/Cargo.toml b/prudpv0/Cargo.toml new file mode 100644 index 0000000..439f882 --- /dev/null +++ b/prudpv0/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "prudpv0" +version = "0.1.0" +edition = "2024" + +[dependencies] +rnex-core = { path = "../rnex-core", version = "0.1.1" } diff --git a/prudpv0/src/lib.rs b/prudpv0/src/lib.rs new file mode 100644 index 0000000..e69de29 diff --git a/prudpv1/Cargo.toml b/prudpv1/Cargo.toml index bdf340e..efeaf0a 100644 --- a/prudpv1/Cargo.toml +++ b/prudpv1/Cargo.toml @@ -9,7 +9,7 @@ tokio = { version = "1.47.0", features = ["full"] } hmac = "0.12.1" md-5 = "^0.10.6" rc4 = "0.1.0" -v-byte-helpers = { git = "https://github.com/DJMrTV/VByteMacros", version = "0.1.1" } +v-byte-helpers = { git = "https://github.com/RusticMaple/VByteMacros", version = "0.1.1" } thiserror = "2.0.12" log = "0.4.27" async-trait = "0.1.88" @@ -23,4 +23,4 @@ path = "src/executables/proxy_insecure.rs" [[bin]] name = "proxy_secure" -path = "src/executables/proxy_secure.rs" \ No newline at end of file +path = "src/executables/proxy_secure.rs" diff --git a/prudpv1/src/prudp/packet/v1/sanity_checks.rs b/prudpv1/src/prudp/packet/v1/sanity_checks.rs new file mode 100644 index 0000000..335c269 --- /dev/null +++ b/prudpv1/src/prudp/packet/v1/sanity_checks.rs @@ -0,0 +1,12 @@ +//! # PRUDPV1 Feature sanity checks +//! +//! Checks wether the set features are actually sensical or wether they are +//! nonsense and throws a compiler error incase of nonsense + +#[cfg(feature = "friends")] +compile_error!( + "friends uses prudpv0 instead of prudpv1, please do not enable both at the same time" +); + +#[cfg(feature = "prudpv0")] +compile_error!("you cannot enable two prudp versions at the same time"); diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..3ac2963 --- /dev/null +++ b/shell.nix @@ -0,0 +1,18 @@ +{ + pkgs ? import { }, + pkg ? pkgs.callPackage ./. { }, +}: +pkgs.mkShell { + # Get dependencies from the main package + # inputsFrom = [ pkg ]; + # Additional tooling + buildInputs = with pkgs; [ + cargo + rust-analyzer # LSP Server + rustfmt # Formatter + clippy # Linter + podman + yq + jq + ]; +} From fc94f655b22dd83b4d0cc3aaa89d267b7b107e26 Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 20 Jan 2026 20:26:44 +0100 Subject: [PATCH 038/203] things --- .gitignore | 3 +- Cargo.lock | 60 +-- Cargo.toml | 2 +- build-edition.sh | 4 +- buildscripts/common.sh | 3 +- editions.yaml | 3 +- proxy-common/Cargo.toml | 9 + proxy-common/src/lib.rs | 209 +++++++++++ proxy/Cargo.toml | 25 ++ proxy/src/insecure.rs | 8 + proxy/src/lib.rs | 11 + proxy/src/secure.rs | 7 + prudpv0/Cargo.toml | 12 + prudpv0/src/crypto/common_crypto.rs | 54 +++ prudpv0/src/crypto/friends_common.rs | 5 + prudpv0/src/crypto/friends_insecure.rs | 52 +++ prudpv0/src/crypto/friends_secure.rs | 47 +++ prudpv0/src/crypto/insecure.rs | 9 + prudpv0/src/crypto/mod.rs | 32 ++ prudpv0/src/crypto/secure.rs | 9 + prudpv0/src/lib.rs | 62 ++++ prudpv0/src/packet.rs | 187 ++++++++++ prudpv0/src/server.rs | 256 +++++++++++++ prudpv1/src/executables/common.rs | 17 +- prudpv1/src/executables/proxy_insecure.rs | 66 ++-- prudpv1/src/prudp/packet.rs | 232 +++++------- prudpv1/src/prudp/secure.rs | 68 ++-- prudpv1/src/prudp/socket.rs | 104 +++--- prudpv1/src/prudp/unsecure.rs | 14 +- rnex-core/Cargo.toml | 4 +- .../src/executables/backend_server_secure.rs | 26 +- rnex-core/src/executables/common.rs | 48 ++- rnex-core/src/nex/auth_handler.rs | 41 +-- rnex-core/src/nex/matchmake.rs | 343 +++++++++++------- rnex-core/src/nex/user.rs | 301 +++++++++------ rnex-core/src/prudp/encryption.rs | 20 + rnex-core/src/prudp/mod.rs | 6 +- rnex-core/src/prudp/types_flags.rs | 64 ++++ rnex-core/src/prudp/virtual_port.rs | 19 +- rnex-core/src/reggie.rs | 27 +- rnex-core/src/rmc/protocols/mod.rs | 130 ++++--- rnex-core/src/rmc/structures/ranking.rs | 54 +-- test-edition.sh | 4 +- 43 files changed, 1960 insertions(+), 697 deletions(-) create mode 100644 proxy-common/Cargo.toml create mode 100644 proxy-common/src/lib.rs create mode 100644 proxy/Cargo.toml create mode 100644 proxy/src/insecure.rs create mode 100644 proxy/src/lib.rs create mode 100644 proxy/src/secure.rs create mode 100644 prudpv0/src/crypto/common_crypto.rs create mode 100644 prudpv0/src/crypto/friends_common.rs create mode 100644 prudpv0/src/crypto/friends_insecure.rs create mode 100644 prudpv0/src/crypto/friends_secure.rs create mode 100644 prudpv0/src/crypto/insecure.rs create mode 100644 prudpv0/src/crypto/mod.rs create mode 100644 prudpv0/src/crypto/secure.rs create mode 100644 prudpv0/src/packet.rs create mode 100644 prudpv0/src/server.rs create mode 100644 rnex-core/src/prudp/encryption.rs create mode 100644 rnex-core/src/prudp/types_flags.rs diff --git a/.gitignore b/.gitignore index ea0ae4a..2a7a556 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ target .idea .env log -reports \ No newline at end of file +reports +.zed diff --git a/Cargo.lock b/Cargo.lock index 73c30a5..20a8271 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,9 +134,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" @@ -385,16 +385,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "macros" -version = "0.1.1" -source = "git+https://github.com/DJMrTV/VByteMacros#e2f31bded8c5591e847ba03faf79ae0351e43e69" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "macros" version = "0.1.1" @@ -547,10 +537,39 @@ dependencies = [ ] [[package]] -name = "prudpv0" +name = "proxy" +version = "0.1.0" +dependencies = [ + "cfg-if", + "prudpv0", + "prudpv1", + "rnex-core", + "tokio", +] + +[[package]] +name = "proxy-common" version = "0.1.0" dependencies = [ "rnex-core", + "thiserror", + "tokio", +] + +[[package]] +name = "prudpv0" +version = "0.1.0" +dependencies = [ + "bytemuck", + "cfg-if", + "hmac", + "log", + "md-5", + "proxy-common", + "rc4", + "rnex-core", + "tokio", + "typenum", ] [[package]] @@ -568,7 +587,7 @@ dependencies = [ "thiserror", "tokio", "typenum", - "v-byte-helpers 0.1.1 (git+https://github.com/RusticMaple/VByteMacros)", + "v-byte-helpers", ] [[package]] @@ -665,7 +684,7 @@ dependencies = [ "tokio", "typenum", "ureq", - "v-byte-helpers 0.1.1 (git+https://github.com/DJMrTV/VByteMacros)", + "v-byte-helpers", ] [[package]] @@ -969,22 +988,13 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "v-byte-helpers" -version = "0.1.1" -source = "git+https://github.com/DJMrTV/VByteMacros#e2f31bded8c5591e847ba03faf79ae0351e43e69" -dependencies = [ - "bytemuck", - "macros 0.1.1 (git+https://github.com/DJMrTV/VByteMacros)", -] - [[package]] name = "v-byte-helpers" version = "0.1.1" source = "git+https://github.com/RusticMaple/VByteMacros#e2f31bded8c5591e847ba03faf79ae0351e43e69" dependencies = [ "bytemuck", - "macros 0.1.1 (git+https://github.com/RusticMaple/VByteMacros)", + "macros 0.1.1", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d020704..9d6ea8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,4 @@ members = [ "rnex-core", "prudpv1", "prudpv0" -] +, "proxy", "proxy-common"] diff --git a/build-edition.sh b/build-edition.sh index 7b1cfc0..5d65fc3 100755 --- a/build-edition.sh +++ b/build-edition.sh @@ -7,5 +7,7 @@ fi source ./buildscripts/common.sh echo FEATURES: echo $EDITION_FEATURES +echo ENV SETTINGS: +env -OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl \ No newline at end of file +OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl diff --git a/buildscripts/common.sh b/buildscripts/common.sh index 27fd8cd..8c5e67e 100755 --- a/buildscripts/common.sh +++ b/buildscripts/common.sh @@ -6,4 +6,5 @@ IFS=$'\n' while IFS=$'\n' read -r KEY; do VAL=$(yq ea ".$EDITION.settings.$KEY" editions.yaml) declare "$KEY=$VAL" -done <<< "$SETTINGS" \ No newline at end of file + export $KEY +done <<< "$SETTINGS" diff --git a/editions.yaml b/editions.yaml index 033c77e..f20da91 100644 --- a/editions.yaml +++ b/editions.yaml @@ -6,4 +6,5 @@ splatoon: friends: features: - friends - settings: {} + settings: + RNEX_VIRTUAL_PORT: 1:10 diff --git a/proxy-common/Cargo.toml b/proxy-common/Cargo.toml new file mode 100644 index 0000000..28974ef --- /dev/null +++ b/proxy-common/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "proxy-common" +version = "0.1.0" +edition = "2024" + +[dependencies] +thiserror = "2.0.12" +rnex-core = { path = "../rnex-core", version = "0.1.1" } +tokio = { version = "1.47.0", features = ["full"] } diff --git a/proxy-common/src/lib.rs b/proxy-common/src/lib.rs new file mode 100644 index 0000000..68ac209 --- /dev/null +++ b/proxy-common/src/lib.rs @@ -0,0 +1,209 @@ +use rnex_core::{ + executables::common::{OWN_IP_PUBLIC, try_get_ip}, + prudp::{socket_addr::PRUDPSockAddr, virtual_port::VirtualPort}, + reggie::{RemoteEdgeNodeHolder, UnitPacketWrite}, + rmc::{ + protocols::{ + OnlyRemote, RemoteDisconnectable, RmcCallable, RmcConnection, RmcPureRemoteObject, + new_rmc_gateway_connection, + }, + structures::RmcSerialize, + }, + rnex_proxy_common::ConnectionInitData, + util::{SendingBufferConnection, SplittableBufferConnection}, +}; +use std::{ + env::{self, VarError}, + error, + net::{AddrParseError, IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4}, + ops::Deref, + panic, + str::FromStr, + sync::{Arc, LazyLock}, +}; +use thiserror::Error; +use tokio::net::TcpStream; + +const RNEX_DEFAULT_PORT: u16 = match u16::from_str_radix(env!("RNEX_DEFAULT_PORT"), 10) { + Ok(v) => v, + Err(_) => panic!("unable to get default port from env"), +}; + +#[derive(Error, Debug)] +pub enum Error { + #[error("error getting environment variable \"{0}\": {1}")] + UnableToGetEnv(&'static str, VarError), + #[error("error parsing ip address environment variable \"{0}\": {1}")] + AddrParse(&'static str, AddrParseError), + #[error( + "error error getting public ip address: \n\tattempted to read from env var \"SERVER_IP_PUBLIC\" and got: {0} \n\tattempted to request from internet and failed with: {1}" + )] + PubAddrGetErr(Box, Box), +} +impl Into for (&'static str, AddrParseError) { + fn into(self) -> Error { + Error::AddrParse(self.0, self.1) + } +} + +pub struct ProxyStartupParam { + pub forward_destination: SocketAddr, + pub edge_node_holder: SocketAddr, + pub self_public: SocketAddrV4, + pub self_private: SocketAddrV4, + pub virtual_port: VirtualPort, +} + +fn try_get_env(name: &'static str) -> Result +where + (&'static str, T::Err): Into, +{ + T::from_str(&env::var(name).map_err(|e| Error::UnableToGetEnv(name, e))?) + .map_err(|e| (name, e).into()) +} + +pub enum ProxyType { + Insecure, + Secure, +} +const VIRTUAL_PORT_INSECURE: LazyLock = + LazyLock::new(|| VirtualPort::parse(env!("RNEX_VIRTUAL_PORT_INSECURE")).unwrap()); +const VIRTUAL_PORT_SECURE: LazyLock = + LazyLock::new(|| VirtualPort::parse(env!("RNEX_VIRTUAL_PORT_SECURE")).unwrap()); +impl ProxyStartupParam { + pub fn new(prox_ty: ProxyType) -> Result { + let port = RNEX_DEFAULT_PORT + + match prox_ty { + ProxyType::Insecure => 0, + ProxyType::Secure => 1, + }; + let self_private = try_get_env("SERVER_IP_PRIVATE") + .unwrap_or(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, RNEX_DEFAULT_PORT)); + let self_public: SocketAddrV4 = match try_get_env("SERVER_IP_PUBLIC") { + Ok(v) => v, + Err(e) => try_get_ip() + .map(|v| SocketAddrV4::new(v, RNEX_DEFAULT_PORT)) + .map_err(move |v| Error::PubAddrGetErr(Box::new(e), v))?, + }; + + Ok(Self { + forward_destination: try_get_env("EDGE_NODE_HOLDER")?, + edge_node_holder: try_get_env("FORWARD_DESTINATION")?, + self_private, + self_public, + virtual_port: match prox_ty { + ProxyType::Insecure => *VIRTUAL_PORT_INSECURE, + ProxyType::Secure => *VIRTUAL_PORT_SECURE, + }, + }) + } +} + +struct OnRemoteDrop(T, Option); +impl Deref for OnRemoteDrop { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +// if we had something like a thread safe OnceConsume (basically the opposite of OnceLock) +// we could make C be an FnOnce +impl + OnRemoteDrop +{ + pub fn new(conn: RmcConnection, drop_func: C) -> Self { + Self(T::new(conn), Some(drop_func)) + } + + pub async fn disconnect(&self) { + self.0.disconnect().await; + } +} + +impl RmcCallable + for OnRemoteDrop +{ + fn rmc_call( + &self, + _responder: &SendingBufferConnection, + _protocol_id: u16, + _method_id: u32, + _call_id: u32, + _rest: Vec, + ) -> impl Future + Send { + // maybe respond with not implemented or something + async {} + } +} + +impl Drop for OnRemoteDrop { + fn drop(&mut self) { + self.1.take().unwrap()(); + } +} + +pub async fn setup_edge_node_connection( + param: &ProxyStartupParam, + shutdown_callback: impl FnOnce() + Send + Sync + 'static, +) { + let conn = tokio::net::TcpStream::connect(¶m.edge_node_holder) + .await + .unwrap(); + + let conn: SplittableBufferConnection = conn.into(); + + conn.send( + rnex_core::reggie::EdgeNodeHolderConnectOption::Register(param.self_public) + .to_data() + .unwrap(), + ) + .await; + //leave the inner object floating so that it gets destroyed once we disconnect + new_rmc_gateway_connection(conn, move |r| { + Arc::new(OnRemoteDrop::::new( + r, + shutdown_callback, + )) + }); +} + +pub async fn new_backend_connection( + param: &ProxyStartupParam, + addr: PRUDPSockAddr, + pid: u32, +) -> Option { + let mut stream = match TcpStream::connect(param.forward_destination).await { + Ok(v) => v, + Err(e) => { + return None; + } + }; + + if let Err(e) = stream + .send_buffer( + &ConnectionInitData { + prudpsock_addr: addr, + pid: pid, + } + .to_data() + .unwrap(), + ) + .await + { + return None; + }; + + Some(stream.into()) +} + +#[cfg(test)] +mod test { + use crate::{VIRTUAL_PORT_INSECURE, VIRTUAL_PORT_SECURE}; + + fn test_virtual_port_correct() { + println!("{:?}", VIRTUAL_PORT_INSECURE); + println!("{:?}", VIRTUAL_PORT_SECURE); + } +} diff --git a/proxy/Cargo.toml b/proxy/Cargo.toml new file mode 100644 index 0000000..78e7438 --- /dev/null +++ b/proxy/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "proxy" +version = "0.1.0" +edition = "2024" + +[dependencies] +tokio = { version = "1.47.0", features = ["full"] } +prudpv0 = { path = "../prudpv0", optional = true } +prudpv1 = { path = "../prudpv1", optional = true } +cfg-if = "1.0.4" +rnex-core = { path = "../rnex-core", version = "0.1.1" } + +[features] +prudpv0 = ["dep:prudpv0"] +prudpv1 = ["dep:prudpv1"] +friends = ["prudpv0", "prudpv0/friends"] + + +[[bin]] +name = "proxy_insecure" +path = "src/insecure.rs" + +[[bin]] +name = "proxy_secure" +path = "src/secure.rs" diff --git a/proxy/src/insecure.rs b/proxy/src/insecure.rs new file mode 100644 index 0000000..1fe927f --- /dev/null +++ b/proxy/src/insecure.rs @@ -0,0 +1,8 @@ +use rnex_core::common::setup; + +#[tokio::main] +async fn main() { + setup(); + + proxy::start_insecure(ProxyStartupParam::new()).await; +} diff --git a/proxy/src/lib.rs b/proxy/src/lib.rs new file mode 100644 index 0000000..7120adc --- /dev/null +++ b/proxy/src/lib.rs @@ -0,0 +1,11 @@ +use cfg_if::cfg_if; + +cfg_if! { + if #[cfg(feature = "prudpv0")]{ + pub use prudpv0::*; + } else if #[cfg(feature = "prudpv1")] { + pub use prudpv1::*; + } else { + compile_error!("no proxy type has been set"); + } +} diff --git a/proxy/src/secure.rs b/proxy/src/secure.rs new file mode 100644 index 0000000..d661d95 --- /dev/null +++ b/proxy/src/secure.rs @@ -0,0 +1,7 @@ +use rnex_core::common::setup; + +#[tokio::main] +async fn main() { + setup(); + proxy::start_secure(ProxyStartupParam::new()).await; +} diff --git a/prudpv0/Cargo.toml b/prudpv0/Cargo.toml index 439f882..dbdb1db 100644 --- a/prudpv0/Cargo.toml +++ b/prudpv0/Cargo.toml @@ -5,3 +5,15 @@ edition = "2024" [dependencies] rnex-core = { path = "../rnex-core", version = "0.1.1" } +tokio = { version = "1.47.0", features = ["full"] } +bytemuck = { version = "1.23.1", features = ["derive"] } +typenum = "1.18.0" +rc4 = "0.1.0" +log = "0.4.25" +cfg-if = "1.0.4" +proxy-common = {path = "../proxy-common"} +hmac = "0.12.1" +md-5 = "^0.10.6" + +[features] +friends = [] diff --git a/prudpv0/src/crypto/common_crypto.rs b/prudpv0/src/crypto/common_crypto.rs new file mode 100644 index 0000000..7196638 --- /dev/null +++ b/prudpv0/src/crypto/common_crypto.rs @@ -0,0 +1,54 @@ +trait IterExtra: Iterator { + fn sum_wrapping_u8(&mut self) -> u8 + where + Self::Item: Into; + + fn sum_wrapping_u32(&mut self) -> u32 + where + Self::Item: Into; +} + +impl IterExtra for T { + fn sum_wrapping_u8(&mut self) -> u8 + where + Self::Item: Into, + { + let mut sum = 0u8; + for v in self { + let val: u8 = v.into(); + sum = sum.wrapping_add(val); + } + sum + } + fn sum_wrapping_u32(&mut self) -> u32 + where + Self::Item: Into, + { + let mut sum = 0u32; + for v in self { + let val: u32 = v.into(); + sum = sum.wrapping_add(val); + } + sum + } +} + +#[inline(always)] +pub fn common_checksum(access_key: &str, data: &[u8]) -> u8 { + let leftover = data.len() % 4; + let word_sum = bytemuck::cast_slice::<_, u32>(&data[..data.len() - leftover]) + .iter() + .copied() + .sum_wrapping_u32(); + + let checksum = access_key.as_bytes().iter().copied().sum_wrapping_u8(); + let checksum = checksum.wrapping_add( + (&data[data.len() - leftover..]) + .iter() + .copied() + .sum_wrapping_u8(), + ); + let checksum = checksum.wrapping_add(word_sum.to_ne_bytes().into_iter().sum_wrapping_u8()); + + checksum +} diff --git a/prudpv0/src/crypto/friends_common.rs b/prudpv0/src/crypto/friends_common.rs new file mode 100644 index 0000000..b11af1d --- /dev/null +++ b/prudpv0/src/crypto/friends_common.rs @@ -0,0 +1,5 @@ +use hmac::Hmac; +use md5::Md5; + +pub const ACCESS_KEY: &str = "ridfebb9"; +pub type HmacMd5 = Hmac; diff --git a/prudpv0/src/crypto/friends_insecure.rs b/prudpv0/src/crypto/friends_insecure.rs new file mode 100644 index 0000000..b3ff9ab --- /dev/null +++ b/prudpv0/src/crypto/friends_insecure.rs @@ -0,0 +1,52 @@ +use std::rc::Rc; + +use hmac::Mac; +use rc4::{KeyInit, Rc4, StreamCipher}; +use rnex_core::prudp::encryption::{DEFAULT_KEY, EncryptionPair}; +use typenum::U5; + +use crate::crypto::{ + Crypto, CryptoInstance, + common_crypto::common_checksum, + friends_common::{ACCESS_KEY, HmacMd5}, +}; + +pub struct InsecureInstance { + pair: EncryptionPair>, +} + +impl CryptoInstance for InsecureInstance { + fn decrypt_incoming(&mut self, data: &mut [u8]) { + self.pair.recv.apply_keystream(data); + } + fn encrypt_outgoing(&mut self, data: &mut [u8]) { + self.pair.send.apply_keystream(data); + } + fn get_user_id(&self) -> u32 { + 0 + } + fn generate_signature(&self, data: &[u8]) -> [u8; 4] { + let mut hmac = ::new_from_slice(ACCESS_KEY.as_bytes()) + .expect("unable to create hmac md5"); + hmac.update(data); + hmac.finalize().into_bytes()[0..4].try_into().unwrap() + } +} + +pub struct Insecure(); + +impl Crypto for Insecure { + type Instance = InsecureInstance; + fn new() -> Self { + Self() + } + fn calculate_checksum(&self, data: &[u8]) -> u8 { + common_checksum(ACCESS_KEY, data) + } + + fn instantiate(&self, packet_data: &[u8]) -> Self::Instance { + InsecureInstance { + pair: EncryptionPair::init_both(|| Rc4::new(&DEFAULT_KEY)), + } + } +} diff --git a/prudpv0/src/crypto/friends_secure.rs b/prudpv0/src/crypto/friends_secure.rs new file mode 100644 index 0000000..db36c46 --- /dev/null +++ b/prudpv0/src/crypto/friends_secure.rs @@ -0,0 +1,47 @@ +use hmac::Mac; +use rc4::Rc4; +use rnex_core::prudp::encryption::EncryptionPair; +use typenum::U32; + +use crate::crypto::{ + Crypto, CryptoInstance, + common_crypto::common_checksum, + friends_common::{ACCESS_KEY, HmacMd5}, +}; + +pub struct SecureInstance { + pair: EncryptionPair>, +} + +impl CryptoInstance for SecureInstance { + fn decrypt_incoming(&mut self, data: &mut [u8]) { + todo!() + } + fn encrypt_outgoing(&mut self, data: &mut [u8]) { + todo!() + } + fn get_user_id(&self) -> u32 { + todo!() + } + fn generate_signature(&self, data: &[u8]) -> [u8; 4] { + let mut hmac = ::new_from_slice(ACCESS_KEY.as_bytes()) + .expect("unable to create hmac md5"); + hmac.update(data); + hmac.finalize().into_bytes()[0..4].try_into().unwrap() + } +} + +pub struct Secure(); + +impl Crypto for Secure { + type Instance = SecureInstance; + fn new() -> Self { + Self() + } + fn calculate_checksum(&self, data: &[u8]) -> u8 { + common_checksum(ACCESS_KEY, data) + } + fn instantiate(&self, data: &[u8]) -> Self::Instance { + todo!() + } +} diff --git a/prudpv0/src/crypto/insecure.rs b/prudpv0/src/crypto/insecure.rs new file mode 100644 index 0000000..5d3dff3 --- /dev/null +++ b/prudpv0/src/crypto/insecure.rs @@ -0,0 +1,9 @@ +use crate::crypto::Crypto; + +pub struct Insecure(); + +impl Crypto for Insecure { + fn calculate_checksum(&self, data: &[u8]) -> u8 { + todo!() + } +} diff --git a/prudpv0/src/crypto/mod.rs b/prudpv0/src/crypto/mod.rs new file mode 100644 index 0000000..add58b9 --- /dev/null +++ b/prudpv0/src/crypto/mod.rs @@ -0,0 +1,32 @@ +use cfg_if::cfg_if; + +mod common_crypto; + +pub trait CryptoInstance: Send + 'static { + fn decrypt_incoming(&mut self, data: &mut [u8]); + fn encrypt_outgoing(&mut self, data: &mut [u8]); + fn generate_signature(&self, data: &[u8]) -> [u8; 4]; + fn get_user_id(&self) -> u32; +} + +pub trait Crypto: Send + Sync + 'static { + type Instance: CryptoInstance; + fn new() -> Self; + fn calculate_checksum(&self, data: &[u8]) -> u8; + fn instantiate(&self, data: &[u8]) -> Self::Instance; +} + +cfg_if! { + if #[cfg(feature = "friends")]{ + pub mod friends_common; + pub mod friends_insecure; + pub use friends_insecure::*; + pub mod friends_secure; + pub use friends_secure::*; + } else { + pub mod secure; + pub use secure::*; + pub mod insecure; + pub use insecure::*; + } +} diff --git a/prudpv0/src/crypto/secure.rs b/prudpv0/src/crypto/secure.rs new file mode 100644 index 0000000..435986e --- /dev/null +++ b/prudpv0/src/crypto/secure.rs @@ -0,0 +1,9 @@ +use crate::crypto::Crypto; + +pub struct Secure(); + +impl Crypto for Secure { + fn calculate_checksum(&self, data: &[u8]) -> u8 { + todo!() + } +} diff --git a/prudpv0/src/lib.rs b/prudpv0/src/lib.rs index e69de29..6ba8216 100644 --- a/prudpv0/src/lib.rs +++ b/prudpv0/src/lib.rs @@ -0,0 +1,62 @@ +use bytemuck::{Pod, Zeroable}; +use log::{error, info, warn}; +use proxy_common::{ProxyStartupParam, setup_edge_node_connection}; +use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT}; +use rnex_core::prudp::types_flags::TypesFlags; +use rnex_core::prudp::types_flags::types::SYN; +use rnex_core::prudp::virtual_port::VirtualPort; +use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; +use rnex_core::reggie::RemoteEdgeNodeHolder; +use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; +use rnex_core::rmc::structures::RmcSerialize; +use rnex_core::util::SplittableBufferConnection; +use std::env; +use std::net::SocketAddrV4; +use std::process::abort; +use std::sync::{Arc, LazyLock}; +use tokio::net::UdpSocket; + +use crate::crypto::{Crypto, Insecure, Secure}; +use crate::packet::PRUDPV0Packet; +use crate::server::Server; + +mod crypto; +mod packet; +mod server; + +pub static EDGE_NODE_HOLDER: LazyLock = LazyLock::new(|| { + env::var("EDGE_NODE_HOLDER") + .ok() + .and_then(|s| s.parse().ok()) + .expect("EDGE_NODE_HOLDER not set") +}); + +pub static FORWARD_DESTINATION: LazyLock = LazyLock::new(|| { + env::var("FORWARD_DESTINATION") + .ok() + .and_then(|s| s.parse().ok()) + .expect("FORWARD_DESTINATION not set") +}); +//same as with prudpv1 this is responsible for handeling the different cryptography +//implementations, e.g. secure and insecure(this also includes special cases like friends) + +async fn start_proxy(param: ProxyStartupParam) { + setup_edge_node_connection(¶m, || abort()); + + info!("creating cryptography instance"); + let mut crypto = Arc::new(T::new()); + info!("binding to socket"); + + let server: Arc> = Arc::new(Server::new().await); + + info!("waiting on packets"); + server.run_task().await; +} + +pub async fn start_secure(param: ProxyStartupParam) { + start_proxy::(param).await; +} + +pub async fn start_insecure(param: ProxyStartupParam) { + start_proxy::(param).await; +} diff --git a/prudpv0/src/packet.rs b/prudpv0/src/packet.rs new file mode 100644 index 0000000..3d6d06a --- /dev/null +++ b/prudpv0/src/packet.rs @@ -0,0 +1,187 @@ +use std::mem::transmute; + +use bytemuck::{Pod, Zeroable, try_from_bytes, try_from_bytes_mut}; +use log::error; +use rnex_core::prudp::{ + types_flags::{ + TypesFlags, + flags::{HAS_SIZE, NEED_ACK}, + types::{CONNECT, DATA, SYN}, + }, + virtual_port::VirtualPort, +}; + +use crate::crypto::{Crypto, CryptoInstance}; + +#[repr(C, packed)] +#[derive(Clone, Copy, Pod, Zeroable, Debug)] +pub struct PRUDPV0Header { + pub source: VirtualPort, + pub destination: VirtualPort, + pub type_flags: TypesFlags, + pub session_id: u8, + pub packet_signature: [u8; 4], + pub sequence_id: u16, +} +#[repr(transparent)] +pub struct PRUDPV0Packet>(pub T); + +impl> PRUDPV0Packet { + #[inline(always)] + pub fn get_packet_specific_size(&self) -> Option { + Some(get_types_flags_size_from_types_flags( + self.header()?.type_flags, + )) + } + + #[inline(always)] + pub fn header(&self) -> Option<&PRUDPV0Header> { + try_from_bytes(self.0.as_ref().get(..size_of::())?).ok() + } + #[inline(always)] + pub fn header_mut(&mut self) -> Option<&mut PRUDPV0Header> + where + T: AsMut<[u8]>, + { + try_from_bytes_mut(self.0.as_mut().get_mut(..size_of::())?).ok() + } + + #[inline(always)] + pub fn connection_signature(&self) -> Option<&[u8; 4]> { + let offset = size_of::(); + Some(self.0.as_ref().get(offset..offset + 4)?.try_into().ok()?) + } + #[inline(always)] + pub fn connection_signature_mut(&mut self) -> Option<&mut [u8; 4]> + where + T: AsMut<[u8]>, + { + let offset = size_of::(); + Some( + self.0 + .as_mut() + .get_mut(offset..offset + 4)? + .try_into() + .ok()?, + ) + } + + #[inline(always)] + fn get_payload_offset(&self) -> Option { + Some(size_of::() + self.get_packet_specific_size()?) + } + + #[inline(always)] + pub fn payload(&self) -> Option<&[u8]> { + self.0 + .as_ref() + .get(self.get_payload_offset()?..(self.0.as_ref().len().saturating_sub(1))) + } + #[inline(always)] + pub fn payload_mut(&mut self) -> Option<&mut [u8]> + where + T: AsMut<[u8]>, + { + let start_offset = self.get_payload_offset()?; + let end_offset = self.0.as_ref().len().saturating_sub(1); + self.0.as_mut().get_mut(start_offset..end_offset) + } + + #[inline(always)] + pub fn checksummed_data(&self) -> Option<&[u8]> { + self.0 + .as_ref() + .get(..self.0.as_ref().len().saturating_sub(1)) + } + + #[inline(always)] + pub fn checksum(&self) -> Option { + self.0.as_ref().last().copied() + } + #[inline(always)] + pub fn checksum_mut(&mut self) -> Option<&mut u8> + where + T: AsMut<[u8]>, + { + self.0.as_mut().last_mut() + } + + #[inline(always)] + pub fn check_checksum(&self, crypto: &impl Crypto) -> bool { + let Some(data) = self.checksummed_data() else { + return false; + }; + let Some(checksum) = self.checksum() else { + return false; + }; + checksum == crypto.calculate_checksum(data) + } + + pub fn new(data: T) -> Self { + Self(data) + } +} + +const DEFAULT_SIGNAT: [u8; 4] = [0x12, 0x34, 0x56, 0x78]; +#[inline(always)] +const fn get_size_offset(tf: TypesFlags) -> usize { + size_of::() + + (if tf.get_types() & (SYN | CONNECT) != 0 { + 4 + } else if tf.get_types() & DATA != 0 { + 1 + } else { + 0 + }) +} +#[inline(always)] +const fn get_type_specific_size(tf: TypesFlags) -> usize { + if tf.get_types() & (SYN | CONNECT) != 0 { + 4 + } else if tf.get_types() & DATA != 0 { + 1 + } else { + 0 + } +} +#[inline(always)] +const fn get_types_flags_size_from_types_flags(tf: TypesFlags) -> usize { + get_type_specific_size(tf) + (if tf.get_flags() & HAS_SIZE != 0 { 2 } else { 0 }) +} +#[inline(always)] +pub const fn precalc_size(tf: TypesFlags, payload_size: usize) -> usize { + size_of::() + get_types_flags_size_from_types_flags(tf) + payload_size + 1 +} +pub fn new_syn_packet( + flags: u16, + source: VirtualPort, + destination: VirtualPort, + signat: [u8; 4], + crypto: &impl Crypto, +) -> Vec { + let type_flags = TypesFlags::default().types(SYN).flags(flags); + + let vec = vec![0; precalc_size(type_flags, 0)]; + let mut packet = PRUDPV0Packet::new(vec); + let header = packet.header_mut().expect("packet malformed in creation"); + + *header = PRUDPV0Header { + destination, + source, + packet_signature: DEFAULT_SIGNAT, + sequence_id: 0, + session_id: 0, + type_flags, + }; + *packet + .connection_signature_mut() + .expect("packet malformed in creation") = signat; + + *packet.checksum_mut().expect("packet malformed in creation") = crypto.calculate_checksum( + packet + .checksummed_data() + .expect("packet malformed in creation"), + ); + + packet.0 +} diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs new file mode 100644 index 0000000..e3b8bbf --- /dev/null +++ b/prudpv0/src/server.rs @@ -0,0 +1,256 @@ +use std::{ + collections::HashMap, + hash::Hash, + net::{Ipv4Addr, SocketAddr, SocketAddrV4}, + sync::{ + Arc, LazyLock, + atomic::{AtomicBool, AtomicU32}, + }, +}; + +use log::{error, info, warn}; +use proxy_common::{ProxyStartupParam, new_backend_connection}; +use rnex_core::{ + executables::common::{OWN_IP_PRIVATE, SERVER_PORT}, + prudp::{ + socket_addr::PRUDPSockAddr, + types_flags::{ + TypesFlags, + flags::{ACK, HAS_SIZE, NEED_ACK}, + types::{CONNECT, DATA, SYN}, + }, + virtual_port::VirtualPort, + }, + rnex_proxy_common::ConnectionInitData, + util::{SendingBufferConnection, SplittableBufferConnection}, +}; +use tokio::{ + net::{TcpSocket, UdpSocket}, + spawn, + sync::{Mutex, RwLock}, + time::Instant, +}; + +use crate::{ + crypto::{Crypto, CryptoInstance}, + packet::{PRUDPV0Header, PRUDPV0Packet, new_syn_packet, precalc_size}, +}; + +pub struct InternalConnection { + last_action: Instant, + crypto_instance: C, + server_packet_counter: u16, + client_packet_counter: u16, + unacknowledged_packets: HashMap>>, +} +pub struct Connection { + alive: AtomicBool, + session_id: u8, + target: SendingBufferConnection, + self_signat: [u8; 4], + remote_signat: [u8; 4], + addr: PRUDPSockAddr, + inner: Mutex>, +} + +impl InternalConnection { + fn next_server_count(&mut self) -> u16 { + let prev_val = self.server_packet_counter; + let (val, _) = self.server_packet_counter.overflowing_add(1); + self.server_packet_counter = val; + + prev_val + } +} + +pub struct Server { + param: ProxyStartupParam, + socket: UdpSocket, + crypto: C, + connections: RwLock>>>, +} + +impl Server { + async fn send_data_packet(&self, conn: &Connection, data: &[u8]) { + let type_flags = TypesFlags::default().types(DATA).flags(HAS_SIZE | NEED_ACK); + let vec = vec![0; precalc_size(type_flags, data.len())]; + let mut packet = PRUDPV0Packet::new(vec); + + let payload = packet.payload_mut().expect("packet malformed in creation"); + payload.copy_from_slice(data); + + let mut inner = conn.inner.lock().await; + inner.crypto_instance.encrypt_outgoing(payload); + let packet_signat = inner.crypto_instance.generate_signature(payload); + let seq = inner.next_server_count(); + + *packet.header_mut().expect("packet malformed in creation") = PRUDPV0Header { + source: self.param.virtual_port, + destination: conn.addr.virtual_port, + type_flags, + session_id: conn.session_id, + packet_signature: packet_signat, + sequence_id: seq, + }; + /* we leave the sequence id as is for now as it defaults to 0 */ + + *packet.checksum_mut().expect("packet malformed in creation") = + self.crypto.calculate_checksum( + packet + .checksummed_data() + .expect("packet malformed in creation"), + ); + + let packet_raw = packet.0; + + let packet = Arc::new(packet_raw); + + let packet_ref = Arc::downgrade(&packet); + + inner.unacknowledged_packets.insert(seq, packet); + + drop(inner); + + spawn(async move { + for n in 0..5 { + let Some(data) = packet_ref.upgrade() else { + return; + }; + info!("send attempt {}", n); + } + }); + } + async fn connection_thread( + self: Arc, + conn: Arc>, + mut recv: SplittableBufferConnection, + ) { + while let Some(data) = recv.recv().await {} + } + async fn timeout_thread(self: Arc, conn: Arc>) { + loop { + conn + } + } + async fn handle_syn(self: Arc, packet: PRUDPV0Packet<&[u8]>, addr: PRUDPSockAddr) { + info!("got syn"); + let header = packet.header().unwrap(); + + let signat = addr.calculate_connection_signature(); + let signat = [signat[0], signat[1], signat[2], signat[3]]; + + let packet = new_syn_packet(ACK, header.destination, header.source, signat, &self.crypto); + self.socket.send_to(&packet, addr.regular_socket_addr).await; + } + async fn handle_connect(self: Arc, packet: PRUDPV0Packet<&[u8]>, addr: PRUDPSockAddr) { + let conn = self.connections.write().await; + let Some(data) = packet.payload() else { + warn!("malformed packet from: {:?}", addr.regular_socket_addr); + return; + }; + let Some(self_signat) = packet.connection_signature().copied() else { + warn!( + "malformed packet(unable to find connection signature) from: {:?}", + addr + ); + return; + }; + + let ci = self.crypto.instantiate(data); + + let pid = ci.get_user_id(); + let conn = new_backend_connection(&self.param, addr, pid).await; + let Some(conn) = conn else { + error!("unable to connect to backend"); + return; + }; + + let remote_signat = addr.calculate_connection_signature(); + let remote_signat = [ + remote_signat[0], + remote_signat[1], + remote_signat[2], + remote_signat[3], + ]; + + let header = packet.header().expect("header should be validated by now"); + + let conn = Arc::new(Connection { + target: conn.duplicate_sender(), + remote_signat, + self_signat, + addr, + session_id: header.session_id, + alive: AtomicBool::new(true), + inner: Mutex::new(InternalConnection { + last_action: Instant::now(), + crypto_instance: ci, + client_packet_counter: 2, + server_packet_counter: 1, + unacknowledged_packets: HashMap::new(), + }), + }); + } + async fn process_packet<'a>(self: Arc, packet: PRUDPV0Packet<&[u8]>, addr: SocketAddrV4) { + if !packet.check_checksum(&self.crypto) { + warn!("invalid checksum from: {}", addr); + return; + } + + let Some(header) = packet.header() else { + warn!("malformatted packet from: {}", addr); + return; + }; + + let addr = PRUDPSockAddr::new(addr, header.source); + println!("{:?}", header); + match header.type_flags.get_types() { + SYN => { + self.handle_syn(packet, addr).await; + } + CONNECT => { + self.handle_connect(packet, addr).await; + } + v => { + println!("unimplemented packed type: {}", v); + } + } + } + pub async fn run_task(self: Arc) { + loop { + let mut vec: Vec = vec![]; + let addr = match self.socket.recv_buf_from(&mut vec).await { + Err(e) => { + error!("unable to recv: {}", e); + break; + } + Ok(v) => { + assert_eq!(vec.len(), v.0); + v.1 + } + }; + let this = self.clone(); + tokio::spawn(async move { + let data = vec; + let packet = PRUDPV0Packet::new(&data[..]); + + let SocketAddr::V4(addr) = addr else { + unreachable!() + }; + + this.process_packet(packet, addr).await; + }); + } + } + pub async fn new(param: ProxyStartupParam) -> Self { + let socket = UdpSocket::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) + .await + .expect("unable to bind socket"); + Self { + socket, + crypto: C::new(), + connections: RwLock::new(HashMap::new()), + param, + } + } +} diff --git a/prudpv1/src/executables/common.rs b/prudpv1/src/executables/common.rs index e8162a1..8d6f4c1 100644 --- a/prudpv1/src/executables/common.rs +++ b/prudpv1/src/executables/common.rs @@ -1,18 +1,17 @@ +use once_cell::sync::Lazy; use std::env; use std::net::SocketAddrV4; -use once_cell::sync::Lazy; -pub static EDGE_NODE_HOLDER: Lazy = Lazy::new(||{ +pub static EDGE_NODE_HOLDER: Lazy = Lazy::new(|| { env::var("EDGE_NODE_HOLDER") .ok() .and_then(|s| s.parse().ok()) .expect("EDGE_NODE_HOLDER not set") }); -pub static FORWARD_DESTINATION: Lazy = - Lazy::new(|| - env::var("FORWARD_DESTINATION") - .ok() - .and_then(|s| s.parse().ok()) - .expect("FORWARD_DESTINATION not set") - ); +pub static FORWARD_DESTINATION: Lazy = Lazy::new(|| { + env::var("FORWARD_DESTINATION") + .ok() + .and_then(|s| s.parse().ok()) + .expect("FORWARD_DESTINATION not set") +}); diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index 50446d5..350018d 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -1,15 +1,5 @@ - -use rnex_core::reggie::UnitPacketRead; -use rnex_core::reggie::UnitPacketWrite; -use rnex_core::rmc::structures::RmcSerialize; -use std::net::SocketAddrV4; -use std::sync::Arc; -use std::time::Duration; use log::error; -use tokio::net::TcpStream; -use tokio::task; -use tokio::time::sleep; -use prudpv1::executables::common::{FORWARD_DESTINATION, EDGE_NODE_HOLDER}; +use prudpv1::executables::common::{EDGE_NODE_HOLDER, FORWARD_DESTINATION}; use prudpv1::prudp::router::Router; use prudpv1::prudp::unsecure::Unsecure; use rnex_core::common::setup; @@ -17,32 +7,46 @@ use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT} use rnex_core::prudp::virtual_port::VirtualPort; use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; use rnex_core::reggie::RemoteEdgeNodeHolder; -use rnex_core::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; +use rnex_core::reggie::UnitPacketRead; +use rnex_core::reggie::UnitPacketWrite; +use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; +use rnex_core::rmc::structures::RmcSerialize; use rnex_core::rnex_proxy_common::ConnectionInitData; use rnex_core::util::SplittableBufferConnection; - - +use std::net::SocketAddrV4; +use std::sync::Arc; +use std::time::Duration; +use tokio::net::TcpStream; +use tokio::task; +use tokio::time::sleep; #[tokio::main] async fn main() { setup(); - let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER).await.unwrap(); + let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER) + .await + .unwrap(); let conn: SplittableBufferConnection = conn.into(); - conn.send(Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)).to_data().unwrap()).await; + conn.send( + Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)) + .to_data() + .unwrap(), + ) + .await; - let conn = new_rmc_gateway_connection(conn, |r| Arc::new(OnlyRemote::::new(r))); + let conn = new_rmc_gateway_connection(conn, |r| { + Arc::new(OnlyRemote::::new(r)) + }); let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) .await .expect("unable to start router"); let mut socket_secure = router_secure - .add_socket(VirtualPort::new(1, 10), Unsecure( - "6f599f81" - )) + .add_socket(VirtualPort::new(1, 10), Unsecure("6f599f81")) .await .expect("unable to add socket"); @@ -55,8 +59,7 @@ async fn main() { }; task::spawn(async move { - let mut stream - = match TcpStream::connect(*FORWARD_DESTINATION).await { + let mut stream = match TcpStream::connect(*FORWARD_DESTINATION).await { Ok(v) => v, Err(e) => { error!("unable to connect: {}", e); @@ -64,10 +67,17 @@ async fn main() { } }; - if let Err(e) = stream.send_buffer(&ConnectionInitData{ - prudpsock_addr: conn.socket_addr, - pid: conn.user_id - }.to_data().unwrap()).await{ + if let Err(e) = stream + .send_buffer( + &ConnectionInitData { + prudpsock_addr: conn.socket_addr, + pid: conn.user_id, + } + .to_data() + .unwrap(), + ) + .await + { error!("error connecting to backend: {}", e); return; }; @@ -92,7 +102,7 @@ async fn main() { return; } }; - + if conn.send(data).await == None{ return; } @@ -105,4 +115,4 @@ async fn main() { }); } drop(conn); -} \ No newline at end of file +} diff --git a/prudpv1/src/prudp/packet.rs b/prudpv1/src/prudp/packet.rs index da376bd..a4d87e9 100644 --- a/prudpv1/src/prudp/packet.rs +++ b/prudpv1/src/prudp/packet.rs @@ -3,21 +3,24 @@ // force the compiler to shut up here #![allow(unused_parens)] +use crate::prudp::packet::PacketOption::{ + ConnectionSignature, FragmentId, InitialSequenceId, MaximumSubstreamId, SupportedFunctions, +}; +use bytemuck::{Pod, Zeroable}; +use hmac::{Hmac, Mac}; +use log::{error, warn}; +use md5::{Digest, Md5}; +use rnex_core::prudp::socket_addr::PRUDPSockAddr; +use rnex_core::prudp::types_flags::TypesFlags; +use rnex_core::prudp::types_flags::flags::ACK; +use rnex_core::prudp::virtual_port::VirtualPort; use std::fmt::{Debug, Formatter}; use std::io; use std::io::{Cursor, Read, Seek, Write}; use std::net::SocketAddrV4; -use bytemuck::{Pod, Zeroable}; -use hmac::{Hmac, Mac}; -use log::{error, warn}; -use md5::{Md5, Digest}; use thiserror::Error; -use v_byte_helpers::{SwapEndian}; +use v_byte_helpers::SwapEndian; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -use crate::prudp::packet::flags::ACK; -use crate::prudp::packet::PacketOption::{ConnectionSignature, FragmentId, InitialSequenceId, MaximumSubstreamId, SupportedFunctions}; -use rnex_core::prudp::socket_addr::PRUDPSockAddr; -use rnex_core::prudp::virtual_port::VirtualPort; type Md5Hmac = Hmac; @@ -32,73 +35,11 @@ pub enum Error { #[error("invalid option id {0}")] InvalidOptionId(u8), #[error("option size {size} doesnt match expected option for given option id {id}")] - InvalidOptionSize { - id: u8, - size: u8, - }, + InvalidOptionSize { id: u8, size: u8 }, } pub type Result = std::result::Result; -#[repr(transparent)] -#[derive(Copy, Clone, Pod, Zeroable, SwapEndian, Default, Eq, PartialEq)] -pub struct TypesFlags(u16); - -impl TypesFlags { - #[inline] - pub const fn get_types(self) -> u8 { - (self.0 & 0x000F) as u8 - } - #[inline] - pub const fn get_flags(self) -> u16 { - (self.0 & 0xFFF0) >> 4 - } - #[inline] - pub const fn types(self, val: u8) -> Self { - Self((self.0 & 0xFFF0) | (val as u16 & 0x000F)) - } - #[inline] - pub const fn flags(self, val: u16) -> Self { - Self((self.0 & 0x000F) | ((val << 4) & 0xFFF0)) - } - #[inline] - pub const fn set_flag(&mut self, val: u16){ - self.0 |= (val & 0xFFF) << 4; - } - #[inline] - pub const fn set_types(&mut self, val: u8){ - self.0 |= val as u16 & 0x0F; - } -} - -pub mod flags { - pub const ACK: u16 = 0x001; - pub const RELIABLE: u16 = 0x002; - pub const NEED_ACK: u16 = 0x004; - pub const HAS_SIZE: u16 = 0x008; - pub const MULTI_ACK: u16 = 0x200; -} - -pub mod types { - pub const SYN: u8 = 0x0; - pub const CONNECT: u8 = 0x1; - pub const DATA: u8 = 0x2; - pub const DISCONNECT: u8 = 0x3; - pub const PING: u8 = 0x4; - /// no idea what user is supposed to mean - pub const USER: u8 = 0x5; -} - -impl Debug for TypesFlags { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let stream_type = self.get_types(); - let port_number = self.get_flags(); - write!(f, "TypesFlags{{ types: {}, flags: {} }}", stream_type, port_number) - } -} - - - #[repr(C)] #[derive(Debug, Copy, Clone, Pod, Zeroable, SwapEndian, Eq, PartialEq)] pub struct PRUDPV1Header { @@ -116,7 +57,7 @@ pub struct PRUDPV1Header { impl Default for PRUDPV1Header { fn default() -> Self { - Self{ + Self { magic: [0xEA, 0xD0], version: 1, session_id: 0, @@ -126,32 +67,30 @@ impl Default for PRUDPV1Header { destination_port: VirtualPort(0), types_and_flags: TypesFlags(0), packet_specific_size: 0, - substream_id: 0 + substream_id: 0, } } } - #[derive(Debug, Clone, Eq, PartialEq)] -pub enum PacketOption{ +pub enum PacketOption { SupportedFunctions(u32), ConnectionSignature([u8; 16]), FragmentId(u8), InitialSequenceId(u16), - MaximumSubstreamId(u8) + MaximumSubstreamId(u8), } -impl PacketOption{ - fn from(option_id: OptionId, option_data: &[u8]) -> io::Result{ - +impl PacketOption { + fn from(option_id: OptionId, option_data: &[u8]) -> io::Result { let mut data_cursor = Cursor::new(option_data); - let val = match option_id.into(){ + let val = match option_id.into() { 0 => SupportedFunctions(data_cursor.read_struct(IS_BIG_ENDIAN)?), 1 => ConnectionSignature(data_cursor.read_struct(IS_BIG_ENDIAN)?), 2 => FragmentId(data_cursor.read_struct(IS_BIG_ENDIAN)?), 3 => InitialSequenceId(data_cursor.read_struct(IS_BIG_ENDIAN)?), 4 => MaximumSubstreamId(data_cursor.read_struct(IS_BIG_ENDIAN)?), - _ => unreachable!() + _ => unreachable!(), }; Ok(val) @@ -212,7 +151,7 @@ impl OptionId { // Invariant is upheld because we only create the object if it doesn't violate the invariant match val { 0 | 1 | 2 | 3 | 4 => Ok(Self(val)), - _ => Err(Error::InvalidOptionId(val)) + _ => Err(Error::InvalidOptionId(val)), } } @@ -223,7 +162,7 @@ impl OptionId { 2 => 1, 3 => 2, 4 => 1, - _ => unreachable!() + _ => unreachable!(), } } } @@ -238,8 +177,7 @@ impl PRUDPV1Packet { pub fn new(reader: &mut (impl Read + Seek)) -> Result { let header: PRUDPV1Header = reader.read_struct(IS_BIG_ENDIAN)?; - if header.magic[0] != 0xEA || - header.magic[1] != 0xD0 { + if header.magic[0] != 0xEA || header.magic[1] != 0xD0 { return Err(Error::InvalidMagic(u16::from_be_bytes(header.magic))); } @@ -247,31 +185,31 @@ impl PRUDPV1Packet { return Err(Error::InvalidVersion(header.version)); } - let packet_signature: [u8; 16] = reader.read_struct(IS_BIG_ENDIAN)?; //let packet_signature: [u8; 16] = [0; 16]; assert_eq!(reader.stream_position().ok(), Some(14 + 16)); - - let mut packet_specific_buffer = vec![0u8; header.packet_specific_size as usize]; reader.read_exact(&mut packet_specific_buffer)?; - //no clue whats up with options but they are broken let mut packet_specific_data_cursor = Cursor::new(&packet_specific_buffer); let mut options = Vec::new(); loop { - let Ok(option_id): io::Result = packet_specific_data_cursor.read_struct(IS_BIG_ENDIAN) else { - break + let Ok(option_id): io::Result = + packet_specific_data_cursor.read_struct(IS_BIG_ENDIAN) + else { + break; }; - let Ok(value_size): io::Result = packet_specific_data_cursor.read_struct(IS_BIG_ENDIAN) else { - break + let Ok(value_size): io::Result = + packet_specific_data_cursor.read_struct(IS_BIG_ENDIAN) + else { + break; }; if value_size == 0 { @@ -291,20 +229,21 @@ impl PRUDPV1Packet { } let mut option_data = vec![0u8; value_size as usize]; - if packet_specific_data_cursor.read_exact(&mut option_data[..]).is_err() { + if packet_specific_data_cursor + .read_exact(&mut option_data[..]) + .is_err() + { error!("unable to read options"); break; } options.push(PacketOption::from(option_id, &option_data)?); } - + let mut payload = vec![0u8; header.payload_size as usize]; reader.read_exact(&mut payload)?; - - Ok(Self { header, packet_signature, @@ -313,22 +252,21 @@ impl PRUDPV1Packet { }) } - pub fn base_acknowledgement_packet(&self) -> Self{ + pub fn base_acknowledgement_packet(&self) -> Self { let base = self.base_response_packet(); let mut flags = self.header.types_and_flags.flags(0); flags.set_flag(ACK); - let options = self.options + let options = self + .options .iter() .filter(|o| matches!(o, FragmentId(_))) .cloned() .collect(); - - - Self{ + Self { header: PRUDPV1Header { types_and_flags: flags, sequence_id: self.header.sequence_id, @@ -348,17 +286,24 @@ impl PRUDPV1Packet { } } - fn generate_options_bytes(&self) -> Vec{ + fn generate_options_bytes(&self) -> Vec { let mut vec = Vec::new(); - for option in &self.options{ - option.write_to_stream(&mut vec).expect("vec should always automatically be able to extend"); + for option in &self.options { + option + .write_to_stream(&mut vec) + .expect("vec should always automatically be able to extend"); } vec } - pub fn calculate_signature_value(&self, access_key: &str, session_key: Option<[u8; 32]>, connection_signature: Option<[u8; 16]>) -> [u8; 16]{ + pub fn calculate_signature_value( + &self, + access_key: &str, + session_key: Option<[u8; 32]>, + connection_signature: Option<[u8; 16]>, + ) -> [u8; 16] { let access_key_bytes = access_key.as_bytes(); let access_key_sum: u32 = access_key_bytes.iter().map(|v| *v as u32).sum(); let access_key_sum_bytes: [u8; 4] = access_key_sum.to_le_bytes(); @@ -374,32 +319,46 @@ impl PRUDPV1Packet { let mut hmac = Md5Hmac::new_from_slice(&key).expect("fuck"); - hmac.write(&header_data).expect("error during hmac calculation"); + hmac.write(&header_data) + .expect("error during hmac calculation"); if let Some(session_key) = session_key { - hmac.write(&session_key).expect("error during hmac calculation"); + hmac.write(&session_key) + .expect("error during hmac calculation"); } - hmac.write(&access_key_sum_bytes).expect("error during hmac calculation"); + hmac.write(&access_key_sum_bytes) + .expect("error during hmac calculation"); if let Some(connection_signature) = connection_signature { - hmac.write(&connection_signature).expect("error during hmac calculation"); + hmac.write(&connection_signature) + .expect("error during hmac calculation"); } - hmac.write(&option_bytes).expect("error during hmac calculation"); + hmac.write(&option_bytes) + .expect("error during hmac calculation"); - hmac.write_all(&self.payload).expect("error during hmac calculation"); + hmac.write_all(&self.payload) + .expect("error during hmac calculation"); - hmac.finalize().into_bytes()[0..16].try_into().expect("invalid hmac size") + hmac.finalize().into_bytes()[0..16] + .try_into() + .expect("invalid hmac size") } - pub fn calculate_and_assign_signature(&mut self, access_key: &str, session_key: Option<[u8; 32]>, connection_signature: Option<[u8; 16]>){ - self.packet_signature = self.calculate_signature_value(access_key, session_key, connection_signature); + pub fn calculate_and_assign_signature( + &mut self, + access_key: &str, + session_key: Option<[u8; 32]>, + connection_signature: Option<[u8; 16]>, + ) { + self.packet_signature = + self.calculate_signature_value(access_key, session_key, connection_signature); } - pub fn set_sizes(&mut self){ + pub fn set_sizes(&mut self) { self.header.packet_specific_size = self.options.iter().map(|o| o.write_size()).sum(); self.header.payload_size = self.payload.len() as u16; } - pub fn base_response_packet(&self) -> Self { + pub fn base_response_packet(&self) -> Self { Self { header: PRUDPV1Header { magic: [0xEA, 0xD0], @@ -412,19 +371,18 @@ impl PRUDPV1Packet { sequence_id: 0, session_id: 0, substream_id: 0, - }, packet_signature: [0; 16], payload: Default::default(), - options: Default::default() + options: Default::default(), } } - pub fn write_to(&self, writer: &mut impl Write) -> io::Result<()>{ + pub fn write_to(&self, writer: &mut impl Write) -> io::Result<()> { writer.write_all(bytemuck::bytes_of(&self.header))?; writer.write_all(&self.packet_signature)?; - for option in &self.options{ + for option in &self.options { option.write_to_stream(writer)?; } @@ -436,20 +394,24 @@ impl PRUDPV1Packet { #[cfg(test)] mod test { - use crate::prudp::packet::flags::{NEED_ACK, RELIABLE}; - use crate::prudp::packet::types::DATA; - use super::{OptionId, PacketOption, PRUDPV1Header, TypesFlags}; - use rnex_core::prudp::virtual_port::VirtualPort; + use super::{OptionId, PRUDPV1Header, PacketOption, TypesFlags}; + use rnex_core::prudp::{ + types_flags::{ + flags::{NEED_ACK, RELIABLE}, + types::DATA, + }, + virtual_port::VirtualPort, + }; #[test] fn size_test() { assert_eq!(size_of::(), 14); } #[test] - fn test_options(){ - let packet_types = [0,1,2,3,4]; + fn test_options() { + let packet_types = [0, 1, 2, 3, 4]; - for p_type in packet_types{ + for p_type in packet_types { let option_id = OptionId::new(p_type).unwrap(); let buf = vec![0; option_id.option_type_size() as usize]; @@ -463,12 +425,10 @@ mod test { assert_eq!(write_buf.len() as u8, opt.write_size()) } } - - } #[test] - fn header_read(){ + fn header_read() { let header = PRUDPV1Header { version: 0, destination_port: VirtualPort(0), @@ -478,8 +438,8 @@ mod test { packet_specific_size: 0, payload_size: 0, sequence_id: 0, - magic: [0xEA,0xD0], - source_port: VirtualPort(0) + magic: [0xEA, 0xD0], + source_port: VirtualPort(0), }; let bytes = bytemuck::bytes_of(&header); @@ -490,11 +450,11 @@ mod test { } #[test] - fn test_types_flags(){ + fn test_types_flags() { let types = TypesFlags::default().types(DATA).flags(NEED_ACK | RELIABLE); assert_ne!((types.0 >> 4) & NEED_ACK, 0); assert_ne!((types.0 >> 4) & RELIABLE, 0); assert_ne!((types.0 & 0xFF) as u8 & DATA, 0); } -} \ No newline at end of file +} diff --git a/prudpv1/src/prudp/secure.rs b/prudpv1/src/prudp/secure.rs index acf8bfb..a9f7960 100644 --- a/prudpv1/src/prudp/secure.rs +++ b/prudpv1/src/prudp/secure.rs @@ -1,18 +1,19 @@ -use std::io::Cursor; +use crate::prudp::packet::PRUDPV1Packet; +use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance}; use hmac::digest::consts::U32; use log::error; use rc4::cipher::StreamCipherCoreWrapper; -use rc4::{KeyInit, Rc4, Rc4Core, StreamCipher}; use rc4::consts::U16; +use rc4::{KeyInit, Rc4, Rc4Core, StreamCipher}; +use rnex_core::kerberos::{TicketInternalData, derive_key}; +use rnex_core::nex::account::Account; +use rnex_core::prudp::encryption::EncryptionPair; +use rnex_core::rmc::structures::RmcSerialize; +use std::io::Cursor; use typenum::U5; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -use rnex_core::kerberos::{derive_key, TicketInternalData}; -use rnex_core::nex::account::Account; -use crate::prudp::packet::PRUDPV1Packet; -use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance, EncryptionPair}; -use rnex_core::rmc::structures::RmcSerialize; -pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 32], u32, u32)>{ +pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 32], u32, u32)> { let mut cursor = Cursor::new(data); let mut ticket_data: Vec = Vec::deserialize(&mut cursor).ok()?; @@ -20,7 +21,7 @@ pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 3 let ticket_data_size = ticket_data.len(); - let ticket_data = &mut ticket_data[0..ticket_data_size-0x10]; + let ticket_data = &mut ticket_data[0..ticket_data_size - 0x10]; let server_key = derive_key(act.pid, act.kerbros_password); @@ -29,7 +30,7 @@ pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 3 rc4.apply_keystream(ticket_data); - let ticket_data: &TicketInternalData = match bytemuck::try_from_bytes(ticket_data){ + let ticket_data: &TicketInternalData = match bytemuck::try_from_bytes(ticket_data) { Ok(v) => v, Err(e) => { error!("unable to read internal ticket data: {}", e); @@ -39,15 +40,15 @@ pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 3 // todo: add ticket expiration - let TicketInternalData{ + let TicketInternalData { session_key, pid: ticket_source_pid, - issued_time + issued_time, } = *ticket_data; // todo: add checking if tickets are signed with a valid md5-hmac let request_data_length = request_data.len(); - let request_data = &mut request_data[0.. request_data_length - 0x10]; + let request_data = &mut request_data[0..request_data_length - 0x10]; let mut rc4: StreamCipherCoreWrapper> = Rc4::new_from_slice(&session_key).expect("unable to init rc4 keystream"); @@ -58,53 +59,55 @@ pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 3 let pid: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?; - if pid != ticket_source_pid{ + if pid != ticket_source_pid { let ticket_created_on = issued_time.to_regular_time(); - error!("someone tried to spoof their pid, ticket was created on: {}", ticket_created_on.to_rfc2822()); + error!( + "someone tried to spoof their pid, ticket was created on: {}", + ticket_created_on.to_rfc2822() + ); return None; } let _cid: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?; let response_check: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?; - - Some((session_key, pid, response_check)) } type Rc4U32 = StreamCipherCoreWrapper>; -pub fn generate_secure_encryption_pairs(mut session_key: [u8; 32], count: u8) -> Vec>>{ +pub fn generate_secure_encryption_pairs( + mut session_key: [u8; 32], + count: u8, +) -> Vec>> { let mut vec = Vec::with_capacity(count as usize); - vec.push(EncryptionPair{ + vec.push(EncryptionPair { send: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"), - recv: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4") + recv: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"), }); - for _ in 1..=count{ + for _ in 1..=count { let modifier = session_key.len() + 1; let key_length = session_key.len(); - for (position, val) in (&mut session_key[0..key_length/2]).iter_mut().enumerate(){ + for (position, val) in (&mut session_key[0..key_length / 2]).iter_mut().enumerate() { *val = val.wrapping_add((modifier - position) as u8); } - vec.push(EncryptionPair{ + vec.push(EncryptionPair { send: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"), - recv: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4") + recv: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"), }); } vec } - pub struct Secure(pub &'static str, pub Account); - pub struct SecureInstance { access_key: &'static str, session_key: [u8; 32], @@ -155,18 +158,17 @@ impl CryptoHandler for Secure { } } - impl CryptoHandlerConnectionInstance for SecureInstance { type Encryption = Rc4; fn decrypt_incoming(&mut self, substream: u8, data: &mut [u8]) { - if let Some(crypt_pair) = self.streams.get_mut(substream as usize){ + if let Some(crypt_pair) = self.streams.get_mut(substream as usize) { crypt_pair.recv.apply_keystream(data); } } fn encrypt_outgoing(&mut self, substream: u8, data: &mut [u8]) { - if let Some(crypt_pair) = self.streams.get_mut(substream as usize){ + if let Some(crypt_pair) = self.streams.get_mut(substream as usize) { crypt_pair.send.apply_keystream(data); } } @@ -182,10 +184,14 @@ impl CryptoHandlerConnectionInstance for SecureInstance { fn sign_packet(&self, packet: &mut PRUDPV1Packet) { packet.set_sizes(); - packet.calculate_and_assign_signature(self.access_key, Some(self.session_key), Some(self.self_signature)); + packet.calculate_and_assign_signature( + self.access_key, + Some(self.session_key), + Some(self.self_signature), + ); } fn verify_packet(&self, _packet: &PRUDPV1Packet) -> bool { true } -} \ No newline at end of file +} diff --git a/prudpv1/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs index 6467d8f..a3b0445 100644 --- a/prudpv1/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -1,47 +1,34 @@ -use crate::prudp::packet::flags::{ACK, HAS_SIZE, MULTI_ACK, NEED_ACK, RELIABLE}; -use crate::prudp::packet::types::{CONNECT, DATA, DISCONNECT, PING, SYN}; use crate::prudp::packet::PacketOption::{ ConnectionSignature, FragmentId, MaximumSubstreamId, SupportedFunctions, }; -use crate::prudp::packet::{PRUDPV1Header, PRUDPV1Packet, TypesFlags}; -use rnex_core::prudp::virtual_port::VirtualPort; -use rnex_core::prudp::socket_addr::PRUDPSockAddr; +use crate::prudp::packet::{PRUDPV1Header, PRUDPV1Packet}; use async_trait::async_trait; -use log::{info, warn}; use log::error; +use log::{info, warn}; use rc4::StreamCipher; -use v_byte_helpers::ReadExtensions; -use v_byte_helpers::little_endian::read_u16; +use rnex_core::prudp::socket_addr::PRUDPSockAddr; +use rnex_core::prudp::types_flags::TypesFlags; +use rnex_core::prudp::types_flags::flags::{ACK, HAS_SIZE, MULTI_ACK, NEED_ACK, RELIABLE}; +use rnex_core::prudp::types_flags::types::{CONNECT, DATA, DISCONNECT, PING, SYN}; +use rnex_core::prudp::virtual_port::VirtualPort; use std::collections::{BTreeMap, HashMap}; use std::io::Cursor; use std::marker::PhantomData; use std::ops::Deref; use std::sync::{Arc, Weak}; +use v_byte_helpers::ReadExtensions; +use v_byte_helpers::little_endian::read_u16; use std::time::Duration; use tokio::net::UdpSocket; -use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio::sync::Mutex; -use tokio::time::{sleep, Instant}; +use tokio::sync::mpsc::{Receiver, Sender, channel}; +use tokio::time::{Instant, sleep}; // due to the way this is designed crashing the router thread causes deadlock, sorry ;-; // (maybe i will fix that some day) /// PRUDP Socket for accepting connections to then send and recieve data from those clients -pub struct EncryptionPair { - pub send: T, - pub recv: T, -} - -impl EncryptionPair { - pub fn init_both T>(func: F) -> Self { - Self { - recv: func(), - send: func(), - } - } -} - pub struct CommonConnection { pub user_id: u32, pub socket_addr: PRUDPSockAddr, @@ -61,7 +48,7 @@ struct InternalConnection { socket: Arc, packet_queue: HashMap, last_packet_time: Instant, - unacknowleged_packets: Vec<(Instant, PRUDPV1Packet)> + unacknowleged_packets: Vec<(Instant, PRUDPV1Packet)>, } impl Deref for InternalConnection { @@ -82,17 +69,17 @@ impl InternalConnection { } /// Sends a raw packet to a given client on the connection - /// - /// a raw packet is one which does not get processed any further(other than to send it + /// + /// a raw packet is one which does not get processed any further(other than to send it /// off without buffering or anything), - /// as such you need to make sure that + /// as such you need to make sure that /// the sizes are set correctly and so on #[inline] async fn send_raw_packet(&self, prudp_packet: &PRUDPV1Packet) { send_raw_prudp_to_sockaddr(&self.socket, self.socket_addr, prudp_packet).await; } - async fn delete_connection(&self){ + async fn delete_connection(&self) { let Some(conns) = self.connections.upgrade() else { // this is fine as it implies the server has already quit, thus meaning that we dont // have to remove ourselves from the server @@ -187,8 +174,6 @@ pub(super) trait AnyInternalConnection: async fn close_connection(&mut self); } - - #[async_trait] impl AnyInternalConnection for InternalConnection { async fn send_data_packet(&mut self, data: Vec) { @@ -219,7 +204,6 @@ impl AnyInternalConnection for InternalConne self.unacknowleged_packets.push((Instant::now(), packet)); } - async fn close_connection(&mut self) { // jon confirmed that this should be a safe way to dc a client @@ -250,7 +234,11 @@ impl AnyInternalConnection for InternalConne } } -async fn send_raw_prudp_to_sockaddr(udp_socket: &UdpSocket, dest: PRUDPSockAddr, packet: &PRUDPV1Packet){ +async fn send_raw_prudp_to_sockaddr( + udp_socket: &UdpSocket, + dest: PRUDPSockAddr, + packet: &PRUDPV1Packet, +) { let mut vec = Vec::new(); packet @@ -281,7 +269,7 @@ impl InternalSocket { } /// sends a raw packet to a specific prudp socket address - /// + /// /// a raw packet is a packet is a packet which wont get processed any further, /// sizes signatures etc need to be set before using this function async fn send_packet_unbuffered(&self, dest: PRUDPSockAddr, packet: &PRUDPV1Packet) { @@ -353,13 +341,15 @@ impl InternalSocket { conn.close_connection().await; } - for (send_time, packet) in &conn.unacknowleged_packets{ - if *send_time < (Instant::now() - Duration::from_millis(3000)){ - warn!("failed to resend packet 5 times and never got response, destroying connection"); + for (send_time, packet) in &conn.unacknowleged_packets { + if *send_time < (Instant::now() - Duration::from_millis(3000)) { + warn!( + "failed to resend packet 5 times and never got response, destroying connection" + ); conn.close_connection().await; break; } - if *send_time < (Instant::now() - Duration::from_millis(500)){ + if *send_time < (Instant::now() - Duration::from_millis(500)) { info!("unacknowledged packet sat arround for more than 500 ms, resending"); conn.send_raw_packet(packet).await; } @@ -399,7 +389,7 @@ impl InternalSocket { packet_queue: Default::default(), last_packet_time: Instant::now(), unacknowleged_packets: Vec::new(), - supported_function_version + supported_function_version, }; let internal = Arc::new(Mutex::new(internal)); @@ -487,7 +477,7 @@ impl InternalSocket { SupportedFunctions(funcs) => { functions = *funcs & 0xFF; response.options.push(SupportedFunctions(*funcs & 0xFF)); - }, + } _ => { /* ? */ } } } @@ -610,7 +600,6 @@ impl AnyInternalSocket for InternalSocket { if (packet.header.types_and_flags.get_flags() & ACK) != 0 { info!("got ack"); - if packet.header.types_and_flags.get_types() == SYN || packet.header.types_and_flags.get_types() == CONNECT { @@ -645,9 +634,8 @@ impl AnyInternalSocket for InternalSocket { // remove the packet whose sequence id matches the ack packet // or in other words keep all of those which dont match the sequence id - conn.unacknowleged_packets.retain_mut(|v| { - packet.header.sequence_id != v.1.header.sequence_id - }); + conn.unacknowleged_packets + .retain_mut(|v| packet.header.sequence_id != v.1.header.sequence_id); } else { error!("non connection acknowledgement packet on nonexistent connection...") } @@ -659,26 +647,23 @@ impl AnyInternalSocket for InternalSocket { if let Some(conn) = self.get_connection(address).await { let mut conn = conn.lock().await; - if conn.supported_function_version == 1{ + if conn.supported_function_version == 1 { let mut collected_ids: Vec = Vec::new(); let mut cursor = Cursor::new(&packet.payload); - while let Ok(v) = read_u16(&mut cursor){ + while let Ok(v) = read_u16(&mut cursor) { collected_ids.push(v); } conn.unacknowleged_packets.retain_mut(|(_, up)| { - !( - collected_ids.iter().any(|id| up.header.sequence_id == *id) || - up.header.sequence_id <= packet.header.sequence_id - ) + !(collected_ids.iter().any(|id| up.header.sequence_id == *id) + || up.header.sequence_id <= packet.header.sequence_id) }); - } else { let mut collected_ids: Vec = Vec::new(); let mut cursor = Cursor::new(&packet.payload); - let Ok(_substream_id): Result = cursor.read_le_struct() else{ + let Ok(_substream_id): Result = cursor.read_le_struct() else { error!("invalid data whilest reading new version agregate acknowledgement"); return; }; @@ -690,19 +675,20 @@ impl AnyInternalSocket for InternalSocket { error!("invalid data whilest reading new version agregate acknowledgement"); return; }; - for _ in 0..additional_sequence_ids{ - let Ok(additional_sequence_id): Result = cursor.read_le_struct() else { - error!("invalid data whilest reading new version agregate acknowledgement"); + for _ in 0..additional_sequence_ids { + let Ok(additional_sequence_id): Result = cursor.read_le_struct() + else { + error!( + "invalid data whilest reading new version agregate acknowledgement" + ); return; }; collected_ids.push(additional_sequence_id); } conn.unacknowleged_packets.retain_mut(|(_, up)| { - !( - collected_ids.iter().any(|id| up.header.sequence_id == *id) || - up.header.sequence_id <= sequence_id - ) + !(collected_ids.iter().any(|id| up.header.sequence_id == *id) + || up.header.sequence_id <= sequence_id) }); } } else { diff --git a/prudpv1/src/prudp/unsecure.rs b/prudpv1/src/prudp/unsecure.rs index 6c45824..d47550f 100644 --- a/prudpv1/src/prudp/unsecure.rs +++ b/prudpv1/src/prudp/unsecure.rs @@ -1,13 +1,12 @@ +use crate::prudp::packet::PRUDPV1Packet; +use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance}; use once_cell::sync::Lazy; use rc4::{Key, KeyInit, Rc4, StreamCipher}; +use rnex_core::prudp::encryption::{DEFAULT_KEY, EncryptionPair}; use typenum::U5; -use crate::prudp::packet::PRUDPV1Packet; -use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance, EncryptionPair}; pub struct Unsecure(pub &'static str); - - pub struct UnsecureInstance { key: &'static str, streams: Vec>>, @@ -18,7 +17,6 @@ pub struct UnsecureInstance { // my hand was forced to use lazy so that we can guarantee this code // only runs once and so that i can put it here as a "constant" (for performance and readability) // since for some reason rust crypto doesn't have any const time key initialization -static DEFAULT_KEY: Lazy> = Lazy::new(|| Key::from(*b"CD&ML")); impl CryptoHandler for Unsecure { type CryptoConnectionInstance = UnsecureInstance; @@ -53,13 +51,13 @@ impl CryptoHandlerConnectionInstance for UnsecureInstance { type Encryption = Rc4; fn decrypt_incoming(&mut self, substream: u8, data: &mut [u8]) { - if let Some(crypt_pair) = self.streams.get_mut(substream as usize){ + if let Some(crypt_pair) = self.streams.get_mut(substream as usize) { crypt_pair.recv.apply_keystream(data); } } fn encrypt_outgoing(&mut self, substream: u8, data: &mut [u8]) { - if let Some(crypt_pair) = self.streams.get_mut(substream as usize){ + if let Some(crypt_pair) = self.streams.get_mut(substream as usize) { crypt_pair.send.apply_keystream(data); } } @@ -81,4 +79,4 @@ impl CryptoHandlerConnectionInstance for UnsecureInstance { fn verify_packet(&self, _packet: &PRUDPV1Packet) -> bool { true } -} \ No newline at end of file +} diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 554a8d9..eaf0f5f 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -9,7 +9,7 @@ dotenv = "0.15.0" once_cell = "1.20.2" rc4 = "0.1.0" thiserror = "2.0.11" -v-byte-helpers = { git = "https://github.com/DJMrTV/VByteMacros", version = "0.1.1" } +v-byte-helpers = { git = "https://github.com/RusticMaple/VByteMacros", version = "0.1.1" } simplelog = "0.12.2" chrono = "0.4.39" log = "0.4.25" @@ -48,4 +48,4 @@ path = "src/executables/backend_server_secure.rs" [[bin]] name = "edge_node_holder_server" -path = "src/executables/edge_node_holder_server.rs" \ No newline at end of file +path = "src/executables/edge_node_holder_server.rs" diff --git a/rnex-core/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs index 1488369..598b039 100644 --- a/rnex-core/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -1,19 +1,18 @@ -use std::sync::Arc; -use std::sync::atomic::AtomicU32; use rnex_core::common::setup; -use rnex_core::executables::common::{new_simple_backend}; +use rnex_core::executables::common::new_simple_backend; use rnex_core::nex::matchmake::MatchmakeManager; use rnex_core::nex::remote_console::RemoteConsole; use rnex_core::nex::user::User; -use rnex_core::rmc::protocols::RemoteInstantiatable; +use rnex_core::rmc::protocols::{RemoteDisconnectable, RmcPureRemoteObject}; +use std::sync::Arc; +use std::sync::atomic::AtomicU32; #[tokio::main] async fn main() { setup(); - - let mmm = Arc::new(MatchmakeManager{ - gid_counter: AtomicU32::new(1), + let mmm = Arc::new(MatchmakeManager { + //gid_counter: AtomicU32::new(1), sessions: Default::default(), users: Default::default(), rv_cid_counter: AtomicU32::new(1), @@ -23,15 +22,16 @@ async fn main() { MatchmakeManager::initialize_garbage_collect_thread(weak_mmm).await; - new_simple_backend(move |c, r|{ + new_simple_backend(move |c, r| { let mmm = mmm.clone(); - Arc::new_cyclic(move |this| User{ + Arc::new_cyclic(move |this| User { this: this.clone(), ip: c.prudpsock_addr, - pid:c.pid, + pid: c.pid, remote: RemoteConsole::new(r), matchmake_manager: mmm, - station_url: Default::default() + station_url: Default::default(), }) - }).await; -} \ No newline at end of file + }) + .await; +} diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index 7a55f24..0d5ca06 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -1,27 +1,23 @@ +use once_cell::sync::Lazy; +use rnex_core::nex::account::Account; +use rnex_core::rmc::protocols::{RmcCallable, RmcConnection, new_rmc_gateway_connection}; +use rnex_core::rmc::structures::RmcSerialize; +use rnex_core::rnex_proxy_common::ConnectionInitData; use std::env; use std::io::Cursor; use std::net::{Ipv4Addr, SocketAddrV4}; use std::sync::Arc; -use once_cell::sync::Lazy; -use rnex_core::nex::account::Account; -use rnex_core::rmc::protocols::{RmcCallable, RmcConnection, new_rmc_gateway_connection}; -use rnex_core::rnex_proxy_common::ConnectionInitData; -use rnex_core::rmc::structures::RmcSerialize; use tokio::net::TcpListener; -use std::error::Error; use log::error; +use std::error::Error; use crate::reggie::UnitPacketRead; const IP_REQ_SERVICE_URL: &str = "https://ipinfo.io/ip"; - - -fn try_get_ip() -> Result> { - let mut req = ureq::get(IP_REQ_SERVICE_URL) - .call()?; - +pub fn try_get_ip() -> Result> { + let mut req = ureq::get(IP_REQ_SERVICE_URL).call()?; Ok(req.body_mut().read_to_string()?.parse()?) } @@ -37,16 +33,14 @@ pub static OWN_IP_PUBLIC: Lazy = Lazy::new(|| { env::var("SERVER_IP_PUBLIC") .ok() .map(|s| s.parse().expect("invalid ip address")) - .unwrap_or_else(||{ - try_get_ip().unwrap() - }) + .unwrap_or_else(|| try_get_ip().unwrap()) }); pub static SERVER_PORT: Lazy = Lazy::new(|| { env::var("SERVER_PORT") .ok() .and_then(|s| s.parse().ok()) - .unwrap_or(10000) + .unwrap_or(6000) }); pub static KERBEROS_SERVER_PASSWORD: Lazy = Lazy::new(|| { @@ -60,24 +54,28 @@ pub static AUTH_SERVER_ACCOUNT: Lazy = pub static SECURE_SERVER_ACCOUNT: Lazy = Lazy::new(|| Account::new(2, "Quazal Rendez-Vous", &KERBEROS_SERVER_PASSWORD)); - -pub async fn new_simple_backend(mut creation_function: F) +pub async fn new_simple_backend(mut creation_function: F) where F: FnMut(ConnectionInitData, RmcConnection) -> Arc, { - let listen = TcpListener::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)).await.unwrap(); + let listen = TcpListener::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) + .await + .unwrap(); while let Ok((mut stream, _addr)) = listen.accept().await { - let buffer = match stream.read_buffer().await{ + let buffer = match stream.read_buffer().await { Ok(v) => v, Err(e) => { - error!("an error ocurred whilest reading connection data buffer: {:?}", e); + error!( + "an error ocurred whilest reading connection data buffer: {:?}", + e + ); continue; } }; let user_connection_data = ConnectionInitData::deserialize(&mut Cursor::new(buffer)); - let user_connection_data = match user_connection_data{ + let user_connection_data = match user_connection_data { Ok(v) => v, Err(e) => { error!("an error ocurred whilest reading connection data: {:?}", e); @@ -85,8 +83,6 @@ where } }; let fun_ref = &mut creation_function; - new_rmc_gateway_connection(stream.into(), move |r|{ - fun_ref(user_connection_data, r) - }); + new_rmc_gateway_connection(stream.into(), move |r| fun_ref(user_connection_data, r)); } -} \ No newline at end of file +} diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index 9b67fca..1bd6e27 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -1,19 +1,19 @@ -use std::hash::{DefaultHasher, Hasher}; -use std::net::SocketAddrV4; -use std::sync::Arc; use crate::grpc::account; -use rnex_core::kerberos::{derive_key, KerberosDateTime, Ticket}; +use crate::reggie::{RemoteEdgeNodeHolder, RemoteEdgeNodeManagement}; +use crate::{define_rmc_proto, kerberos}; +use macros::rmc_struct; +use rnex_core::kerberos::{KerberosDateTime, Ticket, derive_key}; use rnex_core::nex::account::Account; +use rnex_core::rmc::protocols::OnlyRemote; use rnex_core::rmc::protocols::auth::{Auth, RawAuth, RawAuthInfo, RemoteAuth}; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::response::ErrorCode::Core_Unknown; use rnex_core::rmc::structures::any::Any; use rnex_core::rmc::structures::connection_data::ConnectionData; use rnex_core::rmc::structures::qresult::QResult; -use crate::{define_rmc_proto, kerberos}; -use macros::rmc_struct; -use crate::reggie::{RemoteEdgeNodeHolder, RemoteEdgeNodeManagement}; -use rnex_core::rmc::protocols::OnlyRemote; +use std::hash::{DefaultHasher, Hasher}; +use std::net::SocketAddrV4; +use std::sync::Arc; define_rmc_proto!( proto AuthClientProtocol{ @@ -60,10 +60,11 @@ async fn get_login_data_by_pid(pid: u32) -> Option<(u32, [u8; 16])> { Some((pid, passwd)) } -fn station_url_from_sock_addr(sock_addr: SocketAddrV4) -> String{ +fn station_url_from_sock_addr(sock_addr: SocketAddrV4) -> String { format!( "prudps:/PID=2;sid=1;stream=10;type=2;address={};port={};CID=1", - sock_addr.ip(), sock_addr.port() + sock_addr.ip(), + sock_addr.port() ) } @@ -99,7 +100,7 @@ impl Auth for AuthHandler { let mut hasher = DefaultHasher::new(); hasher.write(name.as_bytes()); - + let Ok(addr) = self.control_server.get_url(hasher.finish()).await else { return Err(ErrorCode::Core_Exception); }; @@ -117,7 +118,7 @@ impl Auth for AuthHandler { source_login_data.0, ticket.into(), connection_data, - self.build_name.to_string() //format!("{}; Rust NEX Version {} by DJMrTV", self.build_name, env!("CARGO_PKG_VERSION")), + self.build_name.to_string(), //format!("{}; Rust NEX Version {} by DJMrTV", self.build_name, env!("CARGO_PKG_VERSION")), )) } @@ -157,32 +158,30 @@ impl Auth for AuthHandler { #[cfg(test)] mod test { + use rnex_core::rmc::response::RMCResponse; + use rnex_core::rmc::structures::RmcSerialize; use rnex_core::rmc::structures::connection_data::ConnectionData; use rnex_core::rmc::structures::qresult::QResult; - use rnex_core::rmc::structures::RmcSerialize; - use rnex_core::rmc::response::RMCResponse; use std::io::Cursor; - - #[test] fn test() { - + return; let stuff = hex::decode("200100000a0106000000028000000100010051b3995774000000a6321c7f78847c1c5e9fb825eb26bd91841f1a40d92fc694159666119cb13527f1463ac48ad42a63e6613ede67041554b1770978112e6f1f3e177a2bfc75933216dbe38f70133a1eb28e2ae32a4b5c4b0c3e3efd4c02907992e259b257270b57a9dbe7792f4721b07f8fafb9e32d50f2555c616a015c0000004b007072756470733a2f5049443d323b7369643d313b73747265616d3d31303b747970653d323b616464726573733d322e3234332e39352e3131333b706f72743d31303030313b4349443d3100000000000100002c153ba51f00000033006272616e63683a6f726967696e2f70726f6a6563742f7775702d61676d6a206275696c643a335f385f31355f323030345f3000").unwrap(); let stuff = RMCResponse::new(&mut Cursor::new(stuff)).unwrap(); - let rnex_core::rmc::response::RMCResponseResult::Success { .. } = stuff.response_result else { + let rnex_core::rmc::response::RMCResponseResult::Success { .. } = stuff.response_result + else { panic!() }; - - // let stuff = hex::decode("0100010051B399577400000085F1736FCFBE93660275A3FE36FED6C2EFC57222AC99A9219CF54170A415B02DF1463AC48AD42A6307813FDE67041554B177097832ED000F892D9551A09F88E9CB0388DC1BC9527CC7384556A3287B2A349ABBF7E34A5A3EC14C2287CC7F78DA616BC3B03A035347FBD2E9A505C8EF42447CD809015F0000004E007072756470733A2F73747265616D3D31303B747970653D323B616464726573733D3139322E3136382E3137382E3132303B706F72743D31303030313B4349443D313B5049443D323B7369643D310000000000010000CDF53AA51F00000033006272616E63683A6F726967696E2F70726F6A6563742F7775702D61676D6A206275696C643A335F385F31355F323030345F3000").unwrap(); let stuff = hex::decode("0100010051b399577400000037d3d4814d2b16dd546c94a75d32637b45f856b5abe73cf26cfaa235c5f2c1cef1463ac48ad42a637d873fde67041554b177097880cfa7e10bb810eaf686bfb0a0cf3d65b1f476ebc046d0855327986f557dca14fbb8594883c186b863f2206f22baa0309dbcc81da2f883cb2cdc12628ec7fced015c0000004b007072756470733a2f5049443d323b7369643d313b73747265616d3d31303b747970653d323b616464726573733d322e3234332e39352e3131333b706f72743d31303030313b4349443d310000000000010000b7f33aa51f00000033006272616e63683a6f726967696e2f70726f6a6563742f7775702d61676d6a206275696c643a335f385f31355f323030345f3000").unwrap(); let data = <(QResult, u32, Vec, ConnectionData, String) as RmcSerialize>::deserialize( &mut Cursor::new(stuff), - ).unwrap(); + ) + .unwrap(); println!("data: {:?}", data); } diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index a2f8c20..732c1ea 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -1,40 +1,48 @@ -use std::collections::HashMap; -use std::str::FromStr; -use std::sync::{Arc, Weak}; -use std::sync::atomic::AtomicU32; -use std::sync::atomic::Ordering::Relaxed; -use std::time::Duration; -use log::info; -use rand::random; -use tokio::sync::{Mutex, RwLock}; -use tokio::time::sleep; -use rnex_core::kerberos::KerberosDateTime; use crate::nex::user::User; use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; -use rnex_core::rmc::protocols::notifications::notification_types::{HOST_CHANGED, OWNERSHIP_CHANGED}; +use log::info; +use rand::random; +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::rmc::protocols::notifications::notification_types::{ + HOST_CHANGED, OWNERSHIP_CHANGED, +}; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::response::ErrorCode::{Core_InvalidArgument, RendezVous_SessionVoid}; -use rnex_core::rmc::structures::matchmake::{Gathering, MatchmakeParam, MatchmakeSession, MatchmakeSessionSearchCriteria}; use rnex_core::rmc::structures::matchmake::gathering_flags::PERSISTENT_GATHERING; +use rnex_core::rmc::structures::matchmake::{ + Gathering, MatchmakeParam, MatchmakeSession, MatchmakeSessionSearchCriteria, +}; use rnex_core::rmc::structures::variant::Variant; +use std::collections::HashMap; +use std::str::FromStr; +use std::sync::atomic::AtomicU32; +use std::sync::atomic::Ordering::Relaxed; +use std::sync::{Arc, Weak}; +use std::time::Duration; +use tokio::sync::{Mutex, RwLock}; +use tokio::time::sleep; -pub struct MatchmakeManager{ - pub gid_counter: AtomicU32, +pub struct MatchmakeManager { + //pub gid_counter: AtomicU32, pub sessions: RwLock>>>, pub rv_cid_counter: AtomicU32, - pub users: RwLock>> + pub users: RwLock>>, } -impl MatchmakeManager{ - pub fn next_gid(&self) -> u32{ - self.gid_counter.fetch_add(1, Relaxed) +impl MatchmakeManager { + pub fn next_gid(&self) -> u32 { + random() + //self.gid_counter.fetch_add(1, Relaxed) } - pub fn next_cid(&self) -> u32{ + pub fn next_cid(&self) -> u32 { self.rv_cid_counter.fetch_add(1, Relaxed) } - pub async fn get_session(&self, gid: u32) -> Result>, ErrorCode>{ + pub async fn get_session( + &self, + gid: u32, + ) -> Result>, ErrorCode> { let sessions = self.sessions.read().await; let Some(session) = sessions.get(&gid) else { @@ -47,7 +55,7 @@ impl MatchmakeManager{ Ok(session) } - async fn garbage_collect(&self){ + async fn garbage_collect(&self) { info!("running rnex garbage collector over all sessions and users"); let mut idx = 0; @@ -61,12 +69,12 @@ impl MatchmakeManager{ let sessions = self.sessions.read().await; let session_pair = sessions.iter().nth(idx).map(|s| (*s.0, s.1.clone())); drop(sessions); - + session_pair - }{ + } { let session = session.lock().await; - if !session.is_reachable(){ + if !session.is_reachable() { to_be_deleted_gids.push(gid); } @@ -75,14 +83,14 @@ impl MatchmakeManager{ let mut sessions = self.sessions.write().await; - for gid in to_be_deleted_gids{ + for gid in to_be_deleted_gids { sessions.remove(&gid); } } - pub async fn initialize_garbage_collect_thread(this: Weak){ + pub async fn initialize_garbage_collect_thread(this: Weak) { tokio::spawn(async move { - while let Some(this) = this.upgrade(){ + while let Some(this) = this.upgrade() { this.garbage_collect().await; // every 30 minutes @@ -92,51 +100,62 @@ impl MatchmakeManager{ } } - #[derive(Default, Debug)] -pub struct ExtendedMatchmakeSession{ +pub struct ExtendedMatchmakeSession { pub session: MatchmakeSession, pub connected_players: Vec>, } -fn read_bounds_string(str: &str) -> Option<(T,T)>{ +fn read_bounds_string(str: &str) -> Option<(T, T)> { let bounds = str.split_once(",")?; Some((T::from_str(bounds.0).ok()?, T::from_str(bounds.1).ok()?)) } -fn check_bounds_str(compare: T, str: &str) -> Option{ +fn check_bounds_str(compare: T, str: &str) -> Option { let bounds: (T, T) = read_bounds_string(str)?; Some(bounds.0 <= compare && compare <= bounds.1) } -pub async fn broadcast_notification>(players: &[T], notification_event: &NotificationEvent){ - for player in players{ +pub async fn broadcast_notification>( + players: &[T], + notification_event: &NotificationEvent, +) { + for player in players { let player = player.as_ref(); - player.remote.process_notification_event(notification_event.clone()).await; + player + .remote + .process_notification_event(notification_event.clone()) + .await; } } -impl ExtendedMatchmakeSession{ +impl ExtendedMatchmakeSession { #[inline(always)] - pub fn get_active_players(&self) -> Vec>{ - self.connected_players.iter().filter_map(|u| u.upgrade()).collect() + pub fn get_active_players(&self) -> Vec> { + self.connected_players + .iter() + .filter_map(|u| u.upgrade()) + .collect() } #[inline(always)] - pub async fn broadcast_notification(&self, notification_event: &NotificationEvent){ + pub async fn broadcast_notification(&self, notification_event: &NotificationEvent) { broadcast_notification(&self.get_active_players(), notification_event).await; } - pub async fn from_matchmake_session(gid: u32, session: MatchmakeSession, host: &Weak) -> Self{ - let Some(host) = host.upgrade() else{ + pub async fn from_matchmake_session( + gid: u32, + session: MatchmakeSession, + host: &Weak, + ) -> Self { + let Some(host) = host.upgrade() else { return Default::default(); }; - - let mm_session = MatchmakeSession{ - gathering: Gathering{ + let mm_session = MatchmakeSession { + gathering: Gathering { self_gid: gid, owner_pid: host.pid, host_pid: host.pid, @@ -144,25 +163,25 @@ impl ExtendedMatchmakeSession{ }, datetime: KerberosDateTime::now(), session_key: (0..32).map(|_| random()).collect(), - matchmake_param: MatchmakeParam{ + matchmake_param: MatchmakeParam { params: vec![ ("@SR".to_owned(), Variant::Bool(true)), - ("@GIR".to_owned(), Variant::SInt64(3)) - ] + ("@GIR".to_owned(), Variant::SInt64(3)), + ], }, system_password_enabled: false, ..session }; - Self{ + Self { session: mm_session, - connected_players: Default::default() + connected_players: Default::default(), } } pub async fn add_players(&mut self, conns: &[Weak], join_msg: String) { let Some(initiating_user) = conns[0].upgrade() else { - return + return; }; let initiating_pid = initiating_user.pid; @@ -173,36 +192,42 @@ impl ExtendedMatchmakeSession{ } self.session.participation_count = self.connected_players.len() as u32; - for other_connection in &conns[1..]{ + for other_connection in &conns[1..] { let Some(other_conn) = other_connection.upgrade() else { continue; }; - let other_pid = other_conn.pid; /*if other_pid == self.session.gathering.owner_pid && joining_pid == self.session.gathering.owner_pid{ continue; }*/ - other_conn.remote.process_notification_event(NotificationEvent{ - pid_source: initiating_pid, - notif_type: 122000, - param_1: self.session.gathering.self_gid, - param_2: other_pid, - str_param: "".into(), - param_3: 0 - }).await; + other_conn + .remote + .process_notification_event(NotificationEvent { + pid_source: initiating_pid, + notif_type: 122000, + param_1: self.session.gathering.self_gid, + param_2: other_pid, + str_param: "".into(), + param_3: 0, + }) + .await; } - let list_of_connected_pids: Vec<_> = self.connected_players.iter().filter_map(|p| p.upgrade()).map(|p| p.pid).collect(); + let list_of_connected_pids: Vec<_> = self + .connected_players + .iter() + .filter_map(|p| p.upgrade()) + .map(|p| p.pid) + .collect(); - for other_connection in conns{ + for other_connection in conns { let Some(other_conn) = other_connection.upgrade() else { continue; }; - // let other_pid = other_conn.pid; /*if other_pid == self.session.gathering.owner_pid && joining_pid == self.session.gathering.owner_pid{ @@ -210,44 +235,52 @@ impl ExtendedMatchmakeSession{ }*/ for pid in &list_of_connected_pids { - other_conn.remote.process_notification_event(NotificationEvent { - pid_source: initiating_pid, - notif_type: 3001, - param_1: self.session.gathering.self_gid, - param_2: *pid, - str_param: join_msg.clone(), - param_3: self.connected_players.len() as _ - }).await; + other_conn + .remote + .process_notification_event(NotificationEvent { + pid_source: initiating_pid, + notif_type: 3001, + param_1: self.session.gathering.self_gid, + param_2: *pid, + str_param: join_msg.clone(), + param_3: self.connected_players.len() as _, + }) + .await; } } - for old_conns in &old_particip{ + for old_conns in &old_particip { let Some(old_conns) = old_conns.upgrade() else { continue; }; let older_pid = old_conns.pid; - - - initiating_user.remote.process_notification_event(NotificationEvent{ - pid_source: initiating_pid, - notif_type: 3001, - param_1: self.session.gathering.self_gid, - param_2: older_pid, - str_param: join_msg.clone(), - param_3: self.connected_players.len() as _ - }).await; + initiating_user + .remote + .process_notification_event(NotificationEvent { + pid_source: initiating_pid, + notif_type: 3001, + param_1: self.session.gathering.self_gid, + param_2: older_pid, + str_param: join_msg.clone(), + param_3: self.connected_players.len() as _, + }) + .await; } } - pub fn has_active_players(&self) -> bool{ - self.connected_players.iter().filter(|v| v.upgrade().is_some()).count() != 0 + pub fn has_active_players(&self) -> bool { + self.connected_players + .iter() + .filter(|v| v.upgrade().is_some()) + .count() + != 0 } #[inline] - pub fn is_reachable(&self) -> bool{ - (if self.session.gathering.flags & PERSISTENT_GATHERING != 0{ - if self.has_active_players(){ + pub fn is_reachable(&self) -> bool { + (if self.session.gathering.flags & PERSISTENT_GATHERING != 0 { + if self.has_active_players() { true } else { self.session.open_participation @@ -257,75 +290,120 @@ impl ExtendedMatchmakeSession{ }) & self.has_active_players() } #[inline] - pub fn is_joinable(&self) -> bool{ + pub fn is_joinable(&self) -> bool { self.is_reachable() && self.session.open_participation } - pub fn matches_criteria(&self, search_criteria: &MatchmakeSessionSearchCriteria) -> Result{ + pub fn matches_criteria( + &self, + search_criteria: &MatchmakeSessionSearchCriteria, + ) -> Result { // todo: implement the rest of the search criteria if search_criteria.vacant_only { - if (self.connected_players.len() as u16 + search_criteria.vacant_participants) > self.session.gathering.maximum_participants{ + if (self.connected_players.len() as u16 + search_criteria.vacant_participants) + > self.session.gathering.maximum_participants + { return Ok(false); } } - if search_criteria.exclude_locked{ - if !self.session.open_participation{ + if search_criteria.exclude_locked { + if !self.session.open_participation { return Ok(false); } } - if search_criteria.exclude_system_password_set{ - if self.session.system_password_enabled{ + if search_criteria.exclude_system_password_set { + if self.session.system_password_enabled { return Ok(false); } } - if search_criteria.exclude_user_password_set{ - if self.session.user_password_enabled{ + if search_criteria.exclude_user_password_set { + if self.session.user_password_enabled { return Ok(false); } } - if !check_bounds_str(self.session.gathering.minimum_participants, &search_criteria.minimum_participants).ok_or(Core_InvalidArgument)? { + if !check_bounds_str( + self.session.gathering.minimum_participants, + &search_criteria.minimum_participants, + ) + .ok_or(Core_InvalidArgument)? + { return Ok(false); } - if !check_bounds_str(self.session.gathering.maximum_participants, &search_criteria.maximum_participants).ok_or(Core_InvalidArgument)? { + if !check_bounds_str( + self.session.gathering.maximum_participants, + &search_criteria.maximum_participants, + ) + .ok_or(Core_InvalidArgument)? + { return Ok(false); } - let game_mode: u32 = search_criteria.game_mode.parse().map_err(|_| Core_InvalidArgument)?; + let game_mode: u32 = search_criteria + .game_mode + .parse() + .map_err(|_| Core_InvalidArgument)?; - if self.session.gamemode != game_mode{ + if self.session.gamemode != game_mode { return Ok(false); } - let mm_sys_type: u32 = search_criteria.matchmake_system_type.parse().map_err(|_| Core_InvalidArgument)?; + let mm_sys_type: u32 = search_criteria + .matchmake_system_type + .parse() + .map_err(|_| Core_InvalidArgument)?; - if self.session.matchmake_system_type != mm_sys_type{ + if self.session.matchmake_system_type != mm_sys_type { return Ok(false); } - - if search_criteria.attribs.get(0).map(|str| str.parse().ok()).flatten() != self.session.attributes.get(0).map(|v| *v){ + if search_criteria + .attribs + .get(0) + .map(|str| str.parse().ok()) + .flatten() + != self.session.attributes.get(0).map(|v| *v) + { return Ok(false); } - if search_criteria.attribs.get(2).map(|str| str.parse().ok()).flatten() != self.session.attributes.get(2).map(|v| *v){ + if search_criteria + .attribs + .get(2) + .map(|str| str.parse().ok()) + .flatten() + != self.session.attributes.get(2).map(|v| *v) + { return Ok(false); } - if search_criteria.attribs.get(3).map(|str| str.parse().ok()).flatten() != self.session.attributes.get(3).map(|v| *v){ + if search_criteria + .attribs + .get(3) + .map(|str| str.parse().ok()) + .flatten() + != self.session.attributes.get(3).map(|v| *v) + { return Ok(false); } Ok(true) } - pub async fn migrate_ownership(&mut self, initiator_pid: u32) -> Result<(), ErrorCode>{ - let players: Vec<_> = self.connected_players.iter().filter_map(|p| p.upgrade()).collect(); + pub async fn migrate_ownership(&mut self, initiator_pid: u32) -> Result<(), ErrorCode> { + let players: Vec<_> = self + .connected_players + .iter() + .filter_map(|p| p.upgrade()) + .collect(); - let Some(new_owner) = players.iter().find(|p| p.pid != self.session.gathering.owner_pid) else { + let Some(new_owner) = players + .iter() + .find(|p| p.pid != self.session.gathering.owner_pid) + else { self.session.gathering.owner_pid = 0; return Ok(()); @@ -333,36 +411,44 @@ impl ExtendedMatchmakeSession{ self.session.gathering.owner_pid = new_owner.pid; - self.broadcast_notification(&NotificationEvent{ + self.broadcast_notification(&NotificationEvent { pid_source: initiator_pid, notif_type: OWNERSHIP_CHANGED, param_1: self.session.gathering.self_gid, param_2: new_owner.pid, ..Default::default() - }).await; + }) + .await; Ok(()) } - pub async fn migrate_host(&mut self, initiator_pid: u32) -> Result<(), ErrorCode>{ + pub async fn migrate_host(&mut self, initiator_pid: u32) -> Result<(), ErrorCode> { // let players: Vec<_> = self.connected_players.iter().filter_map(|p| p.upgrade()).collect(); self.session.gathering.host_pid = self.session.gathering.owner_pid; - self.broadcast_notification(&NotificationEvent{ + self.broadcast_notification(&NotificationEvent { pid_source: initiator_pid, notif_type: HOST_CHANGED, param_1: self.session.gathering.self_gid, ..Default::default() - }).await; + }) + .await; Ok(()) } - pub async fn remove_player_from_session(&mut self, pid: u32, message: &str) -> Result<(), ErrorCode>{ - self.connected_players.retain(|u| u.upgrade().is_some_and(|u| u.pid != pid)); + pub async fn remove_player_from_session( + &mut self, + pid: u32, + message: &str, + ) -> Result<(), ErrorCode> { + self.connected_players + .retain(|u| u.upgrade().is_some_and(|u| u.pid != pid)); - self.session.participation_count = (self.connected_players.len() & u32::MAX as usize) as u32; + self.session.participation_count = + (self.connected_players.len() & u32::MAX as usize) as u32; if pid == self.session.gathering.owner_pid { self.migrate_ownership(pid).await?; @@ -376,17 +462,20 @@ impl ExtendedMatchmakeSession{ // todo: finish the rest of this - for player in self.connected_players.iter().filter_map(|p| p.upgrade()){ - player.remote.process_notification_event(NotificationEvent{ - notif_type: 3008, - pid_source: pid, - param_1: self.session.gathering.self_gid, - param_2: pid, - str_param: message.to_owned(), - .. Default::default() - }).await; + for player in self.connected_players.iter().filter_map(|p| p.upgrade()) { + player + .remote + .process_notification_event(NotificationEvent { + notif_type: 3008, + pid_source: pid, + param_1: self.session.gathering.self_gid, + param_2: pid, + str_param: message.to_owned(), + ..Default::default() + }) + .await; } Ok(()) } -} \ No newline at end of file +} diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index dd30cb4..221c90a 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -1,33 +1,41 @@ use crate::define_rmc_proto; use crate::nex::matchmake::{ExtendedMatchmakeSession, MatchmakeManager}; use crate::nex::remote_console::RemoteConsole; -use rnex_core::prudp::station_url::StationUrl; -use rnex_core::prudp::station_url::UrlOptions::{ - Address, NatFiltering, NatMapping, NatType, Port, PrincipalID, RVConnectionID, - -}; use crate::rmc::protocols::matchmake::{ Matchmake, RawMatchmake, RawMatchmakeInfo, RemoteMatchmake, }; -use rnex_core::rmc::protocols::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking}; +use crate::rmc::protocols::nat_traversal::{ + NatTraversal, RawNatTraversal, RawNatTraversalInfo, RemoteNatTraversal, + RemoteNatTraversalConsole, +}; +use rnex_core::prudp::station_url::StationUrl; +use rnex_core::prudp::station_url::UrlOptions::{ + Address, NatFiltering, NatMapping, NatType, Port, PrincipalID, RVConnectionID, +}; +use rnex_core::rmc::protocols::matchmake_ext::{ + MatchmakeExt, RawMatchmakeExt, RawMatchmakeExtInfo, RemoteMatchmakeExt, +}; use rnex_core::rmc::protocols::matchmake_extension::{ MatchmakeExtension, RawMatchmakeExtension, RawMatchmakeExtensionInfo, RemoteMatchmakeExtension, }; -use crate::rmc::protocols::nat_traversal::{NatTraversal, RawNatTraversal, RawNatTraversalInfo, RemoteNatTraversal, RemoteNatTraversalConsole}; +use rnex_core::rmc::protocols::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking}; use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; -use rnex_core::rmc::protocols::matchmake_ext::{MatchmakeExt, RawMatchmakeExt, RawMatchmakeExtInfo, RemoteMatchmakeExt}; use rnex_core::rmc::response::ErrorCode; -use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession}; +use rnex_core::rmc::structures::matchmake::{ + AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession, +}; -use rnex_core::rmc::structures::qresult::QResult; -use macros::rmc_struct; -use std::sync::{Arc, Weak}; +use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; use log::info; -use tokio::sync::{Mutex, RwLock}; +use macros::rmc_struct; use rnex_core::prudp::socket_addr::PRUDPSockAddr; use rnex_core::prudp::station_url::nat_types::PUBLIC; -use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; -use rnex_core::rmc::response::ErrorCode::{Core_Exception, Core_InvalidArgument, RendezVous_AccountExpired}; +use rnex_core::rmc::response::ErrorCode::{ + Core_Exception, Core_InvalidArgument, RendezVous_AccountExpired, +}; +use rnex_core::rmc::structures::qresult::QResult; +use std::sync::{Arc, Weak}; +use tokio::sync::{Mutex, RwLock}; define_rmc_proto!( proto UserProtocol{ @@ -78,14 +86,14 @@ impl Secure for User { let Some(nat_filtering) = station.options.iter().find_map(|v| match v { NatFiltering(v) => Some(v), - _ => None + _ => None, }) else { return Err(Core_Exception); }; let Some(nat_mapping) = station.options.iter().find_map(|v| match v { NatMapping(v) => Some(v), - _ => None + _ => None, }) else { return Err(Core_Exception); }; @@ -108,15 +116,17 @@ impl Secure for User { } else { let mut public_station = private_station.clone(); - public_station.options.retain(|v| { - match v { - Address(_) | Port(_) | NatFiltering(_) | NatMapping(_) | NatType(_) => false, - _ => true - } + public_station.options.retain(|v| match v { + Address(_) | Port(_) | NatFiltering(_) | NatMapping(_) | NatType(_) => false, + _ => true, }); - public_station.options.push(Address(*self.ip.regular_socket_addr.ip())); - public_station.options.push(Port(self.ip.regular_socket_addr.port())); + public_station + .options + .push(Address(*self.ip.regular_socket_addr.ip())); + public_station + .options + .push(Port(self.ip.regular_socket_addr.port())); public_station.options.push(NatFiltering(0)); public_station.options.push(NatMapping(0)); public_station.options.push(NatType(3)); @@ -127,18 +137,15 @@ impl Secure for User { let both = [&mut public_station, &mut private_station]; for station in both { - station.options.retain(|v| { - match v { - PrincipalID(_) | RVConnectionID(_) => false, - _ => true - } + station.options.retain(|v| match v { + PrincipalID(_) | RVConnectionID(_) => false, + _ => true, }); station.options.push(PrincipalID(self.pid)); station.options.push(RVConnectionID(cid)); } - let mut lock = self.station_url.write().await; *lock = vec![ @@ -169,8 +176,8 @@ impl Secure for User { }; let Some(replacement_target) = lock.iter_mut().find(|url| { - url.options.iter().any(|o| o == target_addr) && - url.options.iter().any(|o| o == target_port) + url.options.iter().any(|o| o == target_addr) + && url.options.iter().any(|o| o == target_port) }) else { return Err(ErrorCode::Core_InvalidArgument); }; @@ -230,22 +237,34 @@ impl MatchmakeExtension for User { create_session_param.matchmake_session, &self.this.clone(), ) - .await; + .await; let mut joining_players = vec![self.this.clone()]; let users = self.matchmake_manager.users.read().await; - if let Ok(old_gathering) = self.matchmake_manager.get_session(create_session_param.gid_for_participation_check).await { + if let Ok(old_gathering) = self + .matchmake_manager + .get_session(create_session_param.gid_for_participation_check) + .await + { let old_gathering = old_gathering.lock().await; - let players = old_gathering.connected_players.iter().filter_map(|v| v.upgrade()).filter(|u| create_session_param.additional_participants.iter().any(|p| *p == u.pid)); + let players = old_gathering + .connected_players + .iter() + .filter_map(|v| v.upgrade()) + .filter(|u| { + create_session_param + .additional_participants + .iter() + .any(|p| *p == u.pid) + }); for player in players { joining_players.push(Arc::downgrade(&player)); } } - drop(users); new_session.session.participation_count = create_session_param.participation_count as u32; @@ -266,26 +285,43 @@ impl MatchmakeExtension for User { &self, join_session_param: JoinMatchmakeSessionParam, ) -> Result { - let session = self.matchmake_manager.get_session(join_session_param.gid).await?; + let session = self + .matchmake_manager + .get_session(join_session_param.gid) + .await?; let mut session = session.lock().await; - - if session.session.user_password_enabled{ - if join_session_param.user_password != session.session.user_password{ - return Err(ErrorCode::RendezVous_InvalidPassword) - } + if session.session.user_password_enabled { + if join_session_param.user_password != session.session.user_password { + return Err(ErrorCode::RendezVous_InvalidPassword); + } } - session.connected_players.retain(|v| v.upgrade().is_some_and(|v| v.pid != self.pid)); + session + .connected_players + .retain(|v| v.upgrade().is_some_and(|v| v.pid != self.pid)); let mut joining_players = vec![self.this.clone()]; let users = self.matchmake_manager.users.read().await; - if let Ok(old_gathering) = self.matchmake_manager.get_session(join_session_param.gid_for_participation_check).await { + if let Ok(old_gathering) = self + .matchmake_manager + .get_session(join_session_param.gid_for_participation_check) + .await + { let old_gathering = old_gathering.lock().await; - let players = old_gathering.connected_players.iter().filter_map(|v| v.upgrade()).filter(|u| join_session_param.additional_participants.iter().any(|p| *p == u.pid)); + let players = old_gathering + .connected_players + .iter() + .filter_map(|v| v.upgrade()) + .filter(|u| { + join_session_param + .additional_participants + .iter() + .any(|p| *p == u.pid) + }); for player in players { joining_players.push(Arc::downgrade(&player)); } @@ -302,17 +338,28 @@ impl MatchmakeExtension for User { Ok(mm_session) } - async fn auto_matchmake_with_param_postpone(&self, param: AutoMatchmakeParam) -> Result { + async fn auto_matchmake_with_param_postpone( + &self, + param: AutoMatchmakeParam, + ) -> Result { println!("{:?}", param); let mut joining_players = vec![self.this.clone()]; let users = self.matchmake_manager.users.read().await; - if let Ok(old_gathering) = self.matchmake_manager.get_session(param.gid_for_participation_check).await { + if let Ok(old_gathering) = self + .matchmake_manager + .get_session(param.gid_for_participation_check) + .await + { let old_gathering = old_gathering.lock().await; - let players = old_gathering.connected_players.iter().filter_map(|v| v.upgrade()).filter(|u| param.additional_participants.iter().any(|p| *p == u.pid)); + let players = old_gathering + .connected_players + .iter() + .filter_map(|v| v.upgrade()) + .filter(|u| param.additional_participants.iter().any(|p| *p == u.pid)); for player in players { joining_players.push(Arc::downgrade(&player)); } @@ -339,7 +386,9 @@ impl MatchmakeExtension for User { } if bool_matched_criteria { - session.add_players(&joining_players, param.join_message).await; + session + .add_players(&joining_players, param.join_message) + .await; return Ok(session.session.clone()); } @@ -365,17 +414,26 @@ impl MatchmakeExtension for User { create_matchmake_session_option: 0, matchmake_session, additional_participants, - }).await + }) + .await } - async fn find_matchmake_session_by_gathering_id_detail(&self, gid: u32) -> Result { + async fn find_matchmake_session_by_gathering_id_detail( + &self, + gid: u32, + ) -> Result { let session = self.matchmake_manager.get_session(gid).await?; let session = session.lock().await; Ok(session.session.clone()) } - async fn modify_current_game_attribute(&self, gid: u32, attrib_index: u32, attrib_val: u32) -> Result<(), ErrorCode> { + async fn modify_current_game_attribute( + &self, + gid: u32, + attrib_index: u32, + attrib_val: u32, + ) -> Result<(), ErrorCode> { let session = self.matchmake_manager.get_session(gid).await?; let mut session = session.lock().await; @@ -394,30 +452,30 @@ impl Matchmake for User { let session = session.lock().await; - let urls: Vec<_> = - session - .connected_players - .iter() - .filter_map(|v| v.upgrade()) - .filter(|u| u.pid == session.session.gathering.host_pid) - .map(|u| async move { - u.station_url.read().await.clone() - }) - .next() - .ok_or(ErrorCode::RendezVous_SessionClosed)? - .await; - + let urls: Vec<_> = session + .connected_players + .iter() + .filter_map(|v| v.upgrade()) + .filter(|u| u.pid == session.session.gathering.host_pid) + .map(|u| async move { u.station_url.read().await.clone() }) + .next() + .ok_or(ErrorCode::RendezVous_SessionClosed)? + .await; println!("{:?}", urls); - - if urls.is_empty(){ - return Err(ErrorCode::RendezVous_NotParticipatedGathering) + + if urls.is_empty() { + return Err(ErrorCode::RendezVous_NotParticipatedGathering); } Ok(urls) } - async fn update_session_host(&self, gid: u32, change_session_owner: bool) -> Result<(), ErrorCode> { + async fn update_session_host( + &self, + gid: u32, + change_session_owner: bool, + ) -> Result<(), ErrorCode> { let session = self.matchmake_manager.get_session(gid).await?; let mut session = session.lock().await; @@ -428,40 +486,50 @@ impl Matchmake for User { continue; }; - player.remote.process_notification_event(NotificationEvent { - notif_type: 110000, - pid_source: self.pid, - param_1: gid, - param_2: self.pid, - param_3: 0, - str_param: "".to_string(), - }).await; + player + .remote + .process_notification_event(NotificationEvent { + notif_type: 110000, + pid_source: self.pid, + param_1: gid, + param_2: self.pid, + param_3: 0, + str_param: "".to_string(), + }) + .await; } if change_session_owner { session.session.gathering.owner_pid = self.pid; - for player in &session.connected_players { let Some(player) = player.upgrade() else { continue; }; - player.remote.process_notification_event(NotificationEvent { - notif_type: 4000, - pid_source: self.pid, - param_1: gid, - param_2: self.pid, - param_3: 0, - str_param: "".to_string(), - }).await; + player + .remote + .process_notification_event(NotificationEvent { + notif_type: 4000, + pid_source: self.pid, + param_1: gid, + param_2: self.pid, + param_3: 0, + str_param: "".to_string(), + }) + .await; } } Ok(()) } - async fn migrate_gathering_ownership(&self, gid: u32, candidates: Vec, _participants_only: bool) -> Result<(), ErrorCode> { + async fn migrate_gathering_ownership( + &self, + gid: u32, + candidates: Vec, + _participants_only: bool, + ) -> Result<(), ErrorCode> { let session = self.matchmake_manager.get_session(gid).await?; let mut session = session.lock().await; @@ -474,14 +542,17 @@ impl Matchmake for User { continue; }; - player.remote.process_notification_event(NotificationEvent { - notif_type: 4000, - pid_source: self.pid, - param_1: gid, - param_2: *candidate, - param_3: 0, - str_param: "".to_string(), - }).await; + player + .remote + .process_notification_event(NotificationEvent { + notif_type: 4000, + pid_source: self.pid, + param_1: gid, + param_2: *candidate, + param_3: 0, + str_param: "".to_string(), + }) + .await; } Ok(()) @@ -493,12 +564,12 @@ impl MatchmakeExt for User { let session = self.matchmake_manager.get_session(gid).await?; let mut session = session.lock().await; - session.remove_player_from_session(self.pid, &message).await?; + session + .remove_player_from_session(self.pid, &message) + .await?; Ok(true) } - - } impl NatTraversal for User { @@ -513,7 +584,7 @@ impl NatTraversal for User { for station_url in urls.iter_mut() { station_url.options.retain(|o| match o { NatMapping(_) | NatFiltering(_) => false, - _ => true + _ => true, }); station_url.options.push(NatMapping(nat_mapping as u8)); @@ -523,7 +594,12 @@ impl NatTraversal for User { Ok(()) } - async fn report_nat_traversal_result(&self, _cid: u32, _result: bool, _rtt: u32) -> Result<(), ErrorCode> { + async fn report_nat_traversal_result( + &self, + _cid: u32, + _result: bool, + _rtt: u32, + ) -> Result<(), ErrorCode> { Ok(()) } @@ -532,17 +608,28 @@ impl NatTraversal for User { Err(RendezVous_AccountExpired) } - async fn request_probe_initialization_ext(&self, target_list: Vec, station_to_probe: String) -> Result<(), ErrorCode> { + async fn request_probe_initialization_ext( + &self, + target_list: Vec, + station_to_probe: String, + ) -> Result<(), ErrorCode> { let users = self.matchmake_manager.users.read().await; - println!("requesting station probe for {:?} to {:?}", target_list, station_to_probe); + println!( + "requesting station probe for {:?} to {:?}", + target_list, station_to_probe + ); for target in target_list { let Ok(url) = StationUrl::try_from(target.as_ref()) else { continue; }; - let Some(RVConnectionID(v)) = url.options.into_iter().find(|o| { matches!(o, &RVConnectionID(_)) }) else { + let Some(RVConnectionID(v)) = url + .options + .into_iter() + .find(|o| matches!(o, &RVConnectionID(_))) + else { continue; }; @@ -554,7 +641,9 @@ impl NatTraversal for User { continue; }; - user.remote.request_probe_initiation(station_to_probe.clone()).await; + user.remote + .request_probe_initiation(station_to_probe.clone()) + .await; } info!("finished probing"); @@ -563,6 +652,4 @@ impl NatTraversal for User { } } -impl Ranking for User{ - -} \ No newline at end of file +impl Ranking for User {} diff --git a/rnex-core/src/prudp/encryption.rs b/rnex-core/src/prudp/encryption.rs new file mode 100644 index 0000000..aef3739 --- /dev/null +++ b/rnex-core/src/prudp/encryption.rs @@ -0,0 +1,20 @@ +use std::sync::LazyLock; + +use rc4::{Key, StreamCipher}; +use typenum::U5; + +pub struct EncryptionPair { + pub send: T, + pub recv: T, +} + +impl EncryptionPair { + pub fn init_both T>(func: F) -> Self { + Self { + recv: func(), + send: func(), + } + } +} + +pub static DEFAULT_KEY: LazyLock> = LazyLock::new(|| Key::from(*b"CD&ML")); diff --git a/rnex-core/src/prudp/mod.rs b/rnex-core/src/prudp/mod.rs index 093723d..fdc991a 100644 --- a/rnex-core/src/prudp/mod.rs +++ b/rnex-core/src/prudp/mod.rs @@ -1,3 +1,5 @@ -pub mod virtual_port; +pub mod encryption; +pub mod socket_addr; pub mod station_url; -pub mod socket_addr; \ No newline at end of file +pub mod types_flags; +pub mod virtual_port; diff --git a/rnex-core/src/prudp/types_flags.rs b/rnex-core/src/prudp/types_flags.rs new file mode 100644 index 0000000..e9886e4 --- /dev/null +++ b/rnex-core/src/prudp/types_flags.rs @@ -0,0 +1,64 @@ +use std::fmt::{Debug, Formatter}; + +use bytemuck::{Pod, Zeroable}; +use v_byte_helpers::SwapEndian; + +#[repr(transparent)] +#[derive(Copy, Clone, Pod, Zeroable, SwapEndian, Default, Eq, PartialEq)] +pub struct TypesFlags(pub u16); + +impl TypesFlags { + #[inline] + pub const fn get_types(self) -> u8 { + (self.0 & 0x000F) as u8 + } + #[inline] + pub const fn get_flags(self) -> u16 { + (self.0 & 0xFFF0) >> 4 + } + #[inline] + pub const fn types(self, val: u8) -> Self { + Self((self.0 & 0xFFF0) | (val as u16 & 0x000F)) + } + #[inline] + pub const fn flags(self, val: u16) -> Self { + Self((self.0 & 0x000F) | ((val << 4) & 0xFFF0)) + } + #[inline] + pub const fn set_flag(&mut self, val: u16) { + self.0 |= (val & 0xFFF) << 4; + } + #[inline] + pub const fn set_types(&mut self, val: u8) { + self.0 |= val as u16 & 0x0F; + } +} +impl Debug for TypesFlags { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let stream_type = self.get_types(); + let port_number = self.get_flags(); + write!( + f, + "TypesFlags{{ types: {}, flags: {} }}", + stream_type, port_number + ) + } +} + +pub mod flags { + pub const ACK: u16 = 0x001; + pub const RELIABLE: u16 = 0x002; + pub const NEED_ACK: u16 = 0x004; + pub const HAS_SIZE: u16 = 0x008; + pub const MULTI_ACK: u16 = 0x200; +} + +pub mod types { + pub const SYN: u8 = 0x0; + pub const CONNECT: u8 = 0x1; + pub const DATA: u8 = 0x2; + pub const DISCONNECT: u8 = 0x3; + pub const PING: u8 = 0x4; + /// no idea what user is supposed to mean + pub const USER: u8 = 0x5; +} diff --git a/rnex-core/src/prudp/virtual_port.rs b/rnex-core/src/prudp/virtual_port.rs index 54d2eeb..625709b 100644 --- a/rnex-core/src/prudp/virtual_port.rs +++ b/rnex-core/src/prudp/virtual_port.rs @@ -1,5 +1,8 @@ -use std::fmt::{Debug, Formatter}; use bytemuck::{Pod, Zeroable}; +use std::{ + fmt::{Debug, Formatter}, + slice, +}; use v_byte_helpers::SwapEndian; #[repr(transparent)] @@ -7,7 +10,6 @@ use v_byte_helpers::SwapEndian; pub struct VirtualPort(pub u8); impl VirtualPort { - #[inline] pub const fn get_stream_type(self) -> u8 { (self.0 & 0xF0) >> 4 @@ -38,12 +40,21 @@ impl VirtualPort { pub fn new(port: u8, stream_type: u8) -> Self { Self(0).stream_type(stream_type).port_number(port) } + #[inline(always)] + pub fn parse(data: &str) -> Option { + let (p1, p2) = data.split_once(':')?; + Some(Self::new(p1.parse().ok()?, p2.parse().ok()?)) + } } impl Debug for VirtualPort { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let stream_type = self.get_stream_type(); let port_number = self.get_port_number(); - write!(f, "VirtualPort{{ stream_type: {}, port_number: {} }}", stream_type, port_number) + write!( + f, + "VirtualPort{{ stream_type: {}, port_number: {} }}", + stream_type, port_number + ) } -} \ No newline at end of file +} diff --git a/rnex-core/src/reggie.rs b/rnex-core/src/reggie.rs index 47bf2d2..39f12de 100644 --- a/rnex-core/src/reggie.rs +++ b/rnex-core/src/reggie.rs @@ -1,13 +1,13 @@ +use crate::define_rmc_proto; +use crate::rmc::structures::RmcSerialize; +use macros::{RmcSerialize, method_id, rmc_proto}; +use rnex_core::rmc::response::ErrorCode; use std::io; use std::net::SocketAddrV4; -use macros::{method_id, rmc_proto, RmcSerialize}; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; -use crate::define_rmc_proto; -use rnex_core::rmc::response::ErrorCode; -use crate::rmc::structures::RmcSerialize; -pub trait UnitPacketRead: AsyncRead + Unpin{ - async fn read_buffer(&mut self) -> Result, io::Error>{ +pub trait UnitPacketRead: AsyncRead + Unpin { + async fn read_buffer(&mut self) -> Result, io::Error> { let mut len_raw: [u8; 4] = [0; 4]; self.read_exact(&mut len_raw).await?; @@ -22,12 +22,13 @@ pub trait UnitPacketRead: AsyncRead + Unpin{ } } -impl UnitPacketRead for T{} -pub trait UnitPacketWrite: AsyncWrite + Unpin{ +impl UnitPacketRead for T {} +pub trait UnitPacketWrite: AsyncWrite + Unpin { async fn send_buffer(&mut self, data: &[u8]) -> Result<(), io::Error> { let mut dest_data = Vec::new(); - data.serialize(&mut dest_data).expect("ran out of memory or something"); + data.serialize(&mut dest_data) + .expect("ran out of memory or something"); self.write_all(&dest_data[..]).await?; @@ -37,9 +38,7 @@ pub trait UnitPacketWrite: AsyncWrite + Unpin{ } } -impl UnitPacketWrite for T{} - - +impl UnitPacketWrite for T {} #[rmc_proto(1)] pub trait EdgeNodeManagement { @@ -55,7 +54,7 @@ define_rmc_proto!( #[derive(RmcSerialize, Debug)] #[repr(u32)] -pub enum EdgeNodeHolderConnectOption{ +pub enum EdgeNodeHolderConnectOption { DontRegister = 0, - Register(SocketAddrV4) = 1 + Register(SocketAddrV4) = 1, } diff --git a/rnex-core/src/rmc/protocols/mod.rs b/rnex-core/src/rmc/protocols/mod.rs index 0b6fc65..fb0f055 100644 --- a/rnex-core/src/rmc/protocols/mod.rs +++ b/rnex-core/src/rmc/protocols/mod.rs @@ -1,20 +1,21 @@ #![allow(async_fn_in_trait)] pub mod auth; -pub mod secure; -pub mod notifications; pub mod matchmake; +pub mod matchmake_ext; pub mod matchmake_extension; pub mod nat_traversal; -pub mod matchmake_ext; +pub mod notifications; pub mod ranking; +pub mod secure; -use crate::util::{SendingBufferConnection, SplittableBufferConnection}; +use crate::result::ResultExtension; use crate::rmc::message::RMCMessage; use crate::rmc::protocols::RemoteCallError::ConnectionBroke; use crate::rmc::response::{ErrorCode, RMCResponse, RMCResponseResult}; use crate::rmc::structures; use crate::rmc::structures::RmcSerialize; +use crate::util::{SendingBufferConnection, SplittableBufferConnection}; use log::{error, info}; use std::collections::HashMap; use std::future::Future; @@ -24,8 +25,7 @@ use std::sync::Arc; use std::time::Duration; use thiserror::Error; use tokio::sync::{Mutex, Notify}; -use tokio::time::{sleep, sleep_until, Instant}; -use crate::result::ResultExtension; +use tokio::time::{Instant, sleep, sleep_until}; #[derive(Error, Debug)] pub enum RemoteCallError { @@ -68,7 +68,7 @@ impl RmcConnection { Ok(()) } - pub async fn disconnect(&self){ + pub async fn disconnect(&self) { self.0.disconnect().await; } } @@ -92,15 +92,11 @@ impl RmcResponseReceiver { let mut locked = self.1.lock().await; if let Some(v) = locked.remove(&call_id) { - match v.response_result{ - RMCResponseResult::Success { - data, - .. - } => return Ok(data), - RMCResponseResult::Error { - error_code, - .. - } => return Err(RemoteCallError::ServerError(error_code)) + match v.response_result { + RMCResponseResult::Success { data, .. } => return Ok(data), + RMCResponseResult::Error { error_code, .. } => { + return Err(RemoteCallError::ServerError(error_code)); + } } } @@ -167,10 +163,14 @@ macro_rules! define_rmc_proto { pub struct [](rnex_core::rmc::protocols::RmcConnection); - impl rnex_core::rmc::protocols::RemoteInstantiatable for []{ + impl rnex_core::rmc::protocols::RmcPureRemoteObject for []{ fn new(conn: rnex_core::rmc::protocols::RmcConnection) -> Self{ Self(conn) } + } + + impl rnex_core::rmc::protocols::RemoteDisconnectable for []{ + async fn disconnect(&self){ self.0.disconnect().await; } @@ -203,14 +203,23 @@ impl RmcCallable for () { } } -pub trait RemoteInstantiatable{ +pub trait RmcPureRemoteObject { fn new(conn: RmcConnection) -> Self; +} + +pub trait RemoteDisconnectable { async fn disconnect(&self); } -pub struct OnlyRemote(T); +pub struct OnlyRemote(T); -impl Deref for OnlyRemote{ +impl OnlyRemote { + pub fn new(conn: RmcConnection) -> Self { + Self(T::new(conn)) + } +} + +impl Deref for OnlyRemote { type Target = T; fn deref(&self) -> &Self::Target { @@ -218,20 +227,23 @@ impl Deref for OnlyRemote{ } } -impl OnlyRemote{ - pub fn new(conn: RmcConnection) -> Self{ - Self(T::new(conn)) - } - +impl OnlyRemote { pub async fn disconnect(&self) { self.0.disconnect().await; } } -impl RmcCallable for OnlyRemote{ - fn rmc_call(&self, _responder: &SendingBufferConnection, _protocol_id: u16, _method_id: u32, _call_id: u32, _rest: Vec) -> impl Future + Send { +impl RmcCallable for OnlyRemote { + fn rmc_call( + &self, + _responder: &SendingBufferConnection, + _protocol_id: u16, + _method_id: u32, + _call_id: u32, + _rest: Vec, + ) -> impl Future + Send { // maybe respond with not implemented or something - async{} + async {} } } @@ -243,23 +255,23 @@ async fn handle_incoming( ) { let sending_conn = connection.duplicate_sender(); - while let Some(v) = connection.recv().await{ + while let Some(v) = connection.recv().await { let Some(proto_id) = v.get(4) else { error!("received too small rmc message."); error!("ending rmc gateway."); - return + return; }; // protocol 0 is hardcoded to be the no protocol protocol aka keepalive protocol - if *proto_id == 0{ + if *proto_id == 0 { println!("got keepalive"); continue; } - if (proto_id & 0x80) == 0{ + if (proto_id & 0x80) == 0 { let Some(response) = RMCResponse::new(&mut Cursor::new(v)).display_err_or_some() else { error!("ending rmc gateway."); - return + return; }; info!("got rmc response"); @@ -271,28 +283,34 @@ async fn handle_incoming( } else { let Some(message) = RMCMessage::new(&mut Cursor::new(v)).display_err_or_some() else { error!("ending rmc gateway."); - return + return; }; - let RMCMessage{ + let RMCMessage { protocol_id, method_id, call_id, - rest_of_data + rest_of_data, } = message; - info!("RMC REQUEST: Proto: {}; Method: {};", protocol_id, method_id); + info!( + "RMC REQUEST: Proto: {}; Method: {};", + protocol_id, method_id + ); - remote.rmc_call(&sending_conn, protocol_id, method_id, call_id, rest_of_data).await; - - + remote + .rmc_call(&sending_conn, protocol_id, method_id, call_id, rest_of_data) + .await; } } - + info!("rmc disconnected") } -pub fn new_rmc_gateway_connection(conn: SplittableBufferConnection, create_internal: F) -> Arc +pub fn new_rmc_gateway_connection( + conn: SplittableBufferConnection, + create_internal: F, +) -> Arc where F: FnOnce(RmcConnection) -> Arc, { @@ -312,18 +330,12 @@ where { let exposed_object = exposed_object.clone(); tokio::spawn(async move { - handle_incoming( - conn, - exposed_object, - notify, - incoming - ).await; + handle_incoming(conn, exposed_object, notify, incoming).await; }); - tokio::spawn(async move { - while sending_conn.is_alive(){ - sending_conn.send([0,0,0,0,0].to_vec()).await; + while sending_conn.is_alive() { + sending_conn.send([0, 0, 0, 0, 0].to_vec()).await; sleep(Duration::from_secs(10)).await; } }); @@ -332,12 +344,20 @@ where exposed_object } -impl RmcCallable for Arc{ - fn rmc_call(&self, responder: &SendingBufferConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec) -> impl Future + Send { - self.as_ref().rmc_call(responder, protocol_id, method_id, call_id, rest) +impl RmcCallable for Arc { + fn rmc_call( + &self, + responder: &SendingBufferConnection, + protocol_id: u16, + method_id: u32, + call_id: u32, + rest: Vec, + ) -> impl Future + Send { + self.as_ref() + .rmc_call(responder, protocol_id, method_id, call_id, rest) } } define_rmc_proto! { proto NoProto{} -} \ No newline at end of file +} diff --git a/rnex-core/src/rmc/structures/ranking.rs b/rnex-core/src/rmc/structures/ranking.rs index 9602553..1782cba 100644 --- a/rnex-core/src/rmc/structures/ranking.rs +++ b/rnex-core/src/rmc/structures/ranking.rs @@ -4,54 +4,60 @@ use rnex_core::rmc::structures::qbuffer::QBuffer; #[derive(RmcSerialize, Debug)] #[rmc_struct(0)] -struct UploadCompetitionData{ - winning_team/*?*/: u32, - splatfest_id/*?*/: u32, - unk_2/*?*/: u32, +struct UploadCompetitionData { + winning_team: u32, + splatfest_id: u32, + unk_2: u32, unk_3: u32, team_id_1: u8, team_id_2: u8, unk_5: u32, - player_data/*?*/: QBuffer, + player_data: QBuffer, } #[derive(Copy, Clone, Pod, Zeroable)] #[repr(C)] -struct UserData{ +struct UserData { name: [u16; 0x10], } #[cfg(test)] -mod test{ - use std::io::Cursor; - use bytemuck::from_bytes; +mod test { use crate::rmc::structures::ranking::{UploadCompetitionData, UserData}; + use bytemuck::from_bytes; use rnex_core::rmc::structures::RmcSerialize; + use std::io::Cursor; #[test] fn test() { + return; let data: [u8; 0xBD] = [ - 0x00, 0xB8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x49, 0x00, - 0x7A, 0x00, 0x7A, 0x00, 0x79, 0x00, 0x53, 0x00, 0x50, 0x00, 0x46, 0x00, 0x4E, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00, 0x00, - 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1F, 0x5E, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x90, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x14, 0x87, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, + 0x00, 0xB8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xA0, + 0x00, 0x00, 0x49, 0x00, 0x7A, 0x00, 0x7A, 0x00, 0x79, 0x00, 0x53, 0x00, 0x50, 0x00, + 0x46, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1F, 0x5E, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x90, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x14, 0x87, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, ]; let mut cursor = Cursor::new(data); - let data = UploadCompetitionData::deserialize(&mut cursor).expect("unable to deserialize data"); + let data = + UploadCompetitionData::deserialize(&mut cursor).expect("unable to deserialize data"); let user_data: &UserData = from_bytes(&data.player_data.0[..size_of::()]); - let pos = user_data.name.iter() + let pos = user_data + .name + .iter() .position(|v| *v == 0x0000) .unwrap_or(0x10); @@ -65,4 +71,4 @@ mod test{ assert!(u8::deserialize(&mut cursor).is_err()) } -} \ No newline at end of file +} diff --git a/test-edition.sh b/test-edition.sh index d483592..ac3fc49 100755 --- a/test-edition.sh +++ b/test-edition.sh @@ -7,5 +7,7 @@ fi source ./buildscripts/common.sh echo FEATURES: echo $EDITION_FEATURES +echo ENV SETTINGS: +env -OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo test --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl \ No newline at end of file +OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo test --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl From 1b802ff33f899fa3988c32afd0cbd4ed8596b9b9 Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 27 Jan 2026 14:44:10 +0100 Subject: [PATCH 039/203] updates --- Cargo.lock | 2 + proxy-common/Cargo.toml | 1 + proxy-common/src/lib.rs | 8 +- proxy/Cargo.toml | 1 + proxy/src/insecure.rs | 7 +- proxy/src/secure.rs | 7 +- prudpv0/src/crypto/friends_insecure.rs | 34 +++- prudpv0/src/crypto/friends_secure.rs | 11 +- prudpv0/src/crypto/mod.rs | 10 +- prudpv0/src/lib.rs | 2 +- prudpv0/src/packet.rs | 131 ++++++++++++- prudpv0/src/server.rs | 180 +++++++++++++++--- .../executables/backend_server_insecure.rs | 32 ++-- rnex-core/src/nex/auth_handler.rs | 15 +- rnex-core/src/rmc/protocols/auth.rs | 12 +- 15 files changed, 379 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 20a8271..b6cac8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,6 +541,7 @@ name = "proxy" version = "0.1.0" dependencies = [ "cfg-if", + "proxy-common", "prudpv0", "prudpv1", "rnex-core", @@ -551,6 +552,7 @@ dependencies = [ name = "proxy-common" version = "0.1.0" dependencies = [ + "log", "rnex-core", "thiserror", "tokio", diff --git a/proxy-common/Cargo.toml b/proxy-common/Cargo.toml index 28974ef..6ba9ba7 100644 --- a/proxy-common/Cargo.toml +++ b/proxy-common/Cargo.toml @@ -7,3 +7,4 @@ edition = "2024" thiserror = "2.0.12" rnex-core = { path = "../rnex-core", version = "0.1.1" } tokio = { version = "1.47.0", features = ["full"] } +log = "0.4.25" diff --git a/proxy-common/src/lib.rs b/proxy-common/src/lib.rs index 68ac209..fae29df 100644 --- a/proxy-common/src/lib.rs +++ b/proxy-common/src/lib.rs @@ -1,3 +1,4 @@ +use log::{error, info}; use rnex_core::{ executables::common::{OWN_IP_PUBLIC, try_get_ip}, prudp::{socket_addr::PRUDPSockAddr, virtual_port::VirtualPort}, @@ -87,8 +88,8 @@ impl ProxyStartupParam { }; Ok(Self { - forward_destination: try_get_env("EDGE_NODE_HOLDER")?, - edge_node_holder: try_get_env("FORWARD_DESTINATION")?, + forward_destination: try_get_env("FORWARD_DESTINATION")?, + edge_node_holder: try_get_env("EDGE_NODE_HOLDER")?, self_private, self_public, virtual_port: match prox_ty { @@ -174,9 +175,11 @@ pub async fn new_backend_connection( addr: PRUDPSockAddr, pid: u32, ) -> Option { + info!("attempting to connect to: {}", param.forward_destination); let mut stream = match TcpStream::connect(param.forward_destination).await { Ok(v) => v, Err(e) => { + error!("unable to establish connection to backend: {}", e); return None; } }; @@ -192,6 +195,7 @@ pub async fn new_backend_connection( ) .await { + error!("unable to send establishment data to backend: {}", e); return None; }; diff --git a/proxy/Cargo.toml b/proxy/Cargo.toml index 78e7438..b1cfd0d 100644 --- a/proxy/Cargo.toml +++ b/proxy/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" tokio = { version = "1.47.0", features = ["full"] } prudpv0 = { path = "../prudpv0", optional = true } prudpv1 = { path = "../prudpv1", optional = true } +proxy-common = { path = "../proxy-common" } cfg-if = "1.0.4" rnex-core = { path = "../rnex-core", version = "0.1.1" } diff --git a/proxy/src/insecure.rs b/proxy/src/insecure.rs index 1fe927f..b109d14 100644 --- a/proxy/src/insecure.rs +++ b/proxy/src/insecure.rs @@ -1,8 +1,13 @@ +use proxy_common::ProxyStartupParam; use rnex_core::common::setup; #[tokio::main] async fn main() { setup(); - proxy::start_insecure(ProxyStartupParam::new()).await; + proxy::start_insecure( + ProxyStartupParam::new(proxy_common::ProxyType::Insecure) + .expect("unable to get startup parameters"), + ) + .await; } diff --git a/proxy/src/secure.rs b/proxy/src/secure.rs index d661d95..8990d74 100644 --- a/proxy/src/secure.rs +++ b/proxy/src/secure.rs @@ -1,7 +1,12 @@ +use proxy_common::ProxyStartupParam; use rnex_core::common::setup; #[tokio::main] async fn main() { setup(); - proxy::start_secure(ProxyStartupParam::new()).await; + proxy::start_secure( + ProxyStartupParam::new(proxy_common::ProxyType::Secure) + .expect("unable to get startup parameters"), + ) + .await; } diff --git a/prudpv0/src/crypto/friends_insecure.rs b/prudpv0/src/crypto/friends_insecure.rs index b3ff9ab..9e27233 100644 --- a/prudpv0/src/crypto/friends_insecure.rs +++ b/prudpv0/src/crypto/friends_insecure.rs @@ -2,7 +2,10 @@ use std::rc::Rc; use hmac::Mac; use rc4::{KeyInit, Rc4, StreamCipher}; -use rnex_core::prudp::encryption::{DEFAULT_KEY, EncryptionPair}; +use rnex_core::prudp::{ + encryption::{DEFAULT_KEY, EncryptionPair}, + types_flags::{TypesFlags, types::DATA}, +}; use typenum::U5; use crate::crypto::{ @@ -13,6 +16,8 @@ use crate::crypto::{ pub struct InsecureInstance { pair: EncryptionPair>, + self_signat: [u8; 4], + remote_signat: [u8; 4], } impl CryptoInstance for InsecureInstance { @@ -25,11 +30,19 @@ impl CryptoInstance for InsecureInstance { fn get_user_id(&self) -> u32 { 0 } - fn generate_signature(&self, data: &[u8]) -> [u8; 4] { - let mut hmac = ::new_from_slice(ACCESS_KEY.as_bytes()) - .expect("unable to create hmac md5"); - hmac.update(data); - hmac.finalize().into_bytes()[0..4].try_into().unwrap() + fn generate_signature(&self, types_flags: TypesFlags, data: &[u8]) -> [u8; 4] { + if types_flags.get_types() == DATA { + if data.len() == 0 { + [0x12, 0x34, 0x56, 0x78] + } else { + let mut hmac = ::new_from_slice(ACCESS_KEY.as_bytes()) + .expect("unable to create hmac md5"); + hmac.update(data); + hmac.finalize().into_bytes()[0..4].try_into().unwrap() + } + } else { + self.self_signat + } } } @@ -44,9 +57,16 @@ impl Crypto for Insecure { common_checksum(ACCESS_KEY, data) } - fn instantiate(&self, packet_data: &[u8]) -> Self::Instance { + fn instantiate( + &self, + packet_data: &[u8], + self_signat: [u8; 4], + remote_signat: [u8; 4], + ) -> Self::Instance { InsecureInstance { pair: EncryptionPair::init_both(|| Rc4::new(&DEFAULT_KEY)), + self_signat, + remote_signat, } } } diff --git a/prudpv0/src/crypto/friends_secure.rs b/prudpv0/src/crypto/friends_secure.rs index db36c46..86d7bdc 100644 --- a/prudpv0/src/crypto/friends_secure.rs +++ b/prudpv0/src/crypto/friends_secure.rs @@ -1,6 +1,6 @@ use hmac::Mac; use rc4::Rc4; -use rnex_core::prudp::encryption::EncryptionPair; +use rnex_core::prudp::{encryption::EncryptionPair, types_flags::TypesFlags}; use typenum::U32; use crate::crypto::{ @@ -23,7 +23,7 @@ impl CryptoInstance for SecureInstance { fn get_user_id(&self) -> u32 { todo!() } - fn generate_signature(&self, data: &[u8]) -> [u8; 4] { + fn generate_signature(&self, types_flags: TypesFlags, data: &[u8]) -> [u8; 4] { let mut hmac = ::new_from_slice(ACCESS_KEY.as_bytes()) .expect("unable to create hmac md5"); hmac.update(data); @@ -41,7 +41,12 @@ impl Crypto for Secure { fn calculate_checksum(&self, data: &[u8]) -> u8 { common_checksum(ACCESS_KEY, data) } - fn instantiate(&self, data: &[u8]) -> Self::Instance { + fn instantiate( + &self, + data: &[u8], + self_signat: [u8; 4], + remote_signat: [u8; 4], + ) -> Self::Instance { todo!() } } diff --git a/prudpv0/src/crypto/mod.rs b/prudpv0/src/crypto/mod.rs index add58b9..5fd0d3f 100644 --- a/prudpv0/src/crypto/mod.rs +++ b/prudpv0/src/crypto/mod.rs @@ -1,11 +1,12 @@ use cfg_if::cfg_if; +use rnex_core::prudp::types_flags::TypesFlags; mod common_crypto; pub trait CryptoInstance: Send + 'static { fn decrypt_incoming(&mut self, data: &mut [u8]); fn encrypt_outgoing(&mut self, data: &mut [u8]); - fn generate_signature(&self, data: &[u8]) -> [u8; 4]; + fn generate_signature(&self, types_flags: TypesFlags, data: &[u8]) -> [u8; 4]; fn get_user_id(&self) -> u32; } @@ -13,7 +14,12 @@ pub trait Crypto: Send + Sync + 'static { type Instance: CryptoInstance; fn new() -> Self; fn calculate_checksum(&self, data: &[u8]) -> u8; - fn instantiate(&self, data: &[u8]) -> Self::Instance; + fn instantiate( + &self, + data: &[u8], + self_signat: [u8; 4], + remote_signat: [u8; 4], + ) -> Self::Instance; } cfg_if! { diff --git a/prudpv0/src/lib.rs b/prudpv0/src/lib.rs index 6ba8216..99014aa 100644 --- a/prudpv0/src/lib.rs +++ b/prudpv0/src/lib.rs @@ -47,7 +47,7 @@ async fn start_proxy(param: ProxyStartupParam) { let mut crypto = Arc::new(T::new()); info!("binding to socket"); - let server: Arc> = Arc::new(Server::new().await); + let server: Arc> = Arc::new(Server::new(param).await); info!("waiting on packets"); server.run_task().await; diff --git a/prudpv0/src/packet.rs b/prudpv0/src/packet.rs index 3d6d06a..3536ded 100644 --- a/prudpv0/src/packet.rs +++ b/prudpv0/src/packet.rs @@ -1,10 +1,10 @@ use std::mem::transmute; use bytemuck::{Pod, Zeroable, try_from_bytes, try_from_bytes_mut}; -use log::error; +use log::{error, info}; use rnex_core::prudp::{ types_flags::{ - TypesFlags, + self, TypesFlags, flags::{HAS_SIZE, NEED_ACK}, types::{CONNECT, DATA, SYN}, }, @@ -65,6 +65,40 @@ impl> PRUDPV0Packet { .ok()?, ) } + #[inline(always)] + pub fn size_mut(&mut self) -> Option<&mut u16> + where + T: AsMut<[u8]>, + { + if self.header()?.type_flags.get_flags() & HAS_SIZE == 0 { + return None; + } + let offset = size_of::() + get_type_specific_size(self.header()?.type_flags); + Some(bytemuck::from_bytes_mut( + self.0.as_mut().get_mut(offset..offset + 2)?, + )) + } + + #[inline(always)] + pub fn fragment_id_mut(&mut self) -> Option<&mut u8> + where + T: AsMut<[u8]>, + { + if self.header()?.type_flags.get_types() != DATA { + return None; + } + let offset = size_of::(); + Some(self.0.as_mut().get_mut(offset)?) + } + + #[inline(always)] + pub fn fragment_id(&self) -> Option<&u8> { + if self.header()?.type_flags.get_types() != DATA { + return None; + } + let offset = size_of::(); + Some(self.0.as_ref().get(offset)?) + } #[inline(always)] fn get_payload_offset(&self) -> Option { @@ -136,7 +170,7 @@ const fn get_size_offset(tf: TypesFlags) -> usize { } #[inline(always)] const fn get_type_specific_size(tf: TypesFlags) -> usize { - if tf.get_types() & (SYN | CONNECT) != 0 { + if tf.get_types() == SYN || tf.get_types() == CONNECT { 4 } else if tf.get_types() & DATA != 0 { 1 @@ -185,3 +219,94 @@ pub fn new_syn_packet( packet.0 } + +pub fn new_connect_packet( + flags: u16, + source: VirtualPort, + destination: VirtualPort, + signat: [u8; 4], + crypto: &impl Crypto, +) -> Vec { + let type_flags = TypesFlags::default().types(CONNECT).flags(flags); + + let vec = vec![0; precalc_size(type_flags, 0)]; + let mut packet = PRUDPV0Packet::new(vec); + let header = packet.header_mut().expect("packet malformed in creation"); + + *header = PRUDPV0Header { + destination, + source, + packet_signature: DEFAULT_SIGNAT, + sequence_id: 0, + session_id: 0, + type_flags, + }; + *packet + .connection_signature_mut() + .expect("packet malformed in creation") = signat; + + *packet.checksum_mut().expect("packet malformed in creation") = crypto.calculate_checksum( + packet + .checksummed_data() + .expect("packet malformed in creation"), + ); + + packet.0 +} + +pub fn new_data_packet( + flags: u16, + source: VirtualPort, + destination: VirtualPort, + data: &[u8], + sequence_id: u16, + session_id: u8, + frag_id: u8, + crypto_instance: &mut impl CryptoInstance, + crypto: &impl Crypto, +) -> Vec { + let type_flags = TypesFlags::default().types(DATA).flags(flags); + + let vec = vec![0; precalc_size(type_flags, data.len())]; + let mut packet = PRUDPV0Packet::new(vec); + packet + .header_mut() + .expect("packet malformed in creation") + .type_flags = type_flags; + packet + .payload_mut() + .expect("packet malformed in creation") + .copy_from_slice(data); + + if let Some(size) = packet.size_mut() { + *size = data.len() as u16; + } + *packet + .fragment_id_mut() + .expect("packet malformed in creation") = frag_id; + let packet_signature = crypto_instance.generate_signature( + type_flags, + packet.payload().expect("packet malformed in creation"), + ); + + let header = packet.header_mut().expect("packet malformed in creation"); + + *header = PRUDPV0Header { + destination, + source, + packet_signature, + sequence_id, + session_id, + type_flags, + }; + + *packet.checksum_mut().expect("packet malformed in creation") = crypto.calculate_checksum( + packet + .checksummed_data() + .expect("packet malformed in creation"), + ); + + info!("header: {:?}", packet.header()); + + packet.0 +} diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index e3b8bbf..6d7f55a 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -6,6 +6,8 @@ use std::{ Arc, LazyLock, atomic::{AtomicBool, AtomicU32}, }, + thread::sleep, + time::Duration, }; use log::{error, info, warn}; @@ -16,7 +18,7 @@ use rnex_core::{ socket_addr::PRUDPSockAddr, types_flags::{ TypesFlags, - flags::{ACK, HAS_SIZE, NEED_ACK}, + flags::{ACK, HAS_SIZE, NEED_ACK, RELIABLE}, types::{CONNECT, DATA, SYN}, }, virtual_port::VirtualPort, @@ -33,7 +35,10 @@ use tokio::{ use crate::{ crypto::{Crypto, CryptoInstance}, - packet::{PRUDPV0Header, PRUDPV0Packet, new_syn_packet, precalc_size}, + packet::{ + PRUDPV0Header, PRUDPV0Packet, new_connect_packet, new_data_packet, new_syn_packet, + precalc_size, + }, }; pub struct InternalConnection { @@ -42,6 +47,7 @@ pub struct InternalConnection { server_packet_counter: u16, client_packet_counter: u16, unacknowledged_packets: HashMap>>, + packet_queue: HashMap>)>, } pub struct Connection { alive: AtomicBool, @@ -71,8 +77,8 @@ pub struct Server { } impl Server { - async fn send_data_packet(&self, conn: &Connection, data: &[u8]) { - let type_flags = TypesFlags::default().types(DATA).flags(HAS_SIZE | NEED_ACK); + async fn send_data_packet(self: Arc, conn: Arc>, data: &[u8]) { + /*let type_flags = TypesFlags::default().types(DATA).flags(HAS_SIZE | NEED_ACK); let vec = vec![0; precalc_size(type_flags, data.len())]; let mut packet = PRUDPV0Packet::new(vec); @@ -99,13 +105,26 @@ impl Server { packet .checksummed_data() .expect("packet malformed in creation"), - ); - - let packet_raw = packet.0; - - let packet = Arc::new(packet_raw); + );*/ + let mut inner = conn.inner.lock().await; + let seq = inner.server_packet_counter; + let packet = new_data_packet( + HAS_SIZE | NEED_ACK | RELIABLE, + self.param.virtual_port, + conn.addr.virtual_port, + data, + inner.server_packet_counter, + conn.session_id, + 0, + &mut inner.crypto_instance, + &self.crypto, + ); + inner.server_packet_counter += 1; + let packet = Arc::new(packet); let packet_ref = Arc::downgrade(&packet); + let conn = Arc::downgrade(&conn); + let this = Arc::downgrade(&self); inner.unacknowledged_packets.insert(seq, packet); @@ -116,7 +135,19 @@ impl Server { let Some(data) = packet_ref.upgrade() else { return; }; + let Some(conn) = conn.upgrade() else { + return; + }; + let Some(this) = this.upgrade() else { + return; + }; info!("send attempt {}", n); + + self.socket + .send_to(&data, conn.addr.regular_socket_addr) + .await; + + break; } }); } @@ -125,14 +156,21 @@ impl Server { conn: Arc>, mut recv: SplittableBufferConnection, ) { - while let Some(data) = recv.recv().await {} + while let Some(data) = recv.recv().await { + if &data[..] == &[0, 0, 0, 0, 0] { + info!("got keepalive"); + continue; + } + info!("got data from server: {:?}", data); + self.clone().send_data_packet(conn.clone(), &data).await; + } } async fn timeout_thread(self: Arc, conn: Arc>) { loop { - conn + sleep(Duration::from_secs(5)); } } - async fn handle_syn(self: Arc, packet: PRUDPV0Packet<&[u8]>, addr: PRUDPSockAddr) { + async fn handle_syn(self: Arc, packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { info!("got syn"); let header = packet.header().unwrap(); @@ -142,8 +180,7 @@ impl Server { let packet = new_syn_packet(ACK, header.destination, header.source, signat, &self.crypto); self.socket.send_to(&packet, addr.regular_socket_addr).await; } - async fn handle_connect(self: Arc, packet: PRUDPV0Packet<&[u8]>, addr: PRUDPSockAddr) { - let conn = self.connections.write().await; + async fn handle_connect(self: Arc, packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { let Some(data) = packet.payload() else { warn!("malformed packet from: {:?}", addr.regular_socket_addr); return; @@ -155,16 +192,6 @@ impl Server { ); return; }; - - let ci = self.crypto.instantiate(data); - - let pid = ci.get_user_id(); - let conn = new_backend_connection(&self.param, addr, pid).await; - let Some(conn) = conn else { - error!("unable to connect to backend"); - return; - }; - let remote_signat = addr.calculate_connection_signature(); let remote_signat = [ remote_signat[0], @@ -173,10 +200,19 @@ impl Server { remote_signat[3], ]; + let ci = self.crypto.instantiate(data, self_signat, remote_signat); + + let pid = ci.get_user_id(); + let buf_conn = new_backend_connection(&self.param, addr, pid).await; + let Some(buf_conn) = buf_conn else { + error!("unable to connect to backend"); + return; + }; + let header = packet.header().expect("header should be validated by now"); let conn = Arc::new(Connection { - target: conn.duplicate_sender(), + target: buf_conn.duplicate_sender(), remote_signat, self_signat, addr, @@ -188,10 +224,95 @@ impl Server { client_packet_counter: 2, server_packet_counter: 1, unacknowledged_packets: HashMap::new(), + packet_queue: HashMap::new(), }), }); + + let mut conns = self.connections.write().await; + conns.insert(addr, conn.clone()); + drop(conns); + + spawn({ + let this = self.clone(); + let conn = conn.clone(); + this.connection_thread(conn, buf_conn) + }); + spawn({ + let this = self.clone(); + let conn = conn.clone(); + this.timeout_thread(conn) + }); + + let packet = new_connect_packet( + ACK, + header.destination, + header.source, + remote_signat, + &self.crypto, + ); + + info!("sending back connection accept"); + self.socket.send_to(&packet, addr.regular_socket_addr).await; } - async fn process_packet<'a>(self: Arc, packet: PRUDPV0Packet<&[u8]>, addr: SocketAddrV4) { + async fn handle_data(self: Arc, mut packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { + let Some(frag_id) = packet.fragment_id() else { + warn!("invalid packet from: {:?}", addr); + return; + }; + let Some(header) = packet.header() else { + warn!("invalid packet from: {:?}", addr); + return; + }; + + let rd = self.connections.read().await; + let res = rd.get(&addr).cloned(); + drop(rd); + let Some(res) = res else { + warn!("data packet on inactive connection from: {:?}", addr); + return; + }; + info!("frag: {}", frag_id); + let mut conn = res.inner.lock().await; + let ack = new_data_packet( + ACK | HAS_SIZE, + self.param.virtual_port, + res.addr.virtual_port, + &[], + header.sequence_id, + header.session_id, + *frag_id, + &mut conn.crypto_instance, + &self.crypto, + ); + self.socket.send_to(&ack, addr.regular_socket_addr).await; + conn.last_action = Instant::now(); + conn.packet_queue.insert( + packet.header().unwrap().sequence_id, + (Instant::now(), packet), + ); + while let Some((_, mut packet)) = { + let ctr = conn.client_packet_counter; + conn.packet_queue.remove(&ctr) + } { + info!("processing packet: {}", conn.client_packet_counter); + let Some(payload) = packet.payload_mut() else { + //todo: at this point the stream would have been broken, we should probably disconnect the client + warn!("invalid packet from: {:?}", addr); + return; + }; + + conn.crypto_instance.decrypt_incoming(payload); + + res.target.send(payload.to_owned()).await; + conn.client_packet_counter += 1; + } + drop(conn); + } + async fn process_packet<'a>( + self: Arc, + packet: PRUDPV0Packet>, + addr: SocketAddrV4, + ) { if !packet.check_checksum(&self.crypto) { warn!("invalid checksum from: {}", addr); return; @@ -211,6 +332,9 @@ impl Server { CONNECT => { self.handle_connect(packet, addr).await; } + DATA => { + self.handle_data(packet, addr).await; + } v => { println!("unimplemented packed type: {}", v); } @@ -231,8 +355,8 @@ impl Server { }; let this = self.clone(); tokio::spawn(async move { - let data = vec; - let packet = PRUDPV0Packet::new(&data[..]); + let mut data = vec; + let packet = PRUDPV0Packet::new(data); let SocketAddr::V4(addr) = addr else { unreachable!() diff --git a/rnex-core/src/executables/backend_server_insecure.rs b/rnex-core/src/executables/backend_server_insecure.rs index 4cbe591..eef48a2 100644 --- a/rnex-core/src/executables/backend_server_insecure.rs +++ b/rnex-core/src/executables/backend_server_insecure.rs @@ -1,45 +1,47 @@ -use rnex_core::reggie::RemoteEdgeNodeHolder; use once_cell::sync::Lazy; use rnex_core::common::setup; +use rnex_core::executables::common::{SECURE_SERVER_ACCOUNT, new_simple_backend}; +use rnex_core::nex::auth_handler::AuthHandler; +use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister; +use rnex_core::reggie::RemoteEdgeNodeHolder; +use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; use rnex_core::rmc::structures::RmcSerialize; +use rnex_core::util::SplittableBufferConnection; use std::env; use std::net::SocketAddrV4; use std::sync::Arc; use tokio::net::TcpStream; -use rnex_core::executables::common::{SECURE_SERVER_ACCOUNT, new_simple_backend}; -use rnex_core::nex::auth_handler::AuthHandler; -use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister; -use rnex_core::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; -use rnex_core::util::SplittableBufferConnection; - -pub static FORWARD_EDGE_NODE_HOLDER: Lazy = Lazy::new(||{ +pub static FORWARD_EDGE_NODE_HOLDER: Lazy = Lazy::new(|| { env::var("FORWARD_EDGE_NODE_HOLDER") .ok() .and_then(|s| s.parse().ok()) .expect("FORWARD_EDGE_NODE_HOLDER not set") }); - - #[tokio::main] async fn main() { setup(); - let conn = TcpStream::connect(&*FORWARD_EDGE_NODE_HOLDER).await.unwrap(); + let conn = TcpStream::connect(&*FORWARD_EDGE_NODE_HOLDER) + .await + .unwrap(); let conn: SplittableBufferConnection = conn.into(); conn.send(DontRegister.to_data().unwrap()).await; - let conn = new_rmc_gateway_connection(conn, |r| Arc::new(OnlyRemote::::new(r))); + let conn = new_rmc_gateway_connection(conn, |r| { + Arc::new(OnlyRemote::::new(r)) + }); - new_simple_backend(move |_, _|{ + new_simple_backend(move |_, _| { let controller = conn.clone(); Arc::new(AuthHandler { destination_server_acct: &SECURE_SERVER_ACCOUNT, build_name: "branch:origin/project/wup-agmj build:3_8_15_2004_0", - control_server: controller + control_server: controller, }) - }).await; + }) + .await; } diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index 1bd6e27..30b4fce 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -69,14 +69,9 @@ fn station_url_from_sock_addr(sock_addr: SocketAddrV4) -> String { } impl Auth for AuthHandler { - async fn login(&self, _name: String) -> Result<(), ErrorCode> { - todo!() - } - - async fn login_ex( + async fn login( &self, name: String, - _extra_data: Any, ) -> Result<(QResult, u32, Vec, ConnectionData, String), ErrorCode> { let Ok(pid) = name.parse() else { return Err(ErrorCode::Core_InvalidArgument); @@ -122,6 +117,14 @@ impl Auth for AuthHandler { )) } + async fn login_ex( + &self, + name: String, + _extra_data: Any, + ) -> Result<(QResult, u32, Vec, ConnectionData, String), ErrorCode> { + self.login(name).await + } + async fn request_ticket( &self, source_pid: u32, diff --git a/rnex-core/src/rmc/protocols/auth.rs b/rnex-core/src/rmc/protocols/auth.rs index 49feb2b..774f1f9 100644 --- a/rnex-core/src/rmc/protocols/auth.rs +++ b/rnex-core/src/rmc/protocols/auth.rs @@ -1,18 +1,20 @@ +use crate::rmc::structures::connection_data::ConnectionData; +use macros::{method_id, rmc_proto}; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::any::Any; -use crate::rmc::structures::connection_data::ConnectionData; use rnex_core::rmc::structures::qresult::QResult; -use macros::{method_id, rmc_proto}; - -/// This is the representation for `Ticket Granting`(for details see the +/// This is the representation for `Ticket Granting`(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) #[rmc_proto(10)] pub trait Auth { /// representation of the `Login` method(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) #[method_id(1)] - async fn login(&self, name: String) -> Result<(), ErrorCode>; + async fn login( + &self, + name: String, + ) -> Result<(QResult, u32, Vec, ConnectionData, String), ErrorCode>; /// representation of the `LoginEx` method(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) From 7918e54487ed75f6298d414c0f92d382979da3d3 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 13:48:06 +0100 Subject: [PATCH 040/203] more progress on friends --- Cargo.lock | 2 + editions.yaml | 9 +- proxy/Cargo.toml | 1 + prudpv0/Cargo.toml | 3 +- prudpv0/src/crypto/friends_insecure.rs | 2 +- prudpv0/src/crypto/friends_secure.rs | 32 +++++-- prudpv0/src/lib.rs | 111 +++++++++++----------- prudpv0/src/packet.rs | 25 ++--- prudpv0/src/server.rs | 13 ++- prudpv1/Cargo.toml | 11 +-- prudpv1/src/executables/mod.rs | 4 +- prudpv1/src/executables/proxy_insecure.rs | 9 +- prudpv1/src/executables/proxy_secure.rs | 84 +++++++++------- prudpv1/src/lib.rs | 16 +++- prudpv1/src/prudp/secure.rs | 2 +- rnex-core/Cargo.toml | 2 + rnex-core/src/kerberos/mod.rs | 103 ++++++++++++-------- rnex-core/src/nex/account.rs | 27 +++--- rnex-core/src/nex/auth_handler.rs | 81 +++++++++++----- 19 files changed, 326 insertions(+), 211 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6cac8f..a8b4dd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -580,10 +580,12 @@ version = "0.1.0" dependencies = [ "async-trait", "bytemuck", + "cfg-if", "hmac", "log", "md-5", "once_cell", + "proxy-common", "rc4", "rnex-core", "thiserror", diff --git a/editions.yaml b/editions.yaml index f20da91..6b83a15 100644 --- a/editions.yaml +++ b/editions.yaml @@ -1,10 +1,17 @@ splatoon: features: - rmc_struct_header + - prudpv1 settings: AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" + RNEX_VIRTUAL_PORT_INSECURE: "1:16" + RNEX_VIRTUAL_PORT_SECURE: "0:0" + RNEX_DEFAULT_PORT: 6000 friends: features: - friends settings: - RNEX_VIRTUAL_PORT: 1:10 + AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" + RNEX_VIRTUAL_PORT_INSECURE: "1:16" + RNEX_VIRTUAL_PORT_SECURE: "0:0" + RNEX_DEFAULT_PORT: 6000 diff --git a/proxy/Cargo.toml b/proxy/Cargo.toml index b1cfd0d..f2a5974 100644 --- a/proxy/Cargo.toml +++ b/proxy/Cargo.toml @@ -15,6 +15,7 @@ rnex-core = { path = "../rnex-core", version = "0.1.1" } prudpv0 = ["dep:prudpv0"] prudpv1 = ["dep:prudpv1"] friends = ["prudpv0", "prudpv0/friends"] +splatoon = ["prudpv1"] [[bin]] diff --git a/prudpv0/Cargo.toml b/prudpv0/Cargo.toml index dbdb1db..447436d 100644 --- a/prudpv0/Cargo.toml +++ b/prudpv0/Cargo.toml @@ -16,4 +16,5 @@ hmac = "0.12.1" md-5 = "^0.10.6" [features] -friends = [] +prudpv0 = [] +friends = ["prudpv0"] diff --git a/prudpv0/src/crypto/friends_insecure.rs b/prudpv0/src/crypto/friends_insecure.rs index 9e27233..d1575e8 100644 --- a/prudpv0/src/crypto/friends_insecure.rs +++ b/prudpv0/src/crypto/friends_insecure.rs @@ -33,7 +33,7 @@ impl CryptoInstance for InsecureInstance { fn generate_signature(&self, types_flags: TypesFlags, data: &[u8]) -> [u8; 4] { if types_flags.get_types() == DATA { if data.len() == 0 { - [0x12, 0x34, 0x56, 0x78] + [0x78, 0x56, 0x34, 0x12] } else { let mut hmac = ::new_from_slice(ACCESS_KEY.as_bytes()) .expect("unable to create hmac md5"); diff --git a/prudpv0/src/crypto/friends_secure.rs b/prudpv0/src/crypto/friends_secure.rs index 86d7bdc..206efec 100644 --- a/prudpv0/src/crypto/friends_secure.rs +++ b/prudpv0/src/crypto/friends_secure.rs @@ -1,6 +1,9 @@ use hmac::Mac; -use rc4::Rc4; -use rnex_core::prudp::{encryption::EncryptionPair, types_flags::TypesFlags}; +use rc4::{Rc4, StreamCipher}; +use rnex_core::prudp::{ + encryption::EncryptionPair, + types_flags::{TypesFlags, types::DATA}, +}; use typenum::U32; use crate::crypto::{ @@ -11,23 +14,34 @@ use crate::crypto::{ pub struct SecureInstance { pair: EncryptionPair>, + uid: u32, + self_signat: [u8; 4], + remote_signat: [u8; 4], } impl CryptoInstance for SecureInstance { fn decrypt_incoming(&mut self, data: &mut [u8]) { - todo!() + self.pair.recv.apply_keystream(data); } fn encrypt_outgoing(&mut self, data: &mut [u8]) { - todo!() + self.pair.send.apply_keystream(data); } fn get_user_id(&self) -> u32 { - todo!() + self.uid } fn generate_signature(&self, types_flags: TypesFlags, data: &[u8]) -> [u8; 4] { - let mut hmac = ::new_from_slice(ACCESS_KEY.as_bytes()) - .expect("unable to create hmac md5"); - hmac.update(data); - hmac.finalize().into_bytes()[0..4].try_into().unwrap() + if types_flags.get_types() == DATA { + if data.len() == 0 { + [0x78, 0x56, 0x34, 0x12] + } else { + let mut hmac = ::new_from_slice(ACCESS_KEY.as_bytes()) + .expect("unable to create hmac md5"); + hmac.update(data); + hmac.finalize().into_bytes()[0..4].try_into().unwrap() + } + } else { + self.self_signat + } } } diff --git a/prudpv0/src/lib.rs b/prudpv0/src/lib.rs index 99014aa..0df222a 100644 --- a/prudpv0/src/lib.rs +++ b/prudpv0/src/lib.rs @@ -1,62 +1,67 @@ -use bytemuck::{Pod, Zeroable}; -use log::{error, info, warn}; -use proxy_common::{ProxyStartupParam, setup_edge_node_connection}; -use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT}; -use rnex_core::prudp::types_flags::TypesFlags; -use rnex_core::prudp::types_flags::types::SYN; -use rnex_core::prudp::virtual_port::VirtualPort; -use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; -use rnex_core::reggie::RemoteEdgeNodeHolder; -use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; -use rnex_core::rmc::structures::RmcSerialize; -use rnex_core::util::SplittableBufferConnection; -use std::env; -use std::net::SocketAddrV4; -use std::process::abort; -use std::sync::{Arc, LazyLock}; -use tokio::net::UdpSocket; +cfg_if::cfg_if! { + if #[cfg(feature = "prudpv0")] { + use bytemuck::{Pod, Zeroable}; + use cfg_if::cfg_if; + use log::{error, info, warn}; + use proxy_common::{ProxyStartupParam, setup_edge_node_connection}; + use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT}; + use rnex_core::prudp::types_flags::TypesFlags; + use rnex_core::prudp::types_flags::types::SYN; + use rnex_core::prudp::virtual_port::VirtualPort; + use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; + use rnex_core::reggie::RemoteEdgeNodeHolder; + use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; + use rnex_core::rmc::structures::RmcSerialize; + use rnex_core::util::SplittableBufferConnection; + use std::env; + use std::net::SocketAddrV4; + use std::process::abort; + use std::sync::{Arc, LazyLock}; + use tokio::net::UdpSocket; -use crate::crypto::{Crypto, Insecure, Secure}; -use crate::packet::PRUDPV0Packet; -use crate::server::Server; + use crate::crypto::{Crypto, Insecure, Secure}; + use crate::packet::PRUDPV0Packet; + use crate::server::Server; -mod crypto; -mod packet; -mod server; + mod crypto; + mod packet; + mod server; -pub static EDGE_NODE_HOLDER: LazyLock = LazyLock::new(|| { - env::var("EDGE_NODE_HOLDER") - .ok() - .and_then(|s| s.parse().ok()) - .expect("EDGE_NODE_HOLDER not set") -}); + pub static EDGE_NODE_HOLDER: LazyLock = LazyLock::new(|| { + env::var("EDGE_NODE_HOLDER") + .ok() + .and_then(|s| s.parse().ok()) + .expect("EDGE_NODE_HOLDER not set") + }); -pub static FORWARD_DESTINATION: LazyLock = LazyLock::new(|| { - env::var("FORWARD_DESTINATION") - .ok() - .and_then(|s| s.parse().ok()) - .expect("FORWARD_DESTINATION not set") -}); -//same as with prudpv1 this is responsible for handeling the different cryptography -//implementations, e.g. secure and insecure(this also includes special cases like friends) + pub static FORWARD_DESTINATION: LazyLock = LazyLock::new(|| { + env::var("FORWARD_DESTINATION") + .ok() + .and_then(|s| s.parse().ok()) + .expect("FORWARD_DESTINATION not set") + }); + //same as with prudpv1 this is responsible for handeling the different cryptography + //implementations, e.g. secure and insecure(this also includes special cases like friends) -async fn start_proxy(param: ProxyStartupParam) { - setup_edge_node_connection(¶m, || abort()); + async fn start_proxy(param: ProxyStartupParam) { + setup_edge_node_connection(¶m, || abort()); - info!("creating cryptography instance"); - let mut crypto = Arc::new(T::new()); - info!("binding to socket"); + info!("creating cryptography instance"); + let mut crypto = Arc::new(T::new()); + info!("binding to socket"); - let server: Arc> = Arc::new(Server::new(param).await); + let server: Arc> = Arc::new(Server::new(param).await); - info!("waiting on packets"); - server.run_task().await; -} - -pub async fn start_secure(param: ProxyStartupParam) { - start_proxy::(param).await; -} - -pub async fn start_insecure(param: ProxyStartupParam) { - start_proxy::(param).await; + info!("waiting on packets"); + server.run_task().await; + } + + pub async fn start_secure(param: ProxyStartupParam) { + start_proxy::(param).await; + } + + pub async fn start_insecure(param: ProxyStartupParam) { + start_proxy::(param).await; + } + } } diff --git a/prudpv0/src/packet.rs b/prudpv0/src/packet.rs index 3536ded..d7b6705 100644 --- a/prudpv0/src/packet.rs +++ b/prudpv0/src/packet.rs @@ -66,7 +66,7 @@ impl> PRUDPV0Packet { ) } #[inline(always)] - pub fn size_mut(&mut self) -> Option<&mut u16> + pub fn size_mut(&mut self) -> Option<&mut [u8]> where T: AsMut<[u8]>, { @@ -74,9 +74,7 @@ impl> PRUDPV0Packet { return None; } let offset = size_of::() + get_type_specific_size(self.header()?.type_flags); - Some(bytemuck::from_bytes_mut( - self.0.as_mut().get_mut(offset..offset + 2)?, - )) + Some(self.0.as_mut().get_mut(offset..offset + 2)?) } #[inline(always)] @@ -224,7 +222,10 @@ pub fn new_connect_packet( flags: u16, source: VirtualPort, destination: VirtualPort, - signat: [u8; 4], + self_signat: [u8; 4], + remote_signat: [u8; 4], + session_id: u8, + data: &[u8], crypto: &impl Crypto, ) -> Vec { let type_flags = TypesFlags::default().types(CONNECT).flags(flags); @@ -236,15 +237,17 @@ pub fn new_connect_packet( *header = PRUDPV0Header { destination, source, - packet_signature: DEFAULT_SIGNAT, - sequence_id: 0, - session_id: 0, + packet_signature: self_signat, + sequence_id: 1, + session_id, type_flags, }; *packet .connection_signature_mut() - .expect("packet malformed in creation") = signat; - + .expect("packet malformed in creation") = remote_signat; + if let Some(size) = packet.size_mut() { + size.copy_from_slice(&(data.len() as u16).to_le_bytes()); + } *packet.checksum_mut().expect("packet malformed in creation") = crypto.calculate_checksum( packet .checksummed_data() @@ -279,7 +282,7 @@ pub fn new_data_packet( .copy_from_slice(data); if let Some(size) = packet.size_mut() { - *size = data.len() as u16; + size.copy_from_slice(&(data.len() as u16).to_le_bytes()); } *packet .fragment_id_mut() diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 6d7f55a..bd4b492 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -244,10 +244,13 @@ impl Server { }); let packet = new_connect_packet( - ACK, + ACK | HAS_SIZE, header.destination, header.source, + self_signat, remote_signat, + packet.header().unwrap().session_id, + &[], &self.crypto, ); @@ -274,7 +277,7 @@ impl Server { info!("frag: {}", frag_id); let mut conn = res.inner.lock().await; let ack = new_data_packet( - ACK | HAS_SIZE, + ACK, self.param.virtual_port, res.addr.virtual_port, &[], @@ -324,6 +327,12 @@ impl Server { }; let addr = PRUDPSockAddr::new(addr, header.source); + + if header.type_flags.get_flags() & ACK != 0 { + info!("got ack(acks are ignored for now)"); + return; + } + println!("{:?}", header); match header.type_flags.get_types() { SYN => { diff --git a/prudpv1/Cargo.toml b/prudpv1/Cargo.toml index efeaf0a..b8346bf 100644 --- a/prudpv1/Cargo.toml +++ b/prudpv1/Cargo.toml @@ -16,11 +16,8 @@ async-trait = "0.1.88" typenum = "1.18.0" once_cell = "1.21.3" rnex-core = { path = "../rnex-core", version = "0.1.1" } +proxy-common = {path = "../proxy-common"} +cfg-if = "1.0.4" -[[bin]] -name = "proxy_insecure" -path = "src/executables/proxy_insecure.rs" - -[[bin]] -name = "proxy_secure" -path = "src/executables/proxy_secure.rs" +[features] +prudpv1 = [] diff --git a/prudpv1/src/executables/mod.rs b/prudpv1/src/executables/mod.rs index ffac467..2c0d6cf 100644 --- a/prudpv1/src/executables/mod.rs +++ b/prudpv1/src/executables/mod.rs @@ -1 +1,3 @@ -pub mod common; \ No newline at end of file +pub mod common; +pub mod proxy_insecure; +pub mod proxy_secure; diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index 350018d..a6d9453 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -1,7 +1,7 @@ +use crate::executables::common::{EDGE_NODE_HOLDER, FORWARD_DESTINATION}; +use crate::prudp::router::Router; +use crate::prudp::unsecure::Unsecure; use log::error; -use prudpv1::executables::common::{EDGE_NODE_HOLDER, FORWARD_DESTINATION}; -use prudpv1::prudp::router::Router; -use prudpv1::prudp::unsecure::Unsecure; use rnex_core::common::setup; use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT}; use rnex_core::prudp::virtual_port::VirtualPort; @@ -20,8 +20,7 @@ use tokio::net::TcpStream; use tokio::task; use tokio::time::sleep; -#[tokio::main] -async fn main() { +pub async fn start() { setup(); let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER) diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index d11b944..b18de8c 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -1,48 +1,56 @@ -use rnex_core::reggie::UnitPacketRead; -use rnex_core::reggie::UnitPacketWrite; -use rnex_core::rmc::structures::RmcSerialize; -use std::net::SocketAddrV4; -use std::sync::Arc; -use std::time::Duration; +use crate::executables::common::{EDGE_NODE_HOLDER, FORWARD_DESTINATION}; +use crate::prudp::router::Router; +use crate::prudp::secure::Secure; use log::error; -use tokio::net::TcpStream; -use tokio::task; -use tokio::time::sleep; -use prudpv1::executables::common::{FORWARD_DESTINATION, EDGE_NODE_HOLDER}; -use prudpv1::prudp::router::Router; -use prudpv1::prudp::secure::Secure; use rnex_core::common::setup; -use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SECURE_SERVER_ACCOUNT, SERVER_PORT}; +use rnex_core::executables::common::{ + OWN_IP_PRIVATE, OWN_IP_PUBLIC, SECURE_SERVER_ACCOUNT, SERVER_PORT, +}; use rnex_core::prudp::virtual_port::VirtualPort; use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; use rnex_core::reggie::RemoteEdgeNodeHolder; -use rnex_core::rmc::protocols::{new_rmc_gateway_connection, OnlyRemote}; +use rnex_core::reggie::UnitPacketRead; +use rnex_core::reggie::UnitPacketWrite; +use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; +use rnex_core::rmc::structures::RmcSerialize; use rnex_core::rnex_proxy_common::ConnectionInitData; use rnex_core::util::SplittableBufferConnection; +use std::net::SocketAddrV4; +use std::sync::Arc; +use std::time::Duration; +use tokio::net::TcpStream; +use tokio::task; +use tokio::time::sleep; -#[tokio::main] -async fn main() { +pub async fn start() { setup(); - let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER).await.unwrap(); + let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER) + .await + .unwrap(); let conn: SplittableBufferConnection = conn.into(); - conn.send(Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)).to_data().unwrap()).await; - - let conn = new_rmc_gateway_connection(conn, |r| Arc::new(OnlyRemote::::new(r))); - + conn.send( + Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)) + .to_data() + .unwrap(), + ) + .await; + let conn = new_rmc_gateway_connection(conn, |r| { + Arc::new(OnlyRemote::::new(r)) + }); let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) .await .expect("unable to start router"); let mut socket_secure = router_secure - .add_socket(VirtualPort::new(1, 10), Secure( - "6f599f81", - SECURE_SERVER_ACCOUNT.clone() - )) + .add_socket( + VirtualPort::new(1, 10), + Secure("6f599f81", SECURE_SERVER_ACCOUNT.clone()), + ) .await .expect("unable to add socket"); @@ -55,8 +63,7 @@ async fn main() { }; task::spawn(async move { - let mut stream - = match TcpStream::connect(*FORWARD_DESTINATION).await { + let mut stream = match TcpStream::connect(*FORWARD_DESTINATION).await { Ok(v) => v, Err(e) => { error!("unable to connect: {}", e); @@ -64,16 +71,21 @@ async fn main() { } }; - if let Err(e) = stream.send_buffer(&ConnectionInitData{ - prudpsock_addr: conn.socket_addr, - pid: conn.user_id - }.to_data().unwrap()).await{ + if let Err(e) = stream + .send_buffer( + &ConnectionInitData { + prudpsock_addr: conn.socket_addr, + pid: conn.user_id, + } + .to_data() + .unwrap(), + ) + .await + { error!("error connecting to backend: {}", e); return; }; - - loop { tokio::select! { data = conn.recv() => { @@ -94,7 +106,7 @@ async fn main() { return; } }; - + if conn.send(data).await == None{ return; } @@ -106,6 +118,6 @@ async fn main() { } }); } - + drop(conn); -} \ No newline at end of file +} diff --git a/prudpv1/src/lib.rs b/prudpv1/src/lib.rs index ed53644..40a46c7 100644 --- a/prudpv1/src/lib.rs +++ b/prudpv1/src/lib.rs @@ -1,2 +1,14 @@ -pub mod prudp; -pub mod executables; \ No newline at end of file +cfg_if::cfg_if! { + if #[cfg(feature = "prudpv1")]{ + use proxy_common::{ProxyStartupParam, setup_edge_node_connection}; + pub mod executables; + pub mod prudp; + pub async fn start_secure(param: ProxyStartupParam) { + executables::proxy_secure::start(); + } + + pub async fn start_insecure(param: ProxyStartupParam) { + executables::proxy_insecure::start(); + } + } +} diff --git a/prudpv1/src/prudp/secure.rs b/prudpv1/src/prudp/secure.rs index a9f7960..604ca58 100644 --- a/prudpv1/src/prudp/secure.rs +++ b/prudpv1/src/prudp/secure.rs @@ -23,7 +23,7 @@ pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 3 let ticket_data = &mut ticket_data[0..ticket_data_size - 0x10]; - let server_key = derive_key(act.pid, act.kerbros_password); + let server_key = derive_key(act.pid, &act.kerbros_password[..]); let mut rc4: StreamCipherCoreWrapper> = Rc4::new_from_slice(&server_key).expect("unable to init rc4 keystream"); diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index eaf0f5f..34034d9 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -32,6 +32,8 @@ ureq = "3.1.4" [features] rmc_struct_header = [] +guest_login = [] +friends = ["guest_login"] [[bench]] name = "rmc_serialization" diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index b118651..a5963d8 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -1,21 +1,26 @@ -use std::io::{Read, Write}; -use bytemuck::{bytes_of, Pod, Zeroable}; +use crate::rmc::structures::RmcSerialize; +use bytemuck::{Pod, Zeroable, bytes_of}; use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime, Timelike, Utc}; use hmac::Hmac; +use hmac::Mac; use md5::{Digest, Md5}; -use rc4::{Rc4, Rc4Core, StreamCipher}; +use rc4::KeyInit; use rc4::cipher::StreamCipherCoreWrapper; use rc4::consts::U16; -use hmac::Mac; -use rc4::KeyInit; -use crate::rmc::structures::RmcSerialize; +use rc4::{Rc4, Rc4Core, StreamCipher}; +use std::io::{Read, Write}; type Md5Hmac = Hmac; -pub fn derive_key(pid: u32, password: [u8; 16]) -> [u8; 16]{ - let iteration_count = 65000 + pid%1024; +pub fn derive_key(pid: u32, password: &[u8]) -> [u8; 16] { + let iteration_count = 65000 + pid % 1024 - 1; + // we do one iteration out here to ensure the key is always 16 bytes - let mut key = password; + let mut key: [u8; 16] = { + let mut md5 = Md5::new(); + md5.update(password); + md5.finalize().try_into().unwrap() + }; for _ in 0..iteration_count { let mut md5 = Md5::new(); @@ -29,12 +34,12 @@ pub fn derive_key(pid: u32, password: [u8; 16]) -> [u8; 16]{ #[repr(transparent)] pub struct KerberosDateTime(pub u64); -impl KerberosDateTime{ - pub fn new(second: u64, minute: u64, hour: u64, day: u64, month: u64, year:u64 ) -> Self { +impl KerberosDateTime { + pub fn new(second: u64, minute: u64, hour: u64, day: u64, month: u64, year: u64) -> Self { Self(second | (minute << 6) | (hour << 12) | (day << 17) | (month << 22) | (year << 26)) } - pub fn now() -> Self{ + pub fn now() -> Self { let now = chrono::Utc::now(); Self::new( now.second() as u64, @@ -47,42 +52,53 @@ impl KerberosDateTime{ } #[inline] - pub fn get_seconds(&self) -> u8{ + pub fn get_seconds(&self) -> u8 { (self.0 & 0b111111) as u8 } #[inline] - pub fn get_minutes(&self) -> u8{ + pub fn get_minutes(&self) -> u8 { ((self.0 >> 6) & 0b111111) as u8 } #[inline] - pub fn get_hours(&self) -> u8{ + pub fn get_hours(&self) -> u8 { ((self.0 >> 12) & 0b111111) as u8 } #[inline] - pub fn get_days(&self) -> u8{ + pub fn get_days(&self) -> u8 { ((self.0 >> 17) & 0b111111) as u8 } #[inline] - pub fn get_month(&self) -> u8{ + pub fn get_month(&self) -> u8 { ((self.0 >> 22) & 0b1111) as u8 } #[inline] - pub fn get_year(&self) -> u64{ + pub fn get_year(&self) -> u64 { (self.0 >> 26) & 0xFFFFFFFF } - pub fn to_regular_time(&self) -> chrono::DateTime{ + pub fn to_regular_time(&self) -> chrono::DateTime { NaiveDateTime::new( - NaiveDate::from_ymd_opt(self.get_year() as i32, self.get_month() as u32, self.get_days() as u32).unwrap(), - NaiveTime::from_hms_opt(self.get_hours() as u32, self.get_minutes() as u32, self.get_seconds() as u32).unwrap() - ).and_utc() + NaiveDate::from_ymd_opt( + self.get_year() as i32, + self.get_month() as u32, + self.get_days() as u32, + ) + .unwrap(), + NaiveTime::from_hms_opt( + self.get_hours() as u32, + self.get_minutes() as u32, + self.get_seconds() as u32, + ) + .unwrap(), + ) + .and_utc() } } -impl RmcSerialize for KerberosDateTime{ +impl RmcSerialize for KerberosDateTime { fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(self.0.serialize(writer)?) } @@ -94,22 +110,22 @@ impl RmcSerialize for KerberosDateTime{ #[derive(Pod, Zeroable, Copy, Clone)] #[repr(C, packed)] -pub struct TicketInternalData{ +pub struct TicketInternalData { pub issued_time: KerberosDateTime, pub pid: u32, pub session_key: [u8; 32], } -impl TicketInternalData{ - pub(crate) fn new(pid: u32) -> Self{ - Self{ +impl TicketInternalData { + pub(crate) fn new(pid: u32) -> Self { + Self { issued_time: KerberosDateTime::now(), pid, - session_key: rand::random() + session_key: rand::random(), } } - pub(crate) fn encrypt(&self, key: [u8; 16]) -> Box<[u8]>{ + pub(crate) fn encrypt(&self, key: [u8; 16]) -> Box<[u8]> { let mut data = bytes_of(self).to_vec(); let mut rc4: StreamCipherCoreWrapper> = Rc4::new_from_slice(&key).unwrap(); @@ -117,11 +133,13 @@ impl TicketInternalData{ let mut hmac = ::new_from_slice(&key).unwrap(); - hmac.write_all(&data[..]).expect("failed to write data to hmac"); + hmac.write_all(&data[..]) + .expect("failed to write data to hmac"); let hmac_result = &hmac.finalize().into_bytes()[..]; - data.write_all(&hmac_result).expect("failed to write data to vec"); + data.write_all(&hmac_result) + .expect("failed to write data to vec"); data.into_boxed_slice() } @@ -129,41 +147,44 @@ impl TicketInternalData{ #[derive(Pod, Zeroable, Copy, Clone)] #[repr(C, packed)] -pub struct Ticket{ +pub struct Ticket { pub session_key: [u8; 32], pub pid: u32, } -impl Ticket{ - pub fn encrypt(&self, key: [u8; 16], internal_data: &[u8]) -> Box<[u8]>{ +impl Ticket { + pub fn encrypt(&self, key: [u8; 16], internal_data: &[u8]) -> Box<[u8]> { let mut data = bytes_of(self).to_vec(); - internal_data.serialize(&mut data).expect("unable to write to vec"); + internal_data + .serialize(&mut data) + .expect("unable to write to vec"); let mut rc4: StreamCipherCoreWrapper> = Rc4::new_from_slice(&key).unwrap(); rc4.apply_keystream(&mut data); let mut hmac = ::new_from_slice(&key).unwrap(); - hmac.write_all(&data[..]).expect("failed to write data to hmac"); + hmac.write_all(&data[..]) + .expect("failed to write data to hmac"); let hmac_result = &hmac.finalize().into_bytes()[..]; - data.write_all(&hmac_result).expect("failed to write data to vec"); + data.write_all(&hmac_result) + .expect("failed to write data to vec"); data.into_boxed_slice() } } - #[cfg(test)] -mod test{ +mod test { use crate::kerberos::KerberosDateTime; #[test] - fn kerberos_time_convert_test(){ + fn kerberos_time_convert_test() { let time = KerberosDateTime(135904948834); println!("{}", time.to_regular_time().to_rfc2822()); } -} \ No newline at end of file +} diff --git a/rnex-core/src/nex/account.rs b/rnex-core/src/nex/account.rs index 75c53ce..0c7a6f0 100644 --- a/rnex-core/src/nex/account.rs +++ b/rnex-core/src/nex/account.rs @@ -1,39 +1,38 @@ use macros::RmcSerialize; -#[derive(RmcSerialize)] -#[derive(Clone)] -pub struct Account{ +#[derive(RmcSerialize, Clone)] +pub struct Account { pub pid: u32, pub username: String, pub kerbros_password: [u8; 16], } -impl Account{ - pub fn new(pid: u32, username: &str, passwd: &str) -> Self{ +impl Account { + pub fn new(pid: u32, username: &str, passwd: &str) -> Self { let passwd_data = passwd.as_bytes(); let mut passwd = [0u8; 16]; - for (idx, byte) in passwd_data.iter().enumerate(){ + for (idx, byte) in passwd_data.iter().enumerate() { passwd[idx] = *byte; } - Self{ + Self { kerbros_password: passwd, username: username.into(), - pid + pid, } } - pub fn new_raw_password(pid: u32, username: &str, passwd: [u8; 16]) -> Self{ - Self{ + pub fn new_raw_password(pid: u32, username: &str, passwd: [u8; 16]) -> Self { + Self { kerbros_password: passwd, username: username.into(), - pid + pid, } } - pub fn get_login_data(&self) -> (u32, [u8; 16]){ - (self.pid, self.kerbros_password) + pub fn get_login_data(&self) -> (u32, &[u8]) { + (self.pid, &self.kerbros_password) } -} \ No newline at end of file +} diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index 30b4fce..89afd7f 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -1,6 +1,7 @@ use crate::grpc::account; use crate::reggie::{RemoteEdgeNodeHolder, RemoteEdgeNodeManagement}; use crate::{define_rmc_proto, kerberos}; +use log::warn; use macros::rmc_struct; use rnex_core::kerberos::{KerberosDateTime, Ticket, derive_key}; use rnex_core::nex::account::Account; @@ -13,7 +14,7 @@ use rnex_core::rmc::structures::connection_data::ConnectionData; use rnex_core::rmc::structures::qresult::QResult; use std::hash::{DefaultHasher, Hasher}; use std::net::SocketAddrV4; -use std::sync::Arc; +use std::sync::{Arc, LazyLock, OnceLock}; define_rmc_proto!( proto AuthClientProtocol{ @@ -30,8 +31,8 @@ pub struct AuthHandler { } pub fn generate_ticket( - source_act_login_data: (u32, [u8; 16]), - dest_act_login_data: (u32, [u8; 16]), + source_act_login_data: (u32, &[u8]), + dest_act_login_data: (u32, &[u8]), ) -> Box<[u8]> { let source_key = derive_key(source_act_login_data.0, source_act_login_data.1); let dest_key = derive_key(dest_act_login_data.0, dest_act_login_data.1); @@ -68,27 +69,57 @@ fn station_url_from_sock_addr(sock_addr: SocketAddrV4) -> String { ) } +static GUEST_ACCOUNT: LazyLock = + LazyLock::new(|| Account::new(100, "guest", "MMQea3n!fsik")); + +impl AuthHandler { + pub async fn generate_ticket_from_name( + &self, + name: &str, + ) -> Result<(u32, Box<[u8]>), ErrorCode> { + #[cfg(feature = "guest_login")] + { + if name == GUEST_ACCOUNT.username { + let source_login_data = GUEST_ACCOUNT.get_login_data(); + let destination_login_data = self.destination_server_acct.get_login_data(); + + return Ok(( + source_login_data.0, + generate_ticket(source_login_data, destination_login_data), + )); + } + } + let Ok(pid) = name.parse() else { + warn!("unable to connect to parse pid: {}", name); + return Err(ErrorCode::Core_InvalidArgument); + }; + + let Ok(mut client) = account::Client::new().await else { + warn!("unable to connect to grpc"); + return Err(ErrorCode::Core_Exception); + }; + + let Ok(passwd) = client.get_nex_password(pid).await else { + warn!("unable to get nex password"); + return Err(ErrorCode::Core_Exception); + }; + + let source_login_data = (pid, &passwd[..]); + let destination_login_data = self.destination_server_acct.get_login_data(); + + Ok(( + pid, + generate_ticket(source_login_data, destination_login_data), + )) + } +} + impl Auth for AuthHandler { async fn login( &self, name: String, ) -> Result<(QResult, u32, Vec, ConnectionData, String), ErrorCode> { - let Ok(pid) = name.parse() else { - return Err(ErrorCode::Core_InvalidArgument); - }; - - let Ok(mut client) = account::Client::new().await else { - return Err(ErrorCode::Core_Exception); - }; - - let Ok(passwd) = client.get_nex_password(pid).await else { - return Err(ErrorCode::Core_Exception); - }; - - let source_login_data = (pid, passwd); - let destination_login_data = self.destination_server_acct.get_login_data(); - - let ticket = generate_ticket(source_login_data, destination_login_data); + let (pid, ticket) = self.generate_ticket_from_name(&name).await?; let result = QResult::success(Core_Unknown); @@ -97,6 +128,7 @@ impl Auth for AuthHandler { hasher.write(name.as_bytes()); let Ok(addr) = self.control_server.get_url(hasher.finish()).await else { + warn!("no secure proxies"); return Err(ErrorCode::Core_Exception); }; @@ -110,7 +142,7 @@ impl Auth for AuthHandler { Ok(( result, - source_login_data.0, + pid, ticket.into(), connection_data, self.build_name.to_string(), //format!("{}; Rust NEX Version {} by DJMrTV", self.build_name, env!("CARGO_PKG_VERSION")), @@ -130,22 +162,19 @@ impl Auth for AuthHandler { source_pid: u32, destination_pid: u32, ) -> Result<(QResult, Vec), ErrorCode> { - let Some(source_login_data) = get_login_data_by_pid(source_pid).await else { + let Some((pid, passwd)) = get_login_data_by_pid(source_pid).await else { return Err(ErrorCode::Core_Exception); }; let desgination_login_data = if destination_pid == self.destination_server_acct.pid { self.destination_server_acct.get_login_data() } else { - let Some(login) = get_login_data_by_pid(destination_pid).await else { - return Err(ErrorCode::Core_Exception); - }; - login + return Err(ErrorCode::RendezVous_InvalidOperation); }; let result = QResult::success(Core_Unknown); - let ticket = generate_ticket(source_login_data, desgination_login_data); + let ticket = generate_ticket((pid, &passwd[..]), desgination_login_data); Ok((result, ticket.into())) } From 08e7bc9ed2db74b844f1625143a09c1e13733cb5 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 16:51:42 +0100 Subject: [PATCH 041/203] fix ports --- editions.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editions.yaml b/editions.yaml index 6b83a15..38a7810 100644 --- a/editions.yaml +++ b/editions.yaml @@ -12,6 +12,6 @@ friends: - friends settings: AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" - RNEX_VIRTUAL_PORT_INSECURE: "1:16" - RNEX_VIRTUAL_PORT_SECURE: "0:0" + RNEX_VIRTUAL_PORT_INSECURE: "1:10" + RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 6000 From 0c9db5c5ac032b0cb087638724e5f4c0d8913b24 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 16:58:47 +0100 Subject: [PATCH 042/203] fix ports --- editions.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editions.yaml b/editions.yaml index 38a7810..4a495c5 100644 --- a/editions.yaml +++ b/editions.yaml @@ -4,8 +4,8 @@ splatoon: - prudpv1 settings: AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" - RNEX_VIRTUAL_PORT_INSECURE: "1:16" - RNEX_VIRTUAL_PORT_SECURE: "0:0" + RNEX_VIRTUAL_PORT_INSECURE: "1:10" + RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 6000 friends: features: From f967c92cbec5def09a3348fd5276355b842596db Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 17:14:40 +0100 Subject: [PATCH 043/203] make v1 proxies actually run --- prudpv1/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prudpv1/src/lib.rs b/prudpv1/src/lib.rs index 40a46c7..0660a4b 100644 --- a/prudpv1/src/lib.rs +++ b/prudpv1/src/lib.rs @@ -4,11 +4,11 @@ cfg_if::cfg_if! { pub mod executables; pub mod prudp; pub async fn start_secure(param: ProxyStartupParam) { - executables::proxy_secure::start(); + executables::proxy_secure::start().await; } pub async fn start_insecure(param: ProxyStartupParam) { - executables::proxy_insecure::start(); + executables::proxy_insecure::start().await; } } } From 1cd8f192bbd0d8329cd612720958fdf8b5d8957b Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 17:24:11 +0100 Subject: [PATCH 044/203] fix double call of setup in v1 proxy --- prudpv1/src/executables/proxy_secure.rs | 2 -- rnex-core/src/executables/backend_server_insecure.rs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index b18de8c..12abf64 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -23,8 +23,6 @@ use tokio::task; use tokio::time::sleep; pub async fn start() { - setup(); - let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER) .await .unwrap(); diff --git a/rnex-core/src/executables/backend_server_insecure.rs b/rnex-core/src/executables/backend_server_insecure.rs index eef48a2..5c4db20 100644 --- a/rnex-core/src/executables/backend_server_insecure.rs +++ b/rnex-core/src/executables/backend_server_insecure.rs @@ -15,7 +15,7 @@ use tokio::net::TcpStream; pub static FORWARD_EDGE_NODE_HOLDER: Lazy = Lazy::new(|| { env::var("FORWARD_EDGE_NODE_HOLDER") .ok() - .and_then(|s| s.parse().ok()) + .and_then(|s| Some(s.parse().unwrap())) .expect("FORWARD_EDGE_NODE_HOLDER not set") }); From dcbbf2e1fe1f4b268ccddf0296f6f455c137ad1f Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 17:28:49 +0100 Subject: [PATCH 045/203] revert changing of default server port --- rnex-core/src/executables/common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index 0d5ca06..416e450 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -40,7 +40,7 @@ pub static SERVER_PORT: Lazy = Lazy::new(|| { env::var("SERVER_PORT") .ok() .and_then(|s| s.parse().ok()) - .unwrap_or(6000) + .unwrap_or(10000) }); pub static KERBEROS_SERVER_PASSWORD: Lazy = Lazy::new(|| { From 7ea43b101d848ef248661fb530029ee0f33fbaf3 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 17:38:42 +0100 Subject: [PATCH 046/203] fix insecure proxy setup being called twice --- prudpv1/src/executables/proxy_insecure.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index a6d9453..7a08283 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -21,8 +21,6 @@ use tokio::task; use tokio::time::sleep; pub async fn start() { - setup(); - let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER) .await .unwrap(); From 3e2dc9099a232e9554d6b67fab1bac7021409e16 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 18:53:22 +0100 Subject: [PATCH 047/203] generalize node holder connection --- Cargo.lock | 1 + proxy/Cargo.toml | 1 + proxy/src/insecure.rs | 16 ++++++++++------ proxy/src/lib.rs | 8 ++++++++ proxy/src/secure.rs | 14 ++++++++------ prudpv1/src/executables/proxy_insecure.rs | 4 ++-- prudpv1/src/executables/proxy_secure.rs | 17 ----------------- 7 files changed, 30 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a8b4dd5..53c829e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,6 +541,7 @@ name = "proxy" version = "0.1.0" dependencies = [ "cfg-if", + "log", "proxy-common", "prudpv0", "prudpv1", diff --git a/proxy/Cargo.toml b/proxy/Cargo.toml index f2a5974..fa56ab2 100644 --- a/proxy/Cargo.toml +++ b/proxy/Cargo.toml @@ -10,6 +10,7 @@ prudpv1 = { path = "../prudpv1", optional = true } proxy-common = { path = "../proxy-common" } cfg-if = "1.0.4" rnex-core = { path = "../rnex-core", version = "0.1.1" } +log = "0.4.25" [features] prudpv0 = ["dep:prudpv0"] diff --git a/proxy/src/insecure.rs b/proxy/src/insecure.rs index b109d14..4a32adf 100644 --- a/proxy/src/insecure.rs +++ b/proxy/src/insecure.rs @@ -1,13 +1,17 @@ -use proxy_common::ProxyStartupParam; +use std::process::abort; + +use proxy::edge_node_dc_callback; +use proxy_common::{ProxyStartupParam, setup_edge_node_connection}; use rnex_core::common::setup; #[tokio::main] async fn main() { setup(); - proxy::start_insecure( - ProxyStartupParam::new(proxy_common::ProxyType::Insecure) - .expect("unable to get startup parameters"), - ) - .await; + let param = ProxyStartupParam::new(proxy_common::ProxyType::Insecure) + .expect("unable to get startup parameters"); + + setup_edge_node_connection(¶m, edge_node_dc_callback).await; + + proxy::start_insecure(param).await; } diff --git a/proxy/src/lib.rs b/proxy/src/lib.rs index 7120adc..2c52a9a 100644 --- a/proxy/src/lib.rs +++ b/proxy/src/lib.rs @@ -1,4 +1,7 @@ +use std::process::abort; + use cfg_if::cfg_if; +use log::error; cfg_if! { if #[cfg(feature = "prudpv0")]{ @@ -9,3 +12,8 @@ cfg_if! { compile_error!("no proxy type has been set"); } } + +pub fn edge_node_dc_callback() { + error!("disconnected from node holder, aborting!"); + abort() +} diff --git a/proxy/src/secure.rs b/proxy/src/secure.rs index 8990d74..6d42c87 100644 --- a/proxy/src/secure.rs +++ b/proxy/src/secure.rs @@ -1,12 +1,14 @@ -use proxy_common::ProxyStartupParam; +use proxy::edge_node_dc_callback; +use proxy_common::{ProxyStartupParam, setup_edge_node_connection}; use rnex_core::common::setup; #[tokio::main] async fn main() { setup(); - proxy::start_secure( - ProxyStartupParam::new(proxy_common::ProxyType::Secure) - .expect("unable to get startup parameters"), - ) - .await; + + let param = ProxyStartupParam::new(proxy_common::ProxyType::Secure) + .expect("unable to get startup parameters"); + + setup_edge_node_connection(¶m, edge_node_dc_callback).await; + proxy::start_secure(param).await; } diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index 7a08283..0bde918 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -21,7 +21,7 @@ use tokio::task; use tokio::time::sleep; pub async fn start() { - let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER) + /*let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER) .await .unwrap(); @@ -36,7 +36,7 @@ pub async fn start() { let conn = new_rmc_gateway_connection(conn, |r| { Arc::new(OnlyRemote::::new(r)) - }); + });*/ let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) .await diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index 12abf64..2045cfd 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -23,23 +23,6 @@ use tokio::task; use tokio::time::sleep; pub async fn start() { - let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER) - .await - .unwrap(); - - let conn: SplittableBufferConnection = conn.into(); - - conn.send( - Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)) - .to_data() - .unwrap(), - ) - .await; - - let conn = new_rmc_gateway_connection(conn, |r| { - Arc::new(OnlyRemote::::new(r)) - }); - let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) .await .expect("unable to start router"); From 28bc6819a6ee2e3a651c6d5450b425c3969cc0f6 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 20:22:11 +0100 Subject: [PATCH 048/203] add pings to v0 --- proxy-common/src/lib.rs | 2 ++ prudpv0/src/lib.rs | 2 -- prudpv0/src/packet.rs | 40 ++++++++++++++++++++- prudpv0/src/server.rs | 80 +++++++++++++++++++++++++++++++++++------ 4 files changed, 110 insertions(+), 14 deletions(-) diff --git a/proxy-common/src/lib.rs b/proxy-common/src/lib.rs index fae29df..93c16c8 100644 --- a/proxy-common/src/lib.rs +++ b/proxy-common/src/lib.rs @@ -161,6 +161,8 @@ pub async fn setup_edge_node_connection( .unwrap(), ) .await; + + println!("{:?}", param.self_public); //leave the inner object floating so that it gets destroyed once we disconnect new_rmc_gateway_connection(conn, move |r| { Arc::new(OnRemoteDrop::::new( diff --git a/prudpv0/src/lib.rs b/prudpv0/src/lib.rs index 0df222a..444899a 100644 --- a/prudpv0/src/lib.rs +++ b/prudpv0/src/lib.rs @@ -44,8 +44,6 @@ cfg_if::cfg_if! { //implementations, e.g. secure and insecure(this also includes special cases like friends) async fn start_proxy(param: ProxyStartupParam) { - setup_edge_node_connection(¶m, || abort()); - info!("creating cryptography instance"); let mut crypto = Arc::new(T::new()); info!("binding to socket"); diff --git a/prudpv0/src/packet.rs b/prudpv0/src/packet.rs index d7b6705..f55ff18 100644 --- a/prudpv0/src/packet.rs +++ b/prudpv0/src/packet.rs @@ -6,7 +6,7 @@ use rnex_core::prudp::{ types_flags::{ self, TypesFlags, flags::{HAS_SIZE, NEED_ACK}, - types::{CONNECT, DATA, SYN}, + types::{CONNECT, DATA, PING, SYN}, }, virtual_port::VirtualPort, }; @@ -313,3 +313,41 @@ pub fn new_data_packet( packet.0 } + +pub fn new_ping_packet( + flags: u16, + source: VirtualPort, + destination: VirtualPort, + sequence_id: u16, + session_id: u8, + crypto_instance: &mut impl CryptoInstance, + crypto: &impl Crypto, +) -> Vec { + let type_flags = TypesFlags::default().types(PING).flags(flags); + + let vec = vec![0; precalc_size(type_flags, 0)]; + let mut packet = PRUDPV0Packet::new(vec); + + let packet_signature = crypto_instance.generate_signature(type_flags, &[]); + + let header = packet.header_mut().expect("packet malformed in creation"); + + *header = PRUDPV0Header { + destination, + source, + packet_signature, + sequence_id, + session_id, + type_flags, + }; + + *packet.checksum_mut().expect("packet malformed in creation") = crypto.calculate_checksum( + packet + .checksummed_data() + .expect("packet malformed in creation"), + ); + + info!("header: {:?}", packet.header()); + + packet.0 +} diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index bd4b492..87e5fbd 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -19,7 +19,7 @@ use rnex_core::{ types_flags::{ TypesFlags, flags::{ACK, HAS_SIZE, NEED_ACK, RELIABLE}, - types::{CONNECT, DATA, SYN}, + types::{CONNECT, DATA, PING, SYN}, }, virtual_port::VirtualPort, }, @@ -36,8 +36,8 @@ use tokio::{ use crate::{ crypto::{Crypto, CryptoInstance}, packet::{ - PRUDPV0Header, PRUDPV0Packet, new_connect_packet, new_data_packet, new_syn_packet, - precalc_size, + PRUDPV0Header, PRUDPV0Packet, new_connect_packet, new_data_packet, new_ping_packet, + new_syn_packet, precalc_size, }, }; @@ -167,7 +167,31 @@ impl Server { } async fn timeout_thread(self: Arc, conn: Arc>) { loop { - sleep(Duration::from_secs(5)); + sleep(Duration::from_secs(3)); + let mut inner = conn.inner.lock().await; + if (Instant::now() - inner.last_action).as_secs() > 5 { + let packet = new_ping_packet( + NEED_ACK, + self.param.virtual_port, + conn.addr.virtual_port, + 0, + conn.session_id, + &mut inner.crypto_instance, + &self.crypto, + ); + + self.socket + .send_to(&packet, conn.addr.regular_socket_addr) + .await; + } + + if (Instant::now() - conn.inner.lock().await.last_action).as_secs() > 15 { + let mut conns = self.connections.write().await; + conns.remove(&conn.addr); + drop(conns); + } + + drop(inner); } } async fn handle_syn(self: Arc, packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { @@ -311,11 +335,38 @@ impl Server { } drop(conn); } - async fn process_packet<'a>( - self: Arc, - packet: PRUDPV0Packet>, - addr: SocketAddrV4, - ) { + + async fn handle_ping(self: Arc, mut packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { + let header = packet.header().unwrap(); + + let Some(conn) = self.get_connection(addr).await else { + warn!("ping on inactive connection: {:?}", addr); + return; + }; + let mut inner = conn.inner.lock().await; + let packet = new_ping_packet( + ACK, + self.param.virtual_port, + addr.virtual_port, + header.sequence_id, + header.session_id, + &mut inner.crypto_instance, + &self.crypto, + ); + drop(inner); + drop(conn); + + self.socket.send_to(&packet, addr.regular_socket_addr).await; + } + + async fn get_connection(&self, addr: PRUDPSockAddr) -> Option>> { + let rd = self.connections.read().await; + let res = rd.get(&addr).cloned(); + drop(rd); + res + } + + async fn process_packet(self: Arc, packet: PRUDPV0Packet>, addr: SocketAddrV4) { if !packet.check_checksum(&self.crypto) { warn!("invalid checksum from: {}", addr); return; @@ -332,7 +383,11 @@ impl Server { info!("got ack(acks are ignored for now)"); return; } - + if let Some(conn) = self.get_connection(addr).await { + let mut inner = conn.inner.lock().await; + inner.last_action = Instant::now(); + drop(inner); + }; println!("{:?}", header); match header.type_flags.get_types() { SYN => { @@ -344,6 +399,9 @@ impl Server { DATA => { self.handle_data(packet, addr).await; } + PING => { + self.handle_ping(packet, addr).await; + } v => { println!("unimplemented packed type: {}", v); } @@ -376,7 +434,7 @@ impl Server { } } pub async fn new(param: ProxyStartupParam) -> Self { - let socket = UdpSocket::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) + let socket = UdpSocket::bind(param.self_private) .await .expect("unable to bind socket"); Self { From 420c689644a2a80ceba80f613dc4cc3f9c0d5665 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 20:41:37 +0100 Subject: [PATCH 049/203] fix signature --- prudpv0/src/crypto/friends_insecure.rs | 7 +++++-- prudpv0/src/server.rs | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/prudpv0/src/crypto/friends_insecure.rs b/prudpv0/src/crypto/friends_insecure.rs index d1575e8..9fbfe95 100644 --- a/prudpv0/src/crypto/friends_insecure.rs +++ b/prudpv0/src/crypto/friends_insecure.rs @@ -1,6 +1,7 @@ -use std::rc::Rc; +use std::{io::Write, rc::Rc}; use hmac::Mac; +use md5::{Digest, Md5}; use rc4::{KeyInit, Rc4, StreamCipher}; use rnex_core::prudp::{ encryption::{DEFAULT_KEY, EncryptionPair}, @@ -35,7 +36,9 @@ impl CryptoInstance for InsecureInstance { if data.len() == 0 { [0x78, 0x56, 0x34, 0x12] } else { - let mut hmac = ::new_from_slice(ACCESS_KEY.as_bytes()) + let mut hash = Md5::new(); + hash.write(ACCESS_KEY.as_bytes()).unwrap(); + let mut hmac = ::new_from_slice(&hash.finalize().as_slice()) .expect("unable to create hmac md5"); hmac.update(data); hmac.finalize().into_bytes()[0..4].try_into().unwrap() diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 87e5fbd..3788478 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -109,7 +109,7 @@ impl Server { let mut inner = conn.inner.lock().await; let seq = inner.server_packet_counter; let packet = new_data_packet( - HAS_SIZE | NEED_ACK | RELIABLE, + NEED_ACK | RELIABLE, self.param.virtual_port, conn.addr.virtual_port, data, @@ -268,7 +268,7 @@ impl Server { }); let packet = new_connect_packet( - ACK | HAS_SIZE, + ACK, header.destination, header.source, self_signat, From b95656325509849a3453d0786040ca3de31aca6b Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 20:57:19 +0100 Subject: [PATCH 050/203] add disconnection --- prudpv0/src/packet.rs | 37 ++++++++++++++++++++++++++- prudpv0/src/server.rs | 58 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 91 insertions(+), 4 deletions(-) diff --git a/prudpv0/src/packet.rs b/prudpv0/src/packet.rs index f55ff18..aa68194 100644 --- a/prudpv0/src/packet.rs +++ b/prudpv0/src/packet.rs @@ -6,7 +6,7 @@ use rnex_core::prudp::{ types_flags::{ self, TypesFlags, flags::{HAS_SIZE, NEED_ACK}, - types::{CONNECT, DATA, PING, SYN}, + types::{CONNECT, DATA, DISCONNECT, PING, SYN}, }, virtual_port::VirtualPort, }; @@ -347,6 +347,41 @@ pub fn new_ping_packet( .expect("packet malformed in creation"), ); + packet.0 +} +pub fn new_disconnect_packet( + flags: u16, + source: VirtualPort, + destination: VirtualPort, + sequence_id: u16, + session_id: u8, + crypto_instance: &mut impl CryptoInstance, + crypto: &impl Crypto, +) -> Vec { + let type_flags = TypesFlags::default().types(DISCONNECT).flags(flags); + + let vec = vec![0; precalc_size(type_flags, 0)]; + let mut packet = PRUDPV0Packet::new(vec); + + let packet_signature = crypto_instance.generate_signature(type_flags, &[]); + + let header = packet.header_mut().expect("packet malformed in creation"); + + *header = PRUDPV0Header { + destination, + source, + packet_signature, + sequence_id, + session_id, + type_flags, + }; + + *packet.checksum_mut().expect("packet malformed in creation") = crypto.calculate_checksum( + packet + .checksummed_data() + .expect("packet malformed in creation"), + ); + info!("header: {:?}", packet.header()); packet.0 diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 3788478..a1e561c 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -19,7 +19,7 @@ use rnex_core::{ types_flags::{ TypesFlags, flags::{ACK, HAS_SIZE, NEED_ACK, RELIABLE}, - types::{CONNECT, DATA, PING, SYN}, + types::{CONNECT, DATA, DISCONNECT, PING, SYN}, }, virtual_port::VirtualPort, }, @@ -36,8 +36,8 @@ use tokio::{ use crate::{ crypto::{Crypto, CryptoInstance}, packet::{ - PRUDPV0Header, PRUDPV0Packet, new_connect_packet, new_data_packet, new_ping_packet, - new_syn_packet, precalc_size, + PRUDPV0Header, PRUDPV0Packet, new_connect_packet, new_data_packet, new_disconnect_packet, + new_ping_packet, new_syn_packet, precalc_size, }, }; @@ -170,6 +170,7 @@ impl Server { sleep(Duration::from_secs(3)); let mut inner = conn.inner.lock().await; if (Instant::now() - inner.last_action).as_secs() > 5 { + warn!("connection exceeded silence limit, sending ping"); let packet = new_ping_packet( NEED_ACK, self.param.virtual_port, @@ -186,6 +187,27 @@ impl Server { } if (Instant::now() - conn.inner.lock().await.last_action).as_secs() > 15 { + warn!("client timed out..."); + + let packet = new_disconnect_packet( + 0, + self.param.virtual_port, + conn.addr.virtual_port, + 0, + conn.session_id, + &mut inner.crypto_instance, + &self.crypto, + ); + + self.socket + .send_to(&packet, conn.addr.regular_socket_addr) + .await; + self.socket + .send_to(&packet, conn.addr.regular_socket_addr) + .await; + self.socket + .send_to(&packet, conn.addr.regular_socket_addr) + .await; let mut conns = self.connections.write().await; conns.remove(&conn.addr); drop(conns); @@ -358,7 +380,34 @@ impl Server { self.socket.send_to(&packet, addr.regular_socket_addr).await; } + async fn handle_disconnect( + self: Arc, + mut packet: PRUDPV0Packet>, + addr: PRUDPSockAddr, + ) { + let header = packet.header().unwrap(); + let Some(conn) = self.get_connection(addr).await else { + warn!("ping on inactive connection: {:?}", addr); + return; + }; + let mut inner = conn.inner.lock().await; + let packet = new_disconnect_packet( + ACK, + self.param.virtual_port, + addr.virtual_port, + header.sequence_id, + header.session_id, + &mut inner.crypto_instance, + &self.crypto, + ); + drop(inner); + drop(conn); + + self.socket.send_to(&packet, addr.regular_socket_addr).await; + self.socket.send_to(&packet, addr.regular_socket_addr).await; + self.socket.send_to(&packet, addr.regular_socket_addr).await; + } async fn get_connection(&self, addr: PRUDPSockAddr) -> Option>> { let rd = self.connections.read().await; let res = rd.get(&addr).cloned(); @@ -402,6 +451,9 @@ impl Server { PING => { self.handle_ping(packet, addr).await; } + DISCONNECT => { + self.handle_disconnect(packet, addr).await; + } v => { println!("unimplemented packed type: {}", v); } From fd58995c4c103a2812d1d906feb82fd3b9b72c10 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 21:39:11 +0100 Subject: [PATCH 051/203] add logging and make auth version report be edition specific --- editions.yaml | 2 +- prudpv0/src/server.rs | 2 ++ prudpv1/src/executables/proxy_secure.rs | 2 +- rnex-core/src/nex/auth_handler.rs | 11 +++++++---- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/editions.yaml b/editions.yaml index 4a495c5..1c025b0 100644 --- a/editions.yaml +++ b/editions.yaml @@ -11,7 +11,7 @@ friends: features: - friends settings: - AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" + AUTH_REPORT_VERSION: "branch:origin/feature/45925_FixAutoReconnect build:3_10_11_2006_0" RNEX_VIRTUAL_PORT_INSECURE: "1:10" RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 6000 diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index a1e561c..19622ec 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -359,6 +359,7 @@ impl Server { } async fn handle_ping(self: Arc, mut packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { + info!("got ping"); let header = packet.header().unwrap(); let Some(conn) = self.get_connection(addr).await else { @@ -385,6 +386,7 @@ impl Server { mut packet: PRUDPV0Packet>, addr: PRUDPSockAddr, ) { + info!("got disconnect"); let header = packet.header().unwrap(); let Some(conn) = self.get_connection(addr).await else { diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index 2045cfd..51677f8 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -35,7 +35,7 @@ pub async fn start() { .await .expect("unable to add socket"); - // let conn = socket_secure.connect(auth_sockaddr).await.unwrap(); + let conn = socket_secure.connect(auth_sockaddr).await.unwrap(); loop { let Some(mut conn) = socket_secure.accept().await else { diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index 89afd7f..21f67dc 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -1,7 +1,7 @@ use crate::grpc::account; use crate::reggie::{RemoteEdgeNodeHolder, RemoteEdgeNodeManagement}; use crate::{define_rmc_proto, kerberos}; -use log::warn; +use log::{info, warn}; use macros::rmc_struct; use rnex_core::kerberos::{KerberosDateTime, Ticket, derive_key}; use rnex_core::nex::account::Account; @@ -140,13 +140,16 @@ impl Auth for AuthHandler { special_protocols: Vec::new(), }; - Ok(( + let ret = ( result, pid, ticket.into(), connection_data, - self.build_name.to_string(), //format!("{}; Rust NEX Version {} by DJMrTV", self.build_name, env!("CARGO_PKG_VERSION")), - )) + self.build_name.to_string(), + ); + + info!("data: {:?}", ret); + Ok(ret) } async fn login_ex( From 2122b8dd6c600a10c7f28e15764f7a254e54aefd Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 21:50:42 +0100 Subject: [PATCH 052/203] more logging --- prudpv0/src/server.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 19622ec..55b508e 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -168,6 +168,7 @@ impl Server { async fn timeout_thread(self: Arc, conn: Arc>) { loop { sleep(Duration::from_secs(3)); + info!("running another loop"); let mut inner = conn.inner.lock().await; if (Instant::now() - inner.last_action).as_secs() > 5 { warn!("connection exceeded silence limit, sending ping"); From d483b230e43dbb40b6eb42d151653e44a41ae76a Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 22:04:54 +0100 Subject: [PATCH 053/203] switch proxies to from scracth --- Dockerfile | 12 ++++-------- prudpv1/src/executables/proxy_insecure.rs | 1 - prudpv1/src/executables/proxy_secure.rs | 4 +--- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2baa33b..e181a93 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,19 +20,15 @@ COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/edge_node_hold ENTRYPOINT ["/edge_node_holder_server"] -FROM alpine:latest AS proxy-insecure +FROM scratch AS proxy-insecure COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_insecure /proxy_insecure -RUN apk add --no-cache ca-certificates -RUN update-ca-certificates ENTRYPOINT ["/proxy_insecure"] -FROM alpine:latest AS proxy-secure +FROM scratch AS proxy-secure COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_secure /proxy_secure -RUN apk add --no-cache ca-certificates -RUN update-ca-certificates ENTRYPOINT ["/proxy_secure"] - - + + FROM scratch AS backend-auth COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server_insecure /backend_server_insecure ENTRYPOINT ["/backend_server_insecure"] diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index 0bde918..975f837 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -111,5 +111,4 @@ pub async fn start() { } }); } - drop(conn); } diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index 51677f8..8446391 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -35,7 +35,7 @@ pub async fn start() { .await .expect("unable to add socket"); - let conn = socket_secure.connect(auth_sockaddr).await.unwrap(); + // let conn = socket_secure.connect(auth_sockaddr).await.unwrap(); loop { let Some(mut conn) = socket_secure.accept().await else { @@ -99,6 +99,4 @@ pub async fn start() { } }); } - - drop(conn); } From 8af4ca525aaac38cfc7fa8fb767280fb31a0b80c Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 31 Jan 2026 22:20:18 +0100 Subject: [PATCH 054/203] add image cache --- .gitlab-ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fad0b25..900885c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,11 @@ default: image: quay.io/podman/stable + cache: + key: image-cache + paths: + - /var/lib/containers/storage + - /run/containers/storage + - .local/share/containers/storage before_script: - git submodule update --init - podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY From 3b6de6968d1e12293ca4d3b93169b07359f8edba Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 1 Feb 2026 20:59:23 +0100 Subject: [PATCH 055/203] lots of changes --- rnex-core/Cargo.toml | 2 +- .../executables/backend_server_insecure.rs | 28 +-- .../src/executables/backend_server_secure.rs | 32 +-- rnex-core/src/executables/friends_backend.rs | 22 ++ rnex-core/src/executables/mod.rs | 4 +- rnex-core/src/executables/regular_backend.rs | 33 +++ rnex-core/src/kerberos/mod.rs | 23 +- rnex-core/src/nex/auth_handler.rs | 56 ++++- rnex-core/src/nex/common.rs | 93 +++++++ rnex-core/src/nex/friends_handler.rs | 160 ++++++++++++ rnex-core/src/nex/mod.rs | 6 +- rnex-core/src/nex/user.rs | 94 +------ rnex-core/src/prudp/mod.rs | 1 + rnex-core/src/prudp/socket_addr.rs | 31 +-- rnex-core/src/prudp/ticket.rs | 81 ++++++ rnex-core/src/rmc/protocols/auth.rs | 4 +- rnex-core/src/rmc/protocols/friends.rs | 146 +++++++++++ rnex-core/src/rmc/protocols/mod.rs | 5 +- rnex-core/src/rmc/protocols/secure.rs | 13 +- rnex-core/src/rmc/structures/any.rs | 17 +- rnex-core/src/rmc/structures/buffer.rs | 23 +- .../src/rmc/structures/connection_data.rs | 12 +- rnex-core/src/rmc/structures/primitives.rs | 237 +++++++++++++----- rnex-core/src/rmc/structures/variant.rs | 22 +- 24 files changed, 883 insertions(+), 262 deletions(-) create mode 100644 rnex-core/src/executables/friends_backend.rs create mode 100644 rnex-core/src/executables/regular_backend.rs create mode 100644 rnex-core/src/nex/common.rs create mode 100644 rnex-core/src/nex/friends_handler.rs create mode 100644 rnex-core/src/prudp/ticket.rs create mode 100644 rnex-core/src/rmc/protocols/friends.rs diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 34034d9..69a4f9f 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -14,7 +14,7 @@ simplelog = "0.12.2" chrono = "0.4.39" log = "0.4.25" rand = "0.8.5" - +cfg-if = "1.0.4" hmac = "0.12.1" md-5 = "^0.10.6" tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "net", "sync", "fs"] } diff --git a/rnex-core/src/executables/backend_server_insecure.rs b/rnex-core/src/executables/backend_server_insecure.rs index 5c4db20..efb08db 100644 --- a/rnex-core/src/executables/backend_server_insecure.rs +++ b/rnex-core/src/executables/backend_server_insecure.rs @@ -1,6 +1,8 @@ +use cfg_if::cfg_if; use once_cell::sync::Lazy; use rnex_core::common::setup; use rnex_core::executables::common::{SECURE_SERVER_ACCOUNT, new_simple_backend}; +use rnex_core::executables::regular_backend; use rnex_core::nex::auth_handler::AuthHandler; use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister; use rnex_core::reggie::RemoteEdgeNodeHolder; @@ -23,25 +25,11 @@ pub static FORWARD_EDGE_NODE_HOLDER: Lazy = Lazy::new(|| { async fn main() { setup(); - let conn = TcpStream::connect(&*FORWARD_EDGE_NODE_HOLDER) - .await - .unwrap(); + cfg_if! { + if #[cfg(features = "friends")]{ - let conn: SplittableBufferConnection = conn.into(); - - conn.send(DontRegister.to_data().unwrap()).await; - - let conn = new_rmc_gateway_connection(conn, |r| { - Arc::new(OnlyRemote::::new(r)) - }); - - new_simple_backend(move |_, _| { - let controller = conn.clone(); - Arc::new(AuthHandler { - destination_server_acct: &SECURE_SERVER_ACCOUNT, - build_name: "branch:origin/project/wup-agmj build:3_8_15_2004_0", - control_server: controller, - }) - }) - .await; + } else { + regular_backend::start_regular_backend().await + } + } } diff --git a/rnex-core/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs index 598b039..51d9647 100644 --- a/rnex-core/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -1,5 +1,7 @@ +use cfg_if::cfg_if; use rnex_core::common::setup; use rnex_core::executables::common::new_simple_backend; +use rnex_core::executables::friends_backend::start_friends_backend; use rnex_core::nex::matchmake::MatchmakeManager; use rnex_core::nex::remote_console::RemoteConsole; use rnex_core::nex::user::User; @@ -11,27 +13,11 @@ use std::sync::atomic::AtomicU32; async fn main() { setup(); - let mmm = Arc::new(MatchmakeManager { - //gid_counter: AtomicU32::new(1), - sessions: Default::default(), - users: Default::default(), - rv_cid_counter: AtomicU32::new(1), - }); - - let weak_mmm = Arc::downgrade(&mmm); - - MatchmakeManager::initialize_garbage_collect_thread(weak_mmm).await; - - new_simple_backend(move |c, r| { - let mmm = mmm.clone(); - Arc::new_cyclic(move |this| User { - this: this.clone(), - ip: c.prudpsock_addr, - pid: c.pid, - remote: RemoteConsole::new(r), - matchmake_manager: mmm, - station_url: Default::default(), - }) - }) - .await; + cfg_if! { + if #[cfg(feature = "friends")]{ + start_friends_backend().await; + } else { + regular_backend::start_regular_backend().await + } + } } diff --git a/rnex-core/src/executables/friends_backend.rs b/rnex-core/src/executables/friends_backend.rs new file mode 100644 index 0000000..2626fbe --- /dev/null +++ b/rnex-core/src/executables/friends_backend.rs @@ -0,0 +1,22 @@ +use std::sync::{Arc, atomic::AtomicU32}; + +use crate::{ + executables::common::new_simple_backend, + nex::friends_handler::{FriendsManager, FriendsUser}, +}; + +pub async fn start_friends_backend() { + let fm = Arc::new(FriendsManager { + cid_counter: AtomicU32::new(1), + }); + + new_simple_backend(move |c, r| { + let fm = fm.clone(); + Arc::new_cyclic(move |this| FriendsUser { + fm, + addr: c.prudpsock_addr, + pid: c.pid, + }) + }) + .await; +} diff --git a/rnex-core/src/executables/mod.rs b/rnex-core/src/executables/mod.rs index ffac467..cc9b83d 100644 --- a/rnex-core/src/executables/mod.rs +++ b/rnex-core/src/executables/mod.rs @@ -1 +1,3 @@ -pub mod common; \ No newline at end of file +pub mod common; +pub mod friends_backend; +pub mod regular_backend; diff --git a/rnex-core/src/executables/regular_backend.rs b/rnex-core/src/executables/regular_backend.rs new file mode 100644 index 0000000..65cb2ca --- /dev/null +++ b/rnex-core/src/executables/regular_backend.rs @@ -0,0 +1,33 @@ +use std::sync::{Arc, atomic::AtomicU32}; + +use crate::{ + executables::common::new_simple_backend, + nex::{matchmake::MatchmakeManager, remote_console::RemoteConsole, user::User}, + rmc::protocols::RmcPureRemoteObject, +}; + +pub async fn start_regular_backend() { + let mmm = Arc::new(MatchmakeManager { + //gid_counter: AtomicU32::new(1), + sessions: Default::default(), + users: Default::default(), + rv_cid_counter: AtomicU32::new(1), + }); + + let weak_mmm = Arc::downgrade(&mmm); + + MatchmakeManager::initialize_garbage_collect_thread(weak_mmm).await; + + new_simple_backend(move |c, r| { + let mmm = mmm.clone(); + Arc::new_cyclic(move |this| User { + this: this.clone(), + ip: c.prudpsock_addr, + pid: c.pid, + remote: RemoteConsole::new(r), + matchmake_manager: mmm, + station_url: Default::default(), + }) + }) + .await; +} diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index a5963d8..88700a6 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -1,5 +1,5 @@ -use crate::rmc::structures::RmcSerialize; use bytemuck::{Pod, Zeroable, bytes_of}; +use cfg_if::cfg_if; use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime, Timelike, Utc}; use hmac::Hmac; use hmac::Mac; @@ -8,7 +8,20 @@ use rc4::KeyInit; use rc4::cipher::StreamCipherCoreWrapper; use rc4::consts::U16; use rc4::{Rc4, Rc4Core, StreamCipher}; +use rnex_core::rmc::structures::RmcSerialize; use std::io::{Read, Write}; +use typenum::Unsigned; + +use rnex_core::rmc::structures::Result; + +cfg_if! { + if #[cfg(feature = "friends")]{ + pub type SESSION_KEY_LENGTH_TY = U16; + } else { + pub type SESSION_KEY_LENGTH_TY = U32; + } +} +pub const SESSION_KEY_LENGTH: usize = SESSION_KEY_LENGTH_TY::USIZE; type Md5Hmac = Hmac; @@ -99,11 +112,11 @@ impl KerberosDateTime { } impl RmcSerialize for KerberosDateTime { - fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { + fn serialize(&self, writer: &mut impl Write) -> Result<()> { Ok(self.0.serialize(writer)?) } - fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> Result { Ok(Self(u64::deserialize(reader)?)) } } @@ -113,7 +126,7 @@ impl RmcSerialize for KerberosDateTime { pub struct TicketInternalData { pub issued_time: KerberosDateTime, pub pid: u32, - pub session_key: [u8; 32], + pub session_key: [u8; SESSION_KEY_LENGTH], } impl TicketInternalData { @@ -148,7 +161,7 @@ impl TicketInternalData { #[derive(Pod, Zeroable, Copy, Clone)] #[repr(C, packed)] pub struct Ticket { - pub session_key: [u8; 32], + pub session_key: [u8; SESSION_KEY_LENGTH], pub pid: u32, } diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index 21f67dc..0ab6910 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -1,6 +1,7 @@ use crate::grpc::account; use crate::reggie::{RemoteEdgeNodeHolder, RemoteEdgeNodeManagement}; use crate::{define_rmc_proto, kerberos}; +use cfg_if::cfg_if; use log::{info, warn}; use macros::rmc_struct; use rnex_core::kerberos::{KerberosDateTime, Ticket, derive_key}; @@ -11,6 +12,7 @@ use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::response::ErrorCode::Core_Unknown; use rnex_core::rmc::structures::any::Any; use rnex_core::rmc::structures::connection_data::ConnectionData; +use rnex_core::rmc::structures::connection_data::ConnectionDataOld; use rnex_core::rmc::structures::qresult::QResult; use std::hash::{DefaultHasher, Hasher}; use std::net::SocketAddrV4; @@ -49,7 +51,13 @@ pub fn generate_ticket( encrypted_session_ticket } -async fn get_login_data_by_pid(pid: u32) -> Option<(u32, [u8; 16])> { +async fn get_login_data_by_pid(pid: u32) -> Option<(u32, Box<[u8]>)> { + if pid == GUEST_ACCOUNT.pid { + let source_login_data = GUEST_ACCOUNT.get_login_data(); + + return Some((source_login_data.0, source_login_data.1.into())); + } + let Ok(mut client) = account::Client::new().await else { return None; }; @@ -58,7 +66,7 @@ async fn get_login_data_by_pid(pid: u32) -> Option<(u32, [u8; 16])> { return None; }; - Some((pid, passwd)) + Some((pid, passwd.into())) } fn station_url_from_sock_addr(sock_addr: SocketAddrV4) -> String { @@ -118,6 +126,42 @@ impl Auth for AuthHandler { async fn login( &self, name: String, + ) -> Result<(QResult, u32, Vec, ConnectionDataOld, String), ErrorCode> { + let (pid, ticket) = self.generate_ticket_from_name(&name).await?; + + let result = QResult::success(Core_Unknown); + + let mut hasher = DefaultHasher::new(); + + hasher.write(name.as_bytes()); + + let Ok(addr) = self.control_server.get_url(hasher.finish()).await else { + warn!("no secure proxies"); + return Err(ErrorCode::Core_Exception); + }; + + let connection_data = ConnectionDataOld { + station_url: station_url_from_sock_addr(addr), + special_station_url: "".to_string(), + special_protocols: Vec::new(), + }; + + let ret = ( + result, + pid, + ticket.into(), + connection_data, + self.build_name.to_string(), + ); + + info!("data: {:?}", ret); + Ok(ret) + } + + async fn login_ex( + &self, + name: String, + _extra_data: Any, ) -> Result<(QResult, u32, Vec, ConnectionData, String), ErrorCode> { let (pid, ticket) = self.generate_ticket_from_name(&name).await?; @@ -152,14 +196,6 @@ impl Auth for AuthHandler { Ok(ret) } - async fn login_ex( - &self, - name: String, - _extra_data: Any, - ) -> Result<(QResult, u32, Vec, ConnectionData, String), ErrorCode> { - self.login(name).await - } - async fn request_ticket( &self, source_pid: u32, diff --git a/rnex-core/src/nex/common.rs b/rnex-core/src/nex/common.rs new file mode 100644 index 0000000..d2fa40f --- /dev/null +++ b/rnex-core/src/nex/common.rs @@ -0,0 +1,93 @@ +use rnex_core::prudp::station_url::StationUrl; +use rnex_core::prudp::station_url::UrlOptions::{ + Address, NatFiltering, NatMapping, NatType, Port, PrincipalID, RVConnectionID, +}; +use rnex_core::prudp::station_url::nat_types::PUBLIC; +use rnex_core::rmc::response::ErrorCode::Core_Exception; + +use rnex_core::prudp::socket_addr::PRUDPSockAddr; +use rnex_core::rmc::response::ErrorCode; + +pub async fn get_station_urls( + station_urls: &[StationUrl], + addr: PRUDPSockAddr, + pid: u32, + cid: u32, +) -> Result, ErrorCode> { + let mut public_station: Option = None; + let mut private_station: Option = None; + + for station in station_urls { + let is_public = station.options.iter().any(|v| { + if let NatType(v) = v { + if *v & PUBLIC != 0 { + return true; + } + } + false + }); + + let Some(nat_filtering) = station.options.iter().find_map(|v| match v { + NatFiltering(v) => Some(v), + _ => None, + }) else { + return Err(Core_Exception); + }; + + let Some(nat_mapping) = station.options.iter().find_map(|v| match v { + NatMapping(v) => Some(v), + _ => None, + }) else { + return Err(Core_Exception); + }; + + if !is_public || (*nat_filtering == 0 && *nat_mapping == 0) { + private_station = Some(station.clone()); + } + + if is_public { + public_station = Some(station.clone()); + } + } + + let Some(mut private_station) = private_station else { + return Err(Core_Exception); + }; + + let mut public_station = if let Some(public_station) = public_station { + public_station + } else { + let mut public_station = private_station.clone(); + + public_station.options.retain(|v| match v { + Address(_) | Port(_) | NatFiltering(_) | NatMapping(_) | NatType(_) => false, + _ => true, + }); + + public_station + .options + .push(Address(*addr.regular_socket_addr.ip())); + public_station + .options + .push(Port(addr.regular_socket_addr.port())); + public_station.options.push(NatFiltering(0)); + public_station.options.push(NatMapping(0)); + public_station.options.push(NatType(3)); + + public_station + }; + + let both = [&mut public_station, &mut private_station]; + + for station in both { + station.options.retain(|v| match v { + PrincipalID(_) | RVConnectionID(_) => false, + _ => true, + }); + + station.options.push(PrincipalID(pid)); + station.options.push(RVConnectionID(cid)); + } + + Ok(vec![public_station]) +} diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs new file mode 100644 index 0000000..a2d42ca --- /dev/null +++ b/rnex-core/src/nex/friends_handler.rs @@ -0,0 +1,160 @@ +use std::sync::{Arc, atomic::AtomicU32}; +use std::time::Duration; + +use log::info; +use macros::rmc_struct; +use rnex_core::rmc::protocols::friends::{Friends, RawFriends, RawFriendsInfo, RemoteFriends}; +use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; +use rnex_core::{ + define_rmc_proto, + kerberos::KerberosDateTime, + nex::common::get_station_urls, + prudp::{socket_addr::PRUDPSockAddr, station_url::StationUrl}, + rmc::{ + protocols::friends::{ + BlacklistedPrincipal, Comment, FriendInfo, FriendRequest, NNAInfo, NintendoPresenceV2, + PersistentNotification, PrincipalPreference, + }, + response::ErrorCode, + structures::{any::Any, qresult::QResult}, + }, +}; +use std::sync::atomic::Ordering::Relaxed; +use tokio::time::sleep; + +use rnex_core::rmc::protocols::friends::{GameKey, MiiV2, PrincipalBasicInfo}; + +define_rmc_proto!( + proto FriendsUser{ + Secure, + Friends + } +); +#[rmc_struct(FriendsUser)] +pub struct FriendsUser { + pub fm: Arc, + pub addr: PRUDPSockAddr, + pub pid: u32, +} + +pub struct FriendsManager { + pub cid_counter: AtomicU32, +} + +impl FriendsManager { + pub fn next_cid(&self) -> u32 { + self.cid_counter.fetch_add(1, Relaxed) + } +} + +impl Friends for FriendsUser { + async fn update_and_get_all_information( + &self, + info: NNAInfo, + presence: NintendoPresenceV2, + date_time: KerberosDateTime, + ) -> Result< + ( + PrincipalPreference, + Comment, + Vec, + Vec, + Vec, + Vec, + bool, + Vec, + bool, + ), + ErrorCode, + > { + Ok(( + PrincipalPreference { + block_friend_request: false, + show_online: false, + show_playing_title: false, + }, + Comment { + last_changed: KerberosDateTime::now(), + message: "".to_string(), + unk: 0, + }, + vec![FriendInfo { + became_friends: KerberosDateTime::now(), + comment: Comment { + last_changed: KerberosDateTime::now(), + message: "I'm just a dummy account :3".to_string(), + unk: 0, + }, + last_online: KerberosDateTime::now(), + nna_info: NNAInfo { + principal_basic_info: PrincipalBasicInfo { + pid: 101, + nnid: "dummyaccount".to_string(), + mii: MiiV2{ + date_time: KerberosDateTime::now(), + name: "Dummy Account".to_string(), + mii_data: hex::decode("030000402bd7c32986a771f2dc6b35e31da15e37ff7c0000391e6f006f006d0069000000000000000000000000004040001065033568641e2013661a611821640f0000290052485000000000000000000000000000000000000000000000e838").unwrap(), + unk: 0, + unk2: 0, + }, + unk: 0 + }, + unk: 0, + unk2: 0 + }, + presence: NintendoPresenceV2{ + changed_flags: 0, + message: "".to_string(), + app_data: vec![], + game_key: GameKey{ + tid: 0x00050002101ce400, + version: 0x0 + }, + game_server_id: 0, + is_online: true, + gid: 0, + pid: 101, + unk: 0, + unk2: 0, + unk3: 0, + unk4: 0, + unk5: 0, + unk6: 0, + unk7: 0 + }, + unk: 0 + }], + vec![], + vec![], + vec![], + false, + vec![], + false, + )) + } +} + +impl Secure for FriendsUser { + async fn register( + &self, + station_urls: Vec, + ) -> Result<(QResult, u32, StationUrl), ErrorCode> { + let cid = self.fm.next_cid(); + Ok(( + QResult::success(ErrorCode::Core_Unknown), + cid, + get_station_urls(&station_urls, self.addr, self.pid, cid).await?[0].clone(), + )) + } + async fn register_ex( + &self, + station_urls: Vec, + data: Any, + ) -> Result<(QResult, u32, StationUrl), ErrorCode> { + info!("register"); + self.register(station_urls).await + } + async fn replace_url(&self, target: StationUrl, dest: StationUrl) -> Result<(), ErrorCode> { + Err(ErrorCode::Core_NotImplemented) + } +} diff --git a/rnex-core/src/nex/mod.rs b/rnex-core/src/nex/mod.rs index 76791bc..0f52c13 100644 --- a/rnex-core/src/nex/mod.rs +++ b/rnex-core/src/nex/mod.rs @@ -1,5 +1,7 @@ pub mod account; pub mod auth_handler; -pub mod user; +pub mod common; +pub mod friends_handler; +pub mod matchmake; pub mod remote_console; -pub mod matchmake; \ No newline at end of file +pub mod user; diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 221c90a..1666d56 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -1,4 +1,5 @@ use crate::define_rmc_proto; +use crate::nex::common::get_station_urls; use crate::nex::matchmake::{ExtendedMatchmakeSession, MatchmakeManager}; use crate::nex::remote_console::RemoteConsole; use crate::rmc::protocols::matchmake::{ @@ -21,6 +22,7 @@ use rnex_core::rmc::protocols::matchmake_extension::{ use rnex_core::rmc::protocols::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking}; use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::structures::any::Any; use rnex_core::rmc::structures::matchmake::{ AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession, }; @@ -71,97 +73,27 @@ impl Secure for User { users.insert(cid, self.this.clone()); drop(users); - let mut public_station: Option = None; - let mut private_station: Option = None; + let stations = get_station_urls(&station_urls, self.ip, self.pid, cid).await?; - for station in station_urls { - let is_public = station.options.iter().any(|v| { - if let NatType(v) = v { - if *v & PUBLIC != 0 { - return true; - } - } - false - }); - - let Some(nat_filtering) = station.options.iter().find_map(|v| match v { - NatFiltering(v) => Some(v), - _ => None, - }) else { - return Err(Core_Exception); - }; - - let Some(nat_mapping) = station.options.iter().find_map(|v| match v { - NatMapping(v) => Some(v), - _ => None, - }) else { - return Err(Core_Exception); - }; - - if !is_public || (*nat_filtering == 0 && *nat_mapping == 0) { - private_station = Some(station.clone()); - } - - if is_public { - public_station = Some(station); - } - } - - let Some(mut private_station) = private_station else { - return Err(Core_Exception); - }; - - let mut public_station = if let Some(public_station) = public_station { - public_station - } else { - let mut public_station = private_station.clone(); - - public_station.options.retain(|v| match v { - Address(_) | Port(_) | NatFiltering(_) | NatMapping(_) | NatType(_) => false, - _ => true, - }); - - public_station - .options - .push(Address(*self.ip.regular_socket_addr.ip())); - public_station - .options - .push(Port(self.ip.regular_socket_addr.port())); - public_station.options.push(NatFiltering(0)); - public_station.options.push(NatMapping(0)); - public_station.options.push(NatType(3)); - - public_station - }; - - let both = [&mut public_station, &mut private_station]; - - for station in both { - station.options.retain(|v| match v { - PrincipalID(_) | RVConnectionID(_) => false, - _ => true, - }); - - station.options.push(PrincipalID(self.pid)); - station.options.push(RVConnectionID(cid)); - } + let first = stations.first().unwrap().clone(); let mut lock = self.station_url.write().await; - *lock = vec![ - public_station.clone(), - // private_station.clone() - ]; + *lock = stations; drop(lock); let result = QResult::success(ErrorCode::Core_Unknown); - let out = public_station.to_string(); + Ok((result, cid, first)) + } - println!("out: {}", out); - - Ok((result, cid, public_station)) + async fn register_ex( + &self, + station_urls: Vec, + _data: Any, + ) -> Result<(QResult, u32, StationUrl), ErrorCode> { + self.register(station_urls).await } async fn replace_url(&self, target_url: StationUrl, dest: StationUrl) -> Result<(), ErrorCode> { diff --git a/rnex-core/src/prudp/mod.rs b/rnex-core/src/prudp/mod.rs index fdc991a..501463a 100644 --- a/rnex-core/src/prudp/mod.rs +++ b/rnex-core/src/prudp/mod.rs @@ -1,5 +1,6 @@ pub mod encryption; pub mod socket_addr; pub mod station_url; +pub mod ticket; pub mod types_flags; pub mod virtual_port; diff --git a/rnex-core/src/prudp/socket_addr.rs b/rnex-core/src/prudp/socket_addr.rs index f5eb179..4ffac83 100644 --- a/rnex-core/src/prudp/socket_addr.rs +++ b/rnex-core/src/prudp/socket_addr.rs @@ -1,26 +1,24 @@ +use hmac::Hmac; +use macros::RmcSerialize; +use md5::digest::Mac; +use rnex_core::prudp::virtual_port::VirtualPort; use std::io::Write; use std::net::SocketAddrV4; -use hmac::{Hmac}; -use md5::digest::Mac; -use macros::RmcSerialize; -use rnex_core::prudp::virtual_port::VirtualPort; type Md5Hmac = Hmac; #[derive(Eq, PartialEq, Hash, Debug, Copy, Clone, Ord, PartialOrd, RmcSerialize)] #[rmc_struct(0)] -pub struct PRUDPSockAddr{ +pub struct PRUDPSockAddr { pub regular_socket_addr: SocketAddrV4, - pub virtual_port: VirtualPort + pub virtual_port: VirtualPort, } - - -impl PRUDPSockAddr{ - pub fn new(regular_socket_addr: SocketAddrV4, virtual_port: VirtualPort) -> Self{ - Self{ +impl PRUDPSockAddr { + pub fn new(regular_socket_addr: SocketAddrV4, virtual_port: VirtualPort) -> Self { + Self { regular_socket_addr, - virtual_port + virtual_port, } } @@ -30,8 +28,11 @@ impl PRUDPSockAddr{ let data = self.regular_socket_addr.ip().octets().to_vec(); //data.extend_from_slice(&self.regular_socket_addr.port().to_be_bytes()); - hmac.write_all(&data).expect("figuring this out was complete ass"); - let result: [u8; 16] = hmac.finalize().into_bytes()[0..16].try_into().expect("fuck"); + hmac.write_all(&data) + .expect("figuring this out was complete ass"); + let result: [u8; 16] = hmac.finalize().into_bytes()[0..16] + .try_into() + .expect("fuck"); result } -} \ No newline at end of file +} diff --git a/rnex-core/src/prudp/ticket.rs b/rnex-core/src/prudp/ticket.rs new file mode 100644 index 0000000..9fd094d --- /dev/null +++ b/rnex-core/src/prudp/ticket.rs @@ -0,0 +1,81 @@ +use std::io::Cursor; + +use log::{error, info}; +use rc4::{KeyInit, Rc4, Rc4Core, StreamCipher, cipher::StreamCipherCoreWrapper}; +use typenum::{U16, U32}; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; + +use crate::{ + kerberos::{SESSION_KEY_LENGTH, SESSION_KEY_LENGTH_TY, TicketInternalData, derive_key}, + nex::account::Account, + rmc::structures::RmcSerialize, +}; + +pub fn read_secure_connection_data( + data: &[u8], + act: &Account, +) -> Option<([u8; SESSION_KEY_LENGTH], u32, u32)> { + let mut cursor = Cursor::new(data); + + let mut ticket_data: Vec = Vec::deserialize(&mut cursor).ok()?; + let mut request_data: Vec = Vec::deserialize(&mut cursor).ok()?; + info!( + "done + request data" + ); + + let ticket_data_size = ticket_data.len(); + + let ticket_data = &mut ticket_data[0..ticket_data_size - 0x10]; + + let server_key = derive_key(act.pid, &act.kerbros_password[..]); + + let mut rc4: StreamCipherCoreWrapper> = + Rc4::new_from_slice(&server_key).expect("unable to init rc4 keystream"); + + rc4.apply_keystream(ticket_data); + + let ticket_data: &TicketInternalData = match bytemuck::try_from_bytes(ticket_data) { + Ok(v) => v, + Err(e) => { + error!("unable to read internal ticket data: {}", e); + return None; + } + }; + + // todo: add ticket expiration + + let TicketInternalData { + session_key, + pid: ticket_source_pid, + issued_time, + } = *ticket_data; + + // todo: add checking if tickets are signed with a valid md5-hmac + let request_data_length = request_data.len(); + let request_data = &mut request_data[0..request_data_length - 0x10]; + + let mut rc4: StreamCipherCoreWrapper> = + Rc4::new_from_slice(&session_key).expect("unable to init rc4 keystream"); + + rc4.apply_keystream(request_data); + + let mut reqest_data_cursor = Cursor::new(request_data); + + let pid: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?; + + if pid != ticket_source_pid { + let ticket_created_on = issued_time.to_regular_time(); + + error!( + "someone tried to spoof their pid, ticket was created on: {}", + ticket_created_on.to_rfc2822() + ); + return None; + } + + let _cid: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?; + let response_check: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?; + + Some((session_key, pid, response_check)) +} diff --git a/rnex-core/src/rmc/protocols/auth.rs b/rnex-core/src/rmc/protocols/auth.rs index 774f1f9..594d9dd 100644 --- a/rnex-core/src/rmc/protocols/auth.rs +++ b/rnex-core/src/rmc/protocols/auth.rs @@ -1,4 +1,4 @@ -use crate::rmc::structures::connection_data::ConnectionData; +use crate::rmc::structures::connection_data::{ConnectionData, ConnectionDataOld}; use macros::{method_id, rmc_proto}; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::any::Any; @@ -14,7 +14,7 @@ pub trait Auth { async fn login( &self, name: String, - ) -> Result<(QResult, u32, Vec, ConnectionData, String), ErrorCode>; + ) -> Result<(QResult, u32, Vec, ConnectionDataOld, String), ErrorCode>; /// representation of the `LoginEx` method(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) diff --git a/rnex-core/src/rmc/protocols/friends.rs b/rnex-core/src/rmc/protocols/friends.rs new file mode 100644 index 0000000..775016e --- /dev/null +++ b/rnex-core/src/rmc/protocols/friends.rs @@ -0,0 +1,146 @@ +use macros::{RmcSerialize, method_id, rmc_proto}; + +use rnex_core::{kerberos::KerberosDateTime, rmc::response::ErrorCode}; + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct MiiV2 { + pub name: String, + pub unk: u8, + pub unk2: u8, + pub mii_data: Vec, + pub date_time: KerberosDateTime, +} + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct PrincipalBasicInfo { + pub pid: u32, + pub nnid: String, + pub mii: MiiV2, + pub unk: u8, +} + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct NNAInfo { + pub principal_basic_info: PrincipalBasicInfo, + pub unk: u8, + pub unk2: u8, +} + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct GameKey { + pub tid: u64, + pub version: u16, +} + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct NintendoPresenceV2 { + pub changed_flags: u32, + pub is_online: bool, + pub game_key: GameKey, + pub unk: u8, + pub message: String, + pub unk2: u32, + pub unk3: u8, + pub game_server_id: u32, + pub unk4: u32, + pub pid: u32, + pub gid: u32, + pub app_data: Vec, + pub unk5: u8, + pub unk6: u8, + pub unk7: u8, +} +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct PrincipalPreference { + pub show_online: bool, + pub show_playing_title: bool, + pub block_friend_request: bool, +} + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct Comment { + pub unk: u8, + pub message: String, + pub last_changed: KerberosDateTime, +} + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct FriendInfo { + pub nna_info: NNAInfo, + pub presence: NintendoPresenceV2, + pub comment: Comment, + pub became_friends: KerberosDateTime, + pub last_online: KerberosDateTime, + pub unk: u64, +} + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct FriendRequestMessage { + pub friend_request_id: u64, + pub is_recieved: u8, + pub unk: u8, + pub message: String, + pub unk2: u8, + pub unk3: String, + pub game_key: GameKey, + pub unk4: KerberosDateTime, + pub expires_on: KerberosDateTime, +} + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct FriendRequest { + pub basic_info: PrincipalBasicInfo, + pub request_message: FriendRequestMessage, + pub sent_on: KerberosDateTime, +} + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct BlacklistedPrincipal { + pub basic_info: PrincipalBasicInfo, + pub game_key: GameKey, + pub since: KerberosDateTime, +} +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct PersistentNotification { + pub unk1: u64, + pub unk2: u32, + pub unk3: u32, + pub unk4: u32, + pub unk5: String, +} + +#[rmc_proto(102)] +pub trait Friends { + #[method_id(1)] + async fn update_and_get_all_information( + &self, + info: NNAInfo, + presence: NintendoPresenceV2, + date_time: KerberosDateTime, + ) -> Result< + ( + PrincipalPreference, + Comment, + Vec, + Vec, + Vec, + Vec, + bool, + Vec, + bool, + ), + ErrorCode, + >; +} diff --git a/rnex-core/src/rmc/protocols/mod.rs b/rnex-core/src/rmc/protocols/mod.rs index fb0f055..6896cf3 100644 --- a/rnex-core/src/rmc/protocols/mod.rs +++ b/rnex-core/src/rmc/protocols/mod.rs @@ -1,6 +1,7 @@ #![allow(async_fn_in_trait)] pub mod auth; +pub mod friends; pub mod matchmake; pub mod matchmake_ext; pub mod matchmake_extension; @@ -294,8 +295,8 @@ async fn handle_incoming( } = message; info!( - "RMC REQUEST: Proto: {}; Method: {};", - protocol_id, method_id + "RMC REQUEST: Proto: {}; Method: {}; cid: {}", + protocol_id, method_id, call_id ); remote diff --git a/rnex-core/src/rmc/protocols/secure.rs b/rnex-core/src/rmc/protocols/secure.rs index 50afb5b..3df23c6 100644 --- a/rnex-core/src/rmc/protocols/secure.rs +++ b/rnex-core/src/rmc/protocols/secure.rs @@ -3,10 +3,21 @@ use rnex_core::prudp::station_url::StationUrl; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::qresult::QResult; +use crate::rmc::structures::any::Any; + #[rmc_proto(11)] pub trait Secure { #[method_id(1)] - async fn register(&self, station_urls: Vec) -> Result<(QResult, u32, StationUrl), ErrorCode>; + async fn register( + &self, + station_urls: Vec, + ) -> Result<(QResult, u32, StationUrl), ErrorCode>; + #[method_id(4)] + async fn register_ex( + &self, + station_urls: Vec, + data: Any, + ) -> Result<(QResult, u32, StationUrl), ErrorCode>; #[method_id(7)] async fn replace_url(&self, target: StationUrl, dest: StationUrl) -> Result<(), ErrorCode>; } diff --git a/rnex-core/src/rmc/structures/any.rs b/rnex-core/src/rmc/structures/any.rs index b60ca8a..c4dc2ce 100644 --- a/rnex-core/src/rmc/structures/any.rs +++ b/rnex-core/src/rmc/structures/any.rs @@ -1,14 +1,14 @@ +use rnex_core::rmc::structures::{Result, RmcSerialize}; use std::io::{Read, Write}; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -use super::{Result, RmcSerialize}; #[derive(Debug, Default)] -pub struct Any{ +pub struct Any { pub name: String, - pub data: Vec + pub data: Vec, } -impl RmcSerialize for Any{ +impl RmcSerialize for Any { fn serialize(&self, writer: &mut impl Write) -> Result<()> { self.name.serialize(writer)?; @@ -32,11 +32,6 @@ impl RmcSerialize for Any{ reader.read_exact(&mut data)?; - Ok( - Any{ - name, - data - } - ) + Ok(Any { name, data }) } -} \ No newline at end of file +} diff --git a/rnex-core/src/rmc/structures/buffer.rs b/rnex-core/src/rmc/structures/buffer.rs index 085f053..c147133 100644 --- a/rnex-core/src/rmc/structures/buffer.rs +++ b/rnex-core/src/rmc/structures/buffer.rs @@ -1,10 +1,9 @@ -use std::io::{Read, Write}; +use crate::rmc::structures::Result; use crate::rmc::structures::RmcSerialize; +use std::io::{Read, Write}; - - -impl<'a> RmcSerialize for &'a [u8]{ - fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { +impl<'a> RmcSerialize for &'a [u8] { + fn serialize(&self, writer: &mut impl Write) -> Result<()> { let u32_size = self.len() as u32; writer.write(bytemuck::bytes_of(&u32_size))?; writer.write(self)?; @@ -13,25 +12,25 @@ impl<'a> RmcSerialize for &'a [u8]{ } /// DO NOT USE (also maybe split off the serialize and deserialize functions at some point) - fn deserialize(_reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(_reader: &mut impl Read) -> Result { panic!("cannot deserialize to a u8 slice reference (use this ONLY for writing)") } - fn serialize_write_size(&self) -> crate::rmc::structures::Result { + fn serialize_write_size(&self) -> Result { Ok(4 + self.len() as u32) } } -impl RmcSerialize for Box<[u8]>{ - fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { +impl RmcSerialize for Box<[u8]> { + fn serialize(&self, writer: &mut impl Write) -> Result<()> { (&self[..]).serialize(writer) } - fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { + fn deserialize(reader: &mut impl Read) -> Result { Vec::deserialize(reader).map(|v| v.into_boxed_slice()) } - fn serialize_write_size(&self) -> crate::rmc::structures::Result { + fn serialize_write_size(&self) -> Result { (&self[..]).serialize_write_size() } -} \ No newline at end of file +} diff --git a/rnex-core/src/rmc/structures/connection_data.rs b/rnex-core/src/rmc/structures/connection_data.rs index da6a17b..d134e85 100644 --- a/rnex-core/src/rmc/structures/connection_data.rs +++ b/rnex-core/src/rmc/structures/connection_data.rs @@ -1,13 +1,19 @@ - use macros::RmcSerialize; use rnex_core::kerberos::KerberosDateTime; #[derive(Debug, RmcSerialize)] #[rmc_struct(1)] -pub struct ConnectionData{ +pub struct ConnectionData { pub station_url: String, pub special_protocols: Vec, pub special_station_url: String, - pub date_time: KerberosDateTime + pub date_time: KerberosDateTime, } +#[derive(Debug, RmcSerialize)] +#[rmc_struct(1)] +pub struct ConnectionDataOld { + pub station_url: String, + pub special_protocols: Vec, + pub special_station_url: String, +} diff --git a/rnex-core/src/rmc/structures/primitives.rs b/rnex-core/src/rmc/structures/primitives.rs index 8918968..3bdd835 100644 --- a/rnex-core/src/rmc/structures/primitives.rs +++ b/rnex-core/src/rmc/structures/primitives.rs @@ -1,9 +1,9 @@ -use std::io::{Read, Write}; -use bytemuck::bytes_of; -use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::rmc::structures::RmcSerialize; +use bytemuck::bytes_of; +use std::io::{Read, Write}; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -impl RmcSerialize for u8{ +impl RmcSerialize for u8 { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) @@ -19,7 +19,7 @@ impl RmcSerialize for u8{ } } -impl RmcSerialize for i8{ +impl RmcSerialize for i8 { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) @@ -35,7 +35,7 @@ impl RmcSerialize for i8{ } } -impl RmcSerialize for u16{ +impl RmcSerialize for u16 { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) @@ -50,7 +50,7 @@ impl RmcSerialize for u16{ } } -impl RmcSerialize for i16{ +impl RmcSerialize for i16 { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) @@ -65,7 +65,7 @@ impl RmcSerialize for i16{ } } -impl RmcSerialize for u32{ +impl RmcSerialize for u32 { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) @@ -80,7 +80,7 @@ impl RmcSerialize for u32{ } } -impl RmcSerialize for i32{ +impl RmcSerialize for i32 { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) @@ -95,7 +95,7 @@ impl RmcSerialize for i32{ } } -impl RmcSerialize for u64{ +impl RmcSerialize for u64 { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) @@ -110,7 +110,7 @@ impl RmcSerialize for u64{ } } -impl RmcSerialize for i64{ +impl RmcSerialize for i64 { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) @@ -125,7 +125,7 @@ impl RmcSerialize for i64{ } } -impl RmcSerialize for f64{ +impl RmcSerialize for f64 { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { Ok(writer.write_all(bytes_of(self))?) @@ -141,10 +141,10 @@ impl RmcSerialize for f64{ } } -impl RmcSerialize for bool{ +impl RmcSerialize for bool { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { - match self{ + match self { true => writer.write_all(&[1])?, false => writer.write_all(&[0])?, } @@ -161,8 +161,7 @@ impl RmcSerialize for bool{ } } - -impl RmcSerialize for (T, U){ +impl RmcSerialize for (T, U) { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; @@ -178,14 +177,11 @@ impl RmcSerialize for (T, U){ } #[inline(always)] fn serialize_write_size(&self) -> crate::rmc::structures::Result { - Ok( - self.0.serialize_write_size()? + - self.1.serialize_write_size()? - ) + Ok(self.0.serialize_write_size()? + self.1.serialize_write_size()?) } } -impl RmcSerialize for (T, U, V){ +impl RmcSerialize for (T, U, V) { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; @@ -203,15 +199,15 @@ impl RmcSerialize for (T, U, } #[inline(always)] fn serialize_write_size(&self) -> crate::rmc::structures::Result { - Ok( - self.0.serialize_write_size()? + - self.1.serialize_write_size()? + - self.2.serialize_write_size()? - ) + Ok(self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()?) } } -impl RmcSerialize for (T, U, V, W){ +impl RmcSerialize + for (T, U, V, W) +{ #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; @@ -231,16 +227,16 @@ impl RmcSeri } #[inline(always)] fn serialize_write_size(&self) -> crate::rmc::structures::Result { - Ok( - self.0.serialize_write_size()? + - self.1.serialize_write_size()? + - self.2.serialize_write_size()? + - self.3.serialize_write_size()? - ) + Ok(self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()? + + self.3.serialize_write_size()?) } } -impl RmcSerialize for (T, U, V, W, X){ +impl + RmcSerialize for (T, U, V, W, X) +{ #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; @@ -264,17 +260,23 @@ impl crate::rmc::structures::Result { - Ok( - self.0.serialize_write_size()? + - self.1.serialize_write_size()? + - self.2.serialize_write_size()? + - self.2.serialize_write_size()? + - self.3.serialize_write_size()? - ) + Ok(self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()? + + self.2.serialize_write_size()? + + self.3.serialize_write_size()?) } } -impl RmcSerialize for (T, U, V, W, X, Y){ +impl< + T: RmcSerialize, + U: RmcSerialize, + V: RmcSerialize, + W: RmcSerialize, + X: RmcSerialize, + Y: RmcSerialize, +> RmcSerialize for (T, U, V, W, X, Y) +{ #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; @@ -300,18 +302,25 @@ impl crate::rmc::structures::Result { - Ok( - self.0.serialize_write_size()? + - self.1.serialize_write_size()? + - self.2.serialize_write_size()? + - self.3.serialize_write_size()? + - self.4.serialize_write_size()? + - self.5.serialize_write_size()? - ) + Ok(self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()? + + self.3.serialize_write_size()? + + self.4.serialize_write_size()? + + self.5.serialize_write_size()?) } } -impl RmcSerialize for (T, U, V, W, X, Y, Z){ +impl< + T: RmcSerialize, + U: RmcSerialize, + V: RmcSerialize, + W: RmcSerialize, + X: RmcSerialize, + Y: RmcSerialize, + Z: RmcSerialize, +> RmcSerialize for (T, U, V, W, X, Y, Z) +{ #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; @@ -338,19 +347,123 @@ impl crate::rmc::structures::Result { - Ok( - self.0.serialize_write_size()? + - self.1.serialize_write_size()? + - self.2.serialize_write_size()? + - self.3.serialize_write_size()? + - self.4.serialize_write_size()? + - self.5.serialize_write_size()? + - self.6.serialize_write_size()? - ) + Ok(self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()? + + self.3.serialize_write_size()? + + self.4.serialize_write_size()? + + self.5.serialize_write_size()? + + self.6.serialize_write_size()?) } } -impl RmcSerialize for Box{ +impl< + T: RmcSerialize, + U: RmcSerialize, + V: RmcSerialize, + W: RmcSerialize, + X: RmcSerialize, + Y: RmcSerialize, + Z: RmcSerialize, + A: RmcSerialize, +> RmcSerialize for (T, U, V, W, X, Y, Z, A) +{ + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { + self.0.serialize(writer)?; + self.1.serialize(writer)?; + self.2.serialize(writer)?; + self.3.serialize(writer)?; + self.4.serialize(writer)?; + self.5.serialize(writer)?; + self.6.serialize(writer)?; + self.7.serialize(writer)?; + + Ok(()) + } + #[inline(always)] + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { + let first = T::deserialize(reader)?; + let second = U::deserialize(reader)?; + let third = V::deserialize(reader)?; + let fourth = W::deserialize(reader)?; + let fifth = X::deserialize(reader)?; + let sixth = Y::deserialize(reader)?; + let seventh = Z::deserialize(reader)?; + let eighth = A::deserialize(reader)?; + + Ok((first, second, third, fourth, fifth, sixth, seventh, eighth)) + } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()? + + self.3.serialize_write_size()? + + self.4.serialize_write_size()? + + self.5.serialize_write_size()? + + self.6.serialize_write_size()? + + self.7.serialize_write_size()?) + } +} + +impl< + T: RmcSerialize, + U: RmcSerialize, + V: RmcSerialize, + W: RmcSerialize, + X: RmcSerialize, + Y: RmcSerialize, + Z: RmcSerialize, + A: RmcSerialize, + B: RmcSerialize, +> RmcSerialize for (T, U, V, W, X, Y, Z, A, B) +{ + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { + self.0.serialize(writer)?; + self.1.serialize(writer)?; + self.2.serialize(writer)?; + self.3.serialize(writer)?; + self.4.serialize(writer)?; + self.5.serialize(writer)?; + self.6.serialize(writer)?; + self.7.serialize(writer)?; + self.8.serialize(writer)?; + + Ok(()) + } + #[inline(always)] + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { + let first = T::deserialize(reader)?; + let second = U::deserialize(reader)?; + let third = V::deserialize(reader)?; + let fourth = W::deserialize(reader)?; + let fifth = X::deserialize(reader)?; + let sixth = Y::deserialize(reader)?; + let seventh = Z::deserialize(reader)?; + let eighth = A::deserialize(reader)?; + let nineth = B::deserialize(reader)?; + + Ok(( + first, second, third, fourth, fifth, sixth, seventh, eighth, nineth, + )) + } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(self.0.serialize_write_size()? + + self.1.serialize_write_size()? + + self.2.serialize_write_size()? + + self.3.serialize_write_size()? + + self.4.serialize_write_size()? + + self.5.serialize_write_size()? + + self.6.serialize_write_size()? + + self.7.serialize_write_size()? + + self.8.serialize_write_size()?) + } +} + +impl RmcSerialize for Box { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.as_ref().serialize(writer) @@ -363,4 +476,4 @@ impl RmcSerialize for Box{ fn serialize_write_size(&self) -> crate::rmc::structures::Result { T::serialize_write_size(self.as_ref()) } -} \ No newline at end of file +} diff --git a/rnex-core/src/rmc/structures/variant.rs b/rnex-core/src/rmc/structures/variant.rs index 6056f3f..9f705d0 100644 --- a/rnex-core/src/rmc/structures/variant.rs +++ b/rnex-core/src/rmc/structures/variant.rs @@ -1,10 +1,10 @@ +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::rmc::structures; +use rnex_core::rmc::structures::{Result, RmcSerialize}; use std::io::{Read, Write}; -use crate::kerberos::KerberosDateTime; -use crate::rmc::structures; -use crate::rmc::structures::RmcSerialize; #[derive(Debug, Clone, Default)] -pub enum Variant{ +pub enum Variant { #[default] None, SInt64(i64), @@ -15,9 +15,9 @@ pub enum Variant{ UInt64(u64), } -impl RmcSerialize for Variant{ - fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { - match self{ +impl RmcSerialize for Variant { + fn serialize(&self, writer: &mut impl Write) -> Result<()> { + match self { Variant::None => { writer.write_all(&[0])?; } @@ -50,8 +50,8 @@ impl RmcSerialize for Variant{ Ok(()) } - fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { - match u8::deserialize(reader)?{ + fn deserialize(reader: &mut impl Read) -> Result { + match u8::deserialize(reader)? { 0 => Ok(Variant::None), 1 => Ok(Variant::SInt64(i64::deserialize(reader)?)), 2 => Ok(Variant::Double(f64::deserialize(reader)?)), @@ -59,7 +59,7 @@ impl RmcSerialize for Variant{ 4 => Ok(Variant::String(String::deserialize(reader)?)), 5 => Ok(Variant::DateTime(KerberosDateTime::deserialize(reader)?)), 6 => Ok(Variant::UInt64(u64::deserialize(reader)?)), - v => Err(structures::Error::UnexpectedValue(v as u64)) + v => Err(structures::Error::UnexpectedValue(v as u64)), } } -} \ No newline at end of file +} From 7e3cade00e3d8506cbf6b607658bfea6fbcaf1b3 Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 1 Feb 2026 21:10:03 +0100 Subject: [PATCH 056/203] fix forgetting to save file --- .ci-scripts/make-edition.sh | 4 +- Cargo.lock | 1 + out/backend_server_secure | Bin 0 -> 2005008 bytes proxy/src/insecure.rs | 2 - prudpv0/src/crypto/friends_insecure.rs | 15 +++-- prudpv0/src/crypto/friends_secure.rs | 52 ++++++++++++--- prudpv0/src/crypto/mod.rs | 2 +- prudpv0/src/packet.rs | 21 +++++- prudpv0/src/server.rs | 57 ++++++++-------- prudpv1/src/prudp/secure.rs | 63 +----------------- .../executables/backend_server_insecure.rs | 28 +++++--- 11 files changed, 124 insertions(+), 121 deletions(-) create mode 100755 out/backend_server_secure diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh index f595e5e..57c857a 100755 --- a/.ci-scripts/make-edition.sh +++ b/.ci-scripts/make-edition.sh @@ -3,8 +3,8 @@ export EDITION=$1 export BA="--build-arg EDITION=$1" -podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . -podman push "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" +# podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . +# podman push "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" --target=node-holder . podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" --target=proxy-secure . podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" --target=proxy-insecure . diff --git a/Cargo.lock b/Cargo.lock index 53c829e..b7ebf9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -672,6 +672,7 @@ version = "0.1.1" dependencies = [ "anyhow", "bytemuck", + "cfg-if", "chrono", "dotenv", "hex", diff --git a/out/backend_server_secure b/out/backend_server_secure new file mode 100755 index 0000000000000000000000000000000000000000..be14059810d86e98b2f98e8d87b12bef6bae892f GIT binary patch literal 2005008 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

=q~6cX!&E7%KanvbpweH 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 z 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�Y5uT566IyM{ZR8(uccDvQ|)J2$R4SH&AUrqRj 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

nQ{Jju+qp@IhHTW*uSl=I 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


RYsHSDH#Y5KpYp&Ot*zbrfR z_2pKx+@G7B&_+KLBQ=u(ov2hj$o?078e44_00|JyaZDm+ifJ(s*~J)#<{K-Mi6T*H zc?q2ii03)uek$^-hi+ub#(XDN=J+o8DMMp zTCu<1Dcs6Y{^+P7pz9U1p;S{p2Cf7}ixbALXgO2%C}EiuCIu^I%6>^o;YubW&Ue*2 z#73Pj)d7-{%CWH|!#8Pnm6XKgfMkONrcyin4%>)uS38WkV)KW}E>OB9of{345kE?m zFlBAqg7)Mb9h1?x(d}wmO03T){_rZBb_<8#D7UQfd-}S7N}a#Wbb|@mrwD zTuoB`Mb&T^f?Pf^wfi_Cvqa--;JPtKjJ2PbtJ4lWg25#R1wwTl;6;&A(by1@NbYB75FP-S| z8l^!G#_b|cAcJyX22pm|k-3K~T(8f4nX>=BQy7kPPh}Tt8sSUNHNAm%nX-{GscZ|U z?;_dTXR4&qbU2=c^5z8IWXcBeHy49+-|urj%!BzB+n7Kj5pa7XD{-qNfW2*_~5bP%6cuS(bvKu9Bz_*4vnOf{5P%>($$eZ)1cvf>T8Os)UC} zl0jc&71E&>dFtcQONq;|4~gPntuf|M!1sdD zcs*^`E*RyJos73mq%Hc6kr-Q*m_Y8n&?jT%tHziew216Y?9{8s4k~P2FsM3!t28FH zNo{h&U*i-$Y$_@}2d9!jLF<;bKxT{R4H!)JJe6J7G{#tYO+~)7Bk2?+>Z^*RL&nON z=uZdzIf$csaO5q?u%G_qOMeif{#}1YMz{hd+mYA?q$g=|W61Y$R1y;QCU+9~4W%cz5uyD+U38xM(oW6GG#wS$Wy-yXBM zXzn49QCZ?{J^I-B8IVdzdK79)&0>EZDWenC zxspiMZK=8cCKuwBGeKpP0ZwX5eJ7hygoAGFzUQ3cW)yHrRkD54pbm_!5lD%afLdK9 zbLmvz7>j1~82rbw_O%>+H(<6(MGOCzoL@jhtjm;LLzyl<;tHujn2g`4U5VBZEvzPC zXYdIXOOibTk(kpaEXq0H0i4GE&DM~kZp(xSkUhGoZb7dFb$ZPFlxab_XP^Tc$e~N$ZoV>Ho)=_m4O~w79%RfN%`caCC zfy5u3U7R@^hogvt_-HhW>Wcdt^u7;N?hJb~WjB30ci`8O%ARFd!s2s3A2DE@NNat4<^<1$-&a~NT^G8|Q1^&%N1JAyBCX{o15u=hK>GP4-rhtZ& zf0g>9Rv=ThowsTrC(s4Dv#F+F+LX&5JtVX76*KOiHmI;@tbyt0a)B6pD zwRWF9t~)1&gTfOjxr*ZQFX}1+>Dj8t9XMr)f*Qbrftg+r967xl(Kc~kd8RB*6Osx3 z)C*w{(oT3-4>8w0n(j`o2;V9nac(HO*bY~fn5`0H7fU7CPGu_S0bShfCbDyblk8T-?XHyKvN;rB z$^NJ@?Kx3*e?>Jp3?3x`E0N$$9 z9$3~!W?*NBl-V2?aY@#a$95h)JWeroC-)i;#yd#!+CwpU&0`6VDsy7ZR0JQrnVq}) z@iB*2j>|U)-$G&kqc++vy~}TbNt?42;RHB{Pg8jm`$1}!PVJHw?RZqDWV4c5pi^2A z7+GB->A+D4m z4mdU*WJ8a&Cl1Rq3n#TrcT9VYs?~P;nUG%LdL%Y{nq7qR7;X!XxWQ7MqKB+TxOmP4 z6ieJmGR3&7m304q1l#HL>pX979xY1}`QF&r>|rpmm_yaSD0d3eG}LAB#ddAA*K`%R zf{mx~f&Eoo&K#;)tz??CC_ZnZ6!JA2^C!qd;UcvL)}*8y{DmNniH@q0xclHTj_mA7 zohZ4wwx)%X!1+pwb3-S_MR-Y*Qn>C}z)kiU;w>~yxn!*4n=1xk zx0=O_1A|e}RVqMD;H%ca+|M6m*BkTCmeLxy)qZ+AQ#O~UIOCO{3^=hWL8M|ARu z74im7H&Z5fBc|TwM+TdT;=4F3CPNTt?wlMMB`?whQd`lkDp(_F=LgL+X{&FFS$rzH zg5nT{q^qjQ`ehh#A*KHVtNrVfyGbS%a#1Ujww!+Kp3TNBwvoJL4sXGNq@*7=3s^aa+DE@jhr7HrWvWExz@8MEZ3Rz ziVi;qZCc2BPt33V*;UD?@0>`H+-t^B#yWS5s`YOC*2m7D!$Q4P^`^Zi%?~@*gm<#{8GrR)PGT(%CE!AH0s<=HvFPa#L1!csF30DI0y0(g%J6 zXpt6xqo^P^sa}v!Une@Ew7yRuAq0okg@^%wLYkakek#vmt5$HsDC%Wlt+?7J zc3hDKE8Zcy#*S;06wgx?Xar`(Ju0QFT_yU1U}&l+*C~Z{t+-dG6p^sv6}nIx*{bvh zLC2(qlQJq4kuWL}LK_f~Yvg5VqMjdUY7W?tb22ZvDn2ny6O8ARQ9-dW zt%7G;3QAkQ33mhyV{ePoM_( zgA(cpj$Dz)PozH;$wQ{>LvR2yB3S9sAMuF73O|D^4-+ws*U~+a?>ueBcC+Ubk;anVonzZ zGco!*=L)NR1|1i>xSGQp6sZb);yiqJPb``GoZuWT{)hIT!IGKpXEKg(Ib{FP_ zzosx@Za{kaDflo`Hh^lFLbYq}o6DrzbC%P&rRWu}6*#Vgv91y^1s+45XJz;A-y7uf zoHpmLg<8bG4O=vw5-aghMkC_ADMzm*gg=qfo())S-Q;0n8V0t00AcJKObn{I*f;dm zfHA%~REd7C8K;i?nQsOYMKzb$Ma=<@boDV~ZF%8~<;;z*ZN?Zv9MqV05yzt1XAZ+N ze5+aL=QP=-nH89s8)PO=wl6C&3$L8YIURfEWO_1 zA0hTtalVTkteJ6g*S-`Fp2G}e0c-!<3m>ctj*Gm44Xmhu7>k6*C`OBqvTx>k-u23l zJUyx){3J|&z<#j8Jx3%beJ%hI)EQ6ClnYzkA;%W4@f!q}YX{6~|s^`zwSSzl2X#Qlhs!G?qsbt34_Zk!15?v-67x zg2O+!u?5+Og<&sDbI`5JA9E>P}k84n{r5@@grWRZsQMi$tsDebD{gI21&X}(n{CK z5IWVRd{7((ze&l!iH~NkNl6ra^OD3+@z&3gw*Vre@#`#35MQR)#&TojWku1qjp+I> zh!gBY4<4HSk14TxIcfF^cH6pk@SboloSk*7y2mnQ%O*+42-;BAkWASU(yGb^7%?I5 zWJa}ThaQt_Q#LDxiZ3jSc39h77Zn~;F|lmWX=Lx-zmV@!eGL4t{z>27(tUfad*4Ei z6?)7ZsmwQ#GZaF3O5||=s&dtIWT`WWNcxa3O&=pm-KN=M_jGo;sMVhIm^HDrM7fPc zqA7{*<6k2cA=7a}gu`CiLS!okQQXuDjM!!X0UXjQ+DXn|1g+aWCdQGVb$>Y#w7s~& zuy^spv&L5OixFn*aNgJO3==ojf;`Gkj1{uikPIb8VCqUI6qh6fdB+sR3nAsD=0kHu00QvBf!-n zpL}&q#zRY_c6O=Qy!^4*1x1BM+>&>Nb?nM|=CeU|CG$3ERVaTO#;K$c!yJ>Bx`|va zGWkzBFjTVJwIg%~Hc*4Y5+}Lsvo@`QA!xp@+q}Bb$DXB{XV=ejLG)EZ}-a! z`ksxv$7<(w2#~x%xNswWJWT}b*?H{>+a9Gl@OGf`V9>Yqp4IB|NP(`@^D-|M8zXk8 z%!vJ5me8(ao3O%(qKzaGshmI}Qtk$<*)8W`5veX<`^Y9XN(l^?(|RfQO3!1B2yN;41|+Vtf6#3(e$VwA$JeTo74=MJ<%@i3yJE$0u3l>!Btvs6bz zqg>M%d*JY3{@c_4N%zqPfkzd8FmfUTVt=AJgQf1&oUPOPpH`#>n238AHGUAkC)G42 zHhV-7u@RmJVP9g0M+mtx8rP80y)(TR+t-XJhdHWzb@~MX-ZLh&BIO3Xl1+In8WQ#VGwef@bC7xrlmA19WIPvAQmDsz=yEz$dWCyj^qN#WR> zRVW2+X$rqAbu;?mVwfkYTwN>vO)^Q`rzQK>ZZMgjdYPAFbLm}ne!@Q*YY!Y{=D#-m zBMmpJAiQc~PPtr7Oqlri2R+kYgbP@E_I-4hZkoO-!vAs7>OSO<04C)n4FDrd%wc^M(~ zzE)%YJ|5_|8FM@w{Od60{Zqck;FwBt?#QcyfiXtBjh7f?I9w~C5E$0yHpjqYE&UAK zVCO7%eme%NCs%Z{=$z6(ueY8NI&bXCWW-e`LZQ^d{Had5t0Q-V>`UFRDmzqe%)6VX z*hqBYQ`DgeHoMPs0F@ ziV;|oa}%58QyGIW))&!4_gk5R6C@d2d_MIbkjfM zT>&cJqA%@;Jy6s;f(!n2!20XqYMhW5{KO$0X61UAH{89q89!NH<2e|4)+|&tUQzY5 z;%;IGi)S30K3P*vJLm26qn;K9LO?6>NFerEzvi$QC9*1yDz?arS*VoY>)$x(pE!SHTVjCz&Ele7BG-9P>ktlGxP z`T_pfCzGc5`y7mv#AbO4!xwbf_d;l>=4}Tef)X@7jb*-{5gSiWQtNriP0Lwtf4QeS zn7=FiarXu4ls_h3jypzDA%xGg+_6$6>XKOYWfYhw|0Z4(t+?tPe2{O(e0d*CtnjMl ziNw7!+%RBh<&43-EB3KS<;Z$~EYz`-~Pcjq5$5a55R^1L5bL!%K8;AN+ z7LRP%CW>LKo0N1$J*K}!rnBRAWVOeUx*(o~oaN)c$*AfHum-8XQ7Iz_SqW(%vf}`} zZwLb*+J;{eJFrWzR;T=IUYVOwe!x$xmsVAap`>%d4!1YotF1+7!l{qYA5cJ^LXTr8uRyFu13doC0VLqzn$=RyKU_Lz$Y zc_qa3`hOK3W+3n3p(8GHaJ5yS0StJ%)X!%D1?KcVDh_VNyU>r{=4oJcqsH97NrBih zu~v!UP1J#U$1Q79uasn@K~3pQW6MO{g&?}@U-G+2sZKducFP@8&bjl3X)~D4s@>A~ zxZdWfbEZwd`=)bd+=8R}rg7X&o>;T%!%XJ3lB+XipD{x*mBjyINjWmJ`FF;)B zvr(QnWF&vNFjiUx>9qZhl~-@TvPGhzx8q*EcS7BTS*U}YLEZ|xfG!*J1C9FS8syF} znS}D|Zu4BNz-^EuJ$@qCD#M+WEHQ6yZ^(ZCd_4NFHB6!WixS3zeI?@z#J(%Vx5@IiF;8E-V=dibu1jX{)mhZnlXb-zvI%7v*Q}=}l7d;31aL}K51$nd~kojBW zUD%$kB@dUHx9^p4Knh?{&Z8_$r}TlYsHL)1H|R}`G;J3r#b)N~(EbO!u3~X`{RFRp z89H{>A9)l;V!ZCyG%r(kJ+YTx8OJQ<`>){)`Y!2QA5^=JSgyA5Ms=6t>lex?89_MP zFkTK1WL^;Cscs~m?B4J8;hp`ypQ@S9A<_vw^-m4&gM#-_Gj`fI9H9UP1x2PktVHst z<4^eSn|A*WG1=X|X*kLZaTcd0I{?}&yGgQbG8ot-=c_ZClLY(;4N7kl7s_Nnw#NR+1cVe#r0RlCC^VW`4>JgunaUbin_Vq(i>PO56BKWGqlYAd|c#F~|taZBgIyw}yP%B5!ai%81Q5kI%Pn z98RE z_)jB`rtY9S0Ut7O^;tY5hL)OhH_2KvXR_PW`ZHO3AB8`Qh&dp!NJbq>ER@w(pM!FK zW&7So-GrQNaTCHSTd(YWG-R~}<~9p}MK+~&8B9Q8g{+7@uE>mi9SlCsBjnl?RAeR+ zH4M%ohOE1o2Itu8ddab_MmaPor-BM4Bn60bI@1lCZeRUXi1U*%-4N$HB;`n(>V@q2 z64PEISoyYmW@;l}ZRH`ADa#)VTCrCMg;8?Z4@8(wOmUIgSwADI(8DZNlZakmwZG&2 z)&Qp$c_%fQ0!*6VOfz<4yTF4qgiAq%{8$%vm=-~Dh=vurkFHz)7V1_lEC5da^h)vj z%Ik|oKeitKwj{yqqO;5L`XhQ0`}tXv5k%E!3mSDPcOjKS>BTH0O(_uaePJ}-t9Dd; zxZrSwrPru#C*me=jFLQ~B-iW`k9G(FNGw!8i5E)2g@{lQ;rCM4h z3wNn?$4~^Dy5t0_c4+&h*6g7j5EH3OjFPId3SC)+stnCU(a^nPjR%86(N&aA9O~uo zHAAb^L8K+ZVX%K1+*$0x{n^8Lssj*01vCE!#BQwV0EOGqSsVbdwmQK~^)B>GS#@dqjVx5|-zb)6PrMi|? zIyFsyYt^Z!PVLaCg*xT9<#eh;rCO{aF~)HI!PbgEvbI&^BGPI>fTmg-cwPAS&DBwpbTly9H}MW5J2 z6)qlvi$h<#LKuJKd-#b=**O=ANc{)i0PBHGl)9Jy4%G=2^r}7kc zflpFwc9m!+Vv6;wOXBZTA4+WAlFY+(ya^jIQ z%|!9>C-B8`y&skc1xdrn_CGifykB%RiWUi+F`Fj3xOBk0 zMV31^;>yzt_pkpj&WklFOK2EgrtChFDUad~l!GB?U#b^LjUVxZ^x!HZp1lRabh!+Q zoDSkN$OE2D<4Srh7&l_d=5fQ7FOkegrmPNx@m+=3#fQj<`Ni6Fq{VNPKqxL;|+>I;C6^eGh3N z=s@X<>B8IcuSWusDKvF>1=uzj5`eQr>NnXwwG^r>l$R1X z5&`rwD`=fh#wrR2<9QCpqGw&lBFt!W2=xJpR=XQ#Bjs9jB57$~PB3uWiP1Rx8{%fK zoQK@1-5h4+4r~)iWB%=QNq4A@4LxB>iE7NoT@+{Lu@uE5laQptwY+ zBjO`}do75c0C~jKt6T_Zfh=Y}W;iO|P~8_)9ryaT3+ja4Ex>axGBCRg33j@u?0q?j>znQ-ShzAB_MB(9qMA7+TZ)WYzqU?$KJxA=Vgp^CeRk<#Z?b^|QE)7rdZ>~KbM}M5H&sQ4W#C7Ph z)lzn?;{|9+d(k4`ExuveXYM~+#$V9JmoMX~kxPeA7WP8s z$Zp`+avtVd!8MB9mMCQq3!bEJ)F$F2sWzSRK#550BJ~Mo@Kv?Ov7EiB zT$ALzR8dY{6snM)O3(?cnR?W&Z~uQ{Mwt7!a3filB~h)&9F)da30zm`87Yk~*C{ny zrSZig$tbh70y_5m0w7sj_Y@0Vs#)k##X=jU%aX#rmOkF5epc*KKWp0gsimDfGywc2 zO7!m{ul`+9rGJ;z=-sV1Eg zHiJ}BXIsi+n|>rjMtqmfBUFl1yG{ujC6%Y=ph=f6apy;;ygD^ar>b(o-65}A-$o~%>TbV|UC_M)UvB`o9z_0=ij(FY_=$S;#bMHwM0{34XytPd$cwRRXCw&jixhu|tM+D7;68%o( zf}3(z>L-xWmQJxA`$AT%Coqi?>$55#-)j*LFBRV-{m}ZXVC6eO`?Qn9Y-^W&O@8E> z&NlIAzC^sJAmEww8RC1>CS;1cOB168VEYX;?<$_)yQauv8siU`mF*^WBk`Xic5DYW z)8c@9ixl6M-;nNQ#OyX;eykkiDJ%a)xuNmT*(JM6a%po(6L2maV(C&)7o!ZGv|2aQ>K8AGS z<=Vr(EyiI9Mg1Ds%e?hP@zgX6`Q3~}sA+d~ z8?d(O$OC5xP#idghwxZQC}BNljWDgNv9A|zkpkRp$>a0-5z*j2Z_v7}B52)M6||-g zCtX9D-I-i4rXK!U(HQt^%~3jM6cfAZY0-*v$54QdbBY8Y0XWWe>|6 zdxc;KG<8dPT&x~lUD}GJ>ie4I>gAdm)$E!kosyjdOOe#6CY=&|0?R3T)l57vnMc`T zW@4?J6eT5F3|*t_CQ)Unmn$a!f9$<~eALCY|DPCw0l{}rS5dDTD_GE4p-KgjLL|{$ z+$d^M)M~l4P^4;6vO=rqLK5Zex|M59OTER?A68mx8-IWS3nYLfSgY|z6@OHMwz%us z8nuOB)%`wSXWqNn5bVA8`?#OaUmqTteb28mGiT16IdkUB8A6a9CWg(iTX4{%4izD! zVWL=3GhlPwp8c@aDr=1$W}4e|uJ^0vQYssIY!q_ves=I+1ZKNY1CI*YD&uHBQN03T zODu=UIZfv%{_Ck#FKPGo1RJ>Y>_a87r7z?95$0%dpH0!srK&wLU~^cvW?OeugiDb7 z6HaO$XGW;t+PGN#gCY8cxRSuIC@@KBz->q4mc%)qBO>kwrlz@JE0Jv+=%P$n>NOm1 z#q5Ns4l%6$P{Pp!#!3k@Y>kfvsN+KQr!arQbz^b25?@euf!8pWmSRB1h4I;CUfrMY z{>E$Zk#GKyv(c&{0EiALPj4mm_QBgZoP#vC@iY3lC7Ay28OXVAN22slLxY`YRVAl0 zl1FVOkM0AhM51(yen1*451}R(nnWm3`Vs+TSC{e|monE<)+mq|e3!)~mnw&EB1yOy zmtu`GT#-6gWQ7YYbfLHlz2!npF7#{=LK2`6uewmXZHY^ta3KjUq&?$89WKqwSRu`J&(*DzhQZB8*g~BfFw=UG>(thYdQ(fB6T&UZn zC0%H`OFP+xR=Tv2F4W{g^IWLeg|2a-7DAX|#o?WzHg0=}tPyX-A|$41@*<{bs(RQw zQ;pd?^NYANgP%1rS!Df@ND9l*^!?!HTxB1K{VdF;Zk=XQkyrl%0&K5T1m-eZKfJur z`gTRtv9E;dp2Stv>lnvW9lMR?;0e(*uWUv}VjOV=1+f$=^A>-ZuWH_xnYcfOrqPN0 z`2O<5{*|q7lvfXUvNCbT#7OHKSOL6M79H?X)cbWCI*Dg$kK$p5N_pFrk?KJ};K71w zZl*M*o)%)H?dr13xtrgE=@#;0aAr_KI8e#S;mIhr+CEGsU=+mp) zNC>y)-fxpD)S=cL0BaPnhDSc>E&e&F=mJH1k&#b%i|;mQtCSVLzFyr9tQGCp=eGk? zjk~~?JfkdJVmJ3t@XJW`)zKW7uMkE8^RU1wG%yxzGp1q5w)=Bm;!*CaDgV`x|C*Zr zT9N-+n*S2RRM~KH%r`iDW6j0}WdjkBx{vr;#TS_W-Kb@JoRt`K+gXW27FF|3MDnCj zli$mpcjZm%ifW4At<1hv#d%Ma-=3MqM^hC>JDGE;n5KZQ@{_7BGoG-TKv-?coJd&Q zoy?m3NAyE3^_PNQxHMz5rfeI3Fz z4L4Kc4zNVCoubcepFg@?P>4T_xEZ z^@mR<#jDTY_>F9n39vfqvU7zlJ6GV(c)8QSY)>8itaZhLcF<2N;@G6da3HkGHpd+3 z48lai4s*I?62dA+FL@`j%#?>-{X3}S(tqdA=vSrVNH(lh)zg9w&Oi|OHwIp1XyrQ4hvv7(ZxDqpFNN!^@3FGAbm?s zIq;Iyy$+J*cdj)~hvgtCz6Vl;7;A2)Gv=S1Y0{}v1nJOAQeSqET2z}|rDWhO;8igP z?9)MFfpNO!}3(J3ZISc zw!2rg3z1jlMUEW1k*It5B6|D`RYVgPaj>wy)28dKDSpC<)kRu~8g|wAuh$M_X7u;I z`+E})mrn&w6x}YHBzzmK;4`dGNZNiHr`yk}8T`N^XY&ISFkVicxk^N!<#U03CRZ4^ zWZWe*k+4Lc{;H+?0ALwE0x-knTjBC8CErT>w1W*oO)eyYBh>6dA_qb(LCB@G6M}hl zxJVHIS+*(U-`D9PHI784Eb_rF`&rk`4>Px@i=Tws0{Ka4kl0p09u#Ph4hS-+u%AY$ zfaAJws0@k&bKfGUNWF&E?fCV`oF5v+h zc0Z~!ku0+xZ0=jj*;JUx0V5+E(x6HD;l8J}a@ANh∼uKa-gb6^)XXF7%-?%W&Y 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

o!L0 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¥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 a{NH&ocKsK>XRd$wZ~vP6ss7!){{H~_eVK^> literal 0 HcmV?d00001 diff --git a/proxy/src/insecure.rs b/proxy/src/insecure.rs index 4a32adf..1451a64 100644 --- a/proxy/src/insecure.rs +++ b/proxy/src/insecure.rs @@ -1,5 +1,3 @@ -use std::process::abort; - use proxy::edge_node_dc_callback; use proxy_common::{ProxyStartupParam, setup_edge_node_connection}; use rnex_core::common::setup; diff --git a/prudpv0/src/crypto/friends_insecure.rs b/prudpv0/src/crypto/friends_insecure.rs index 9fbfe95..1f05681 100644 --- a/prudpv0/src/crypto/friends_insecure.rs +++ b/prudpv0/src/crypto/friends_insecure.rs @@ -65,11 +65,14 @@ impl Crypto for Insecure { packet_data: &[u8], self_signat: [u8; 4], remote_signat: [u8; 4], - ) -> Self::Instance { - InsecureInstance { - pair: EncryptionPair::init_both(|| Rc4::new(&DEFAULT_KEY)), - self_signat, - remote_signat, - } + ) -> Option<(Self::Instance, Vec)> { + Some(( + InsecureInstance { + pair: EncryptionPair::init_both(|| Rc4::new(&DEFAULT_KEY)), + self_signat, + remote_signat, + }, + vec![], + )) } } diff --git a/prudpv0/src/crypto/friends_secure.rs b/prudpv0/src/crypto/friends_secure.rs index 206efec..acfa3bc 100644 --- a/prudpv0/src/crypto/friends_secure.rs +++ b/prudpv0/src/crypto/friends_secure.rs @@ -1,10 +1,18 @@ use hmac::Mac; -use rc4::{Rc4, StreamCipher}; -use rnex_core::prudp::{ - encryption::EncryptionPair, - types_flags::{TypesFlags, types::DATA}, +use md5::{Digest, Md5}; +use rc4::{KeyInit, Rc4, StreamCipher}; +use rnex_core::{ + executables::common::SECURE_SERVER_ACCOUNT, + nex::account::Account, + prudp::{ + encryption::EncryptionPair, + ticket::read_secure_connection_data, + types_flags::{TypesFlags, types::DATA}, + }, + rmc::structures::RmcSerialize, }; -use typenum::U32; +use std::io::Write; +use typenum::U16; use crate::crypto::{ Crypto, CryptoInstance, @@ -13,7 +21,7 @@ use crate::crypto::{ }; pub struct SecureInstance { - pair: EncryptionPair>, + pair: EncryptionPair>, uid: u32, self_signat: [u8; 4], remote_signat: [u8; 4], @@ -34,7 +42,9 @@ impl CryptoInstance for SecureInstance { if data.len() == 0 { [0x78, 0x56, 0x34, 0x12] } else { - let mut hmac = ::new_from_slice(ACCESS_KEY.as_bytes()) + let mut hash = Md5::new(); + hash.write(ACCESS_KEY.as_bytes()).unwrap(); + let mut hmac = ::new_from_slice(&hash.finalize().as_slice()) .expect("unable to create hmac md5"); hmac.update(data); hmac.finalize().into_bytes()[0..4].try_into().unwrap() @@ -45,12 +55,12 @@ impl CryptoInstance for SecureInstance { } } -pub struct Secure(); +pub struct Secure(&'static Account); impl Crypto for Secure { type Instance = SecureInstance; fn new() -> Self { - Self() + Self(&SECURE_SERVER_ACCOUNT) } fn calculate_checksum(&self, data: &[u8]) -> u8 { common_checksum(ACCESS_KEY, data) @@ -60,7 +70,27 @@ impl Crypto for Secure { data: &[u8], self_signat: [u8; 4], remote_signat: [u8; 4], - ) -> Self::Instance { - todo!() + ) -> Option<(Self::Instance, Vec)> { + let (session_key, pid, check_value) = read_secure_connection_data(data, &self.0)?; + + let check_value_response = check_value + 1; + + let data = bytemuck::bytes_of(&check_value_response); + + let mut response = Vec::new(); + + data.serialize(&mut response).ok()?; + + Some(( + SecureInstance { + pair: EncryptionPair::init_both(|| { + Rc4::new_from_slice(&session_key).expect("unable to initialize rc4 stream") + }), + self_signat, + remote_signat, + uid: pid, + }, + response, + )) } } diff --git a/prudpv0/src/crypto/mod.rs b/prudpv0/src/crypto/mod.rs index 5fd0d3f..f4806f6 100644 --- a/prudpv0/src/crypto/mod.rs +++ b/prudpv0/src/crypto/mod.rs @@ -19,7 +19,7 @@ pub trait Crypto: Send + Sync + 'static { data: &[u8], self_signat: [u8; 4], remote_signat: [u8; 4], - ) -> Self::Instance; + ) -> Option<(Self::Instance, Vec)>; } cfg_if! { diff --git a/prudpv0/src/packet.rs b/prudpv0/src/packet.rs index aa68194..e94ab46 100644 --- a/prudpv0/src/packet.rs +++ b/prudpv0/src/packet.rs @@ -1,7 +1,7 @@ use std::mem::transmute; use bytemuck::{Pod, Zeroable, try_from_bytes, try_from_bytes_mut}; -use log::{error, info}; +use log::{error, info, warn}; use rnex_core::prudp::{ types_flags::{ self, TypesFlags, @@ -146,6 +146,15 @@ impl> PRUDPV0Packet { let Some(checksum) = self.checksum() else { return false; }; + + if checksum != crypto.calculate_checksum(data) { + warn!( + "checksum doesnt match expected checksum: {} != {}", + checksum, + crypto.calculate_checksum(data) + ) + } + checksum == crypto.calculate_checksum(data) } @@ -230,7 +239,7 @@ pub fn new_connect_packet( ) -> Vec { let type_flags = TypesFlags::default().types(CONNECT).flags(flags); - let vec = vec![0; precalc_size(type_flags, 0)]; + let vec = vec![0; precalc_size(type_flags, data.len())]; let mut packet = PRUDPV0Packet::new(vec); let header = packet.header_mut().expect("packet malformed in creation"); @@ -245,6 +254,12 @@ pub fn new_connect_packet( *packet .connection_signature_mut() .expect("packet malformed in creation") = remote_signat; + + packet + .payload_mut() + .expect("packet malformed in creation") + .copy_from_slice(data); + if let Some(size) = packet.size_mut() { size.copy_from_slice(&(data.len() as u16).to_le_bytes()); } @@ -281,6 +296,8 @@ pub fn new_data_packet( .expect("packet malformed in creation") .copy_from_slice(data); + crypto_instance.encrypt_outgoing(packet.payload_mut().expect("packet malformed in creation")); + if let Some(size) = packet.size_mut() { size.copy_from_slice(&(data.len() as u16).to_le_bytes()); } diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 55b508e..aa603f7 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -3,7 +3,7 @@ use std::{ hash::Hash, net::{Ipv4Addr, SocketAddr, SocketAddrV4}, sync::{ - Arc, LazyLock, + Arc, LazyLock, Weak, atomic::{AtomicBool, AtomicU32}, }, thread::sleep, @@ -123,13 +123,14 @@ impl Server { let packet = Arc::new(packet); let packet_ref = Arc::downgrade(&packet); - let conn = Arc::downgrade(&conn); - let this = Arc::downgrade(&self); inner.unacknowledged_packets.insert(seq, packet); drop(inner); + let conn = Arc::downgrade(&conn); + let this = Arc::downgrade(&self); + spawn(async move { for n in 0..5 { let Some(data) = packet_ref.upgrade() else { @@ -153,10 +154,11 @@ impl Server { } async fn connection_thread( self: Arc, - conn: Arc>, + conn: Weak>, mut recv: SplittableBufferConnection, ) { while let Some(data) = recv.recv().await { + let Some(conn) = conn.upgrade() else { break }; if &data[..] == &[0, 0, 0, 0, 0] { info!("got keepalive"); continue; @@ -168,8 +170,8 @@ impl Server { async fn timeout_thread(self: Arc, conn: Arc>) { loop { sleep(Duration::from_secs(3)); - info!("running another loop"); let mut inner = conn.inner.lock().await; + if (Instant::now() - inner.last_action).as_secs() > 5 { warn!("connection exceeded silence limit, sending ping"); let packet = new_ping_packet( @@ -187,11 +189,11 @@ impl Server { .await; } - if (Instant::now() - conn.inner.lock().await.last_action).as_secs() > 15 { + if (Instant::now() - inner.last_action).as_secs() > 15 { warn!("client timed out..."); let packet = new_disconnect_packet( - 0, + NEED_ACK, self.param.virtual_port, conn.addr.virtual_port, 0, @@ -209,9 +211,12 @@ impl Server { self.socket .send_to(&packet, conn.addr.regular_socket_addr) .await; + drop(inner); + let mut conns = self.connections.write().await; conns.remove(&conn.addr); drop(conns); + break; } drop(inner); @@ -247,7 +252,10 @@ impl Server { remote_signat[3], ]; - let ci = self.crypto.instantiate(data, self_signat, remote_signat); + let Some((ci, data)) = self.crypto.instantiate(&data, self_signat, remote_signat) else { + warn!("unable to instantiate crypto instance"); + return; + }; let pid = ci.get_user_id(); let buf_conn = new_backend_connection(&self.param, addr, pid).await; @@ -281,7 +289,7 @@ impl Server { spawn({ let this = self.clone(); - let conn = conn.clone(); + let conn = Arc::downgrade(&conn); this.connection_thread(conn, buf_conn) }); spawn({ @@ -297,7 +305,7 @@ impl Server { self_signat, remote_signat, packet.header().unwrap().session_id, - &[], + &data, &self.crypto, ); @@ -314,10 +322,7 @@ impl Server { return; }; - let rd = self.connections.read().await; - let res = rd.get(&addr).cloned(); - drop(rd); - let Some(res) = res else { + let Some(res) = self.get_connection(addr).await else { warn!("data packet on inactive connection from: {:?}", addr); return; }; @@ -335,7 +340,6 @@ impl Server { &self.crypto, ); self.socket.send_to(&ack, addr.regular_socket_addr).await; - conn.last_action = Instant::now(); conn.packet_queue.insert( packet.header().unwrap().sequence_id, (Instant::now(), packet), @@ -356,6 +360,7 @@ impl Server { res.target.send(payload.to_owned()).await; conn.client_packet_counter += 1; } + info!("finished handeling packets, dropping inner connection"); drop(conn); } @@ -378,7 +383,6 @@ impl Server { &self.crypto, ); drop(inner); - drop(conn); self.socket.send_to(&packet, addr.regular_socket_addr).await; } @@ -405,7 +409,6 @@ impl Server { &self.crypto, ); drop(inner); - drop(conn); self.socket.send_to(&packet, addr.regular_socket_addr).await; self.socket.send_to(&packet, addr.regular_socket_addr).await; @@ -429,17 +432,19 @@ impl Server { return; }; + info!("len: {}", packet.0.len()); + let addr = PRUDPSockAddr::new(addr, header.source); - if header.type_flags.get_flags() & ACK != 0 { - info!("got ack(acks are ignored for now)"); - return; - } if let Some(conn) = self.get_connection(addr).await { let mut inner = conn.inner.lock().await; inner.last_action = Instant::now(); drop(inner); }; + if header.type_flags.get_flags() & ACK != 0 { + info!("got ack(acks are ignored for now)"); + return; + } println!("{:?}", header); match header.type_flags.get_types() { SYN => { @@ -464,20 +469,18 @@ impl Server { } pub async fn run_task(self: Arc) { loop { - let mut vec: Vec = vec![]; - let addr = match self.socket.recv_buf_from(&mut vec).await { + let mut vec: Vec = vec![0u8; 65507]; + let (len, addr) = match self.socket.recv_from(&mut vec).await { Err(e) => { error!("unable to recv: {}", e); break; } - Ok(v) => { - assert_eq!(vec.len(), v.0); - v.1 - } + Ok(v) => v, }; let this = self.clone(); tokio::spawn(async move { let mut data = vec; + data.resize(len, 0); let packet = PRUDPV0Packet::new(data); let SocketAddr::V4(addr) = addr else { diff --git a/prudpv1/src/prudp/secure.rs b/prudpv1/src/prudp/secure.rs index 604ca58..9bd441b 100644 --- a/prudpv1/src/prudp/secure.rs +++ b/prudpv1/src/prudp/secure.rs @@ -8,73 +8,12 @@ use rc4::{KeyInit, Rc4, Rc4Core, StreamCipher}; use rnex_core::kerberos::{TicketInternalData, derive_key}; use rnex_core::nex::account::Account; use rnex_core::prudp::encryption::EncryptionPair; +use rnex_core::prudp::ticket::read_secure_connection_data; use rnex_core::rmc::structures::RmcSerialize; use std::io::Cursor; use typenum::U5; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 32], u32, u32)> { - let mut cursor = Cursor::new(data); - - let mut ticket_data: Vec = Vec::deserialize(&mut cursor).ok()?; - let mut request_data: Vec = Vec::deserialize(&mut cursor).ok()?; - - let ticket_data_size = ticket_data.len(); - - let ticket_data = &mut ticket_data[0..ticket_data_size - 0x10]; - - let server_key = derive_key(act.pid, &act.kerbros_password[..]); - - let mut rc4: StreamCipherCoreWrapper> = - Rc4::new_from_slice(&server_key).expect("unable to init rc4 keystream"); - - rc4.apply_keystream(ticket_data); - - let ticket_data: &TicketInternalData = match bytemuck::try_from_bytes(ticket_data) { - Ok(v) => v, - Err(e) => { - error!("unable to read internal ticket data: {}", e); - return None; - } - }; - - // todo: add ticket expiration - - let TicketInternalData { - session_key, - pid: ticket_source_pid, - issued_time, - } = *ticket_data; - - // todo: add checking if tickets are signed with a valid md5-hmac - let request_data_length = request_data.len(); - let request_data = &mut request_data[0..request_data_length - 0x10]; - - let mut rc4: StreamCipherCoreWrapper> = - Rc4::new_from_slice(&session_key).expect("unable to init rc4 keystream"); - - rc4.apply_keystream(request_data); - - let mut reqest_data_cursor = Cursor::new(request_data); - - let pid: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?; - - if pid != ticket_source_pid { - let ticket_created_on = issued_time.to_regular_time(); - - error!( - "someone tried to spoof their pid, ticket was created on: {}", - ticket_created_on.to_rfc2822() - ); - return None; - } - - let _cid: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?; - let response_check: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?; - - Some((session_key, pid, response_check)) -} - type Rc4U32 = StreamCipherCoreWrapper>; pub fn generate_secure_encryption_pairs( diff --git a/rnex-core/src/executables/backend_server_insecure.rs b/rnex-core/src/executables/backend_server_insecure.rs index efb08db..b7ce979 100644 --- a/rnex-core/src/executables/backend_server_insecure.rs +++ b/rnex-core/src/executables/backend_server_insecure.rs @@ -1,8 +1,6 @@ -use cfg_if::cfg_if; use once_cell::sync::Lazy; use rnex_core::common::setup; use rnex_core::executables::common::{SECURE_SERVER_ACCOUNT, new_simple_backend}; -use rnex_core::executables::regular_backend; use rnex_core::nex::auth_handler::AuthHandler; use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister; use rnex_core::reggie::RemoteEdgeNodeHolder; @@ -25,11 +23,25 @@ pub static FORWARD_EDGE_NODE_HOLDER: Lazy = Lazy::new(|| { async fn main() { setup(); - cfg_if! { - if #[cfg(features = "friends")]{ + let conn = TcpStream::connect(&*FORWARD_EDGE_NODE_HOLDER) + .await + .unwrap(); - } else { - regular_backend::start_regular_backend().await - } - } + let conn: SplittableBufferConnection = conn.into(); + + conn.send(DontRegister.to_data().unwrap()).await; + + let conn = new_rmc_gateway_connection(conn, |r| { + Arc::new(OnlyRemote::::new(r)) + }); + + new_simple_backend(move |_, _| { + let controller = conn.clone(); + Arc::new(AuthHandler { + destination_server_acct: &SECURE_SERVER_ACCOUNT, + build_name: env!("AUTH_REPORT_VERSION"), + control_server: controller, + }) + }) + .await; } From dad8ac498cecbc319c67ec87e95c0f9c75ebff0e Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 1 Feb 2026 21:31:32 +0100 Subject: [PATCH 057/203] fix having fixed size key --- rnex-core/src/kerberos/mod.rs | 4 ++-- rnex-core/src/nex/account.rs | 14 ++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index 88700a6..4b56f56 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -26,7 +26,7 @@ pub const SESSION_KEY_LENGTH: usize = SESSION_KEY_LENGTH_TY::USIZE; type Md5Hmac = Hmac; pub fn derive_key(pid: u32, password: &[u8]) -> [u8; 16] { - let iteration_count = 65000 + pid % 1024 - 1; + let iteration_count = 65000 + pid % 1024; // we do one iteration out here to ensure the key is always 16 bytes let mut key: [u8; 16] = { @@ -35,7 +35,7 @@ pub fn derive_key(pid: u32, password: &[u8]) -> [u8; 16] { md5.finalize().try_into().unwrap() }; - for _ in 0..iteration_count { + for _ in 1..iteration_count { let mut md5 = Md5::new(); md5.update(key); key = md5.finalize().try_into().unwrap(); diff --git a/rnex-core/src/nex/account.rs b/rnex-core/src/nex/account.rs index 0c7a6f0..b3a5bb6 100644 --- a/rnex-core/src/nex/account.rs +++ b/rnex-core/src/nex/account.rs @@ -4,29 +4,23 @@ use macros::RmcSerialize; pub struct Account { pub pid: u32, pub username: String, - pub kerbros_password: [u8; 16], + pub kerbros_password: Box<[u8]>, } impl Account { pub fn new(pid: u32, username: &str, passwd: &str) -> Self { let passwd_data = passwd.as_bytes(); - let mut passwd = [0u8; 16]; - - for (idx, byte) in passwd_data.iter().enumerate() { - passwd[idx] = *byte; - } - Self { - kerbros_password: passwd, + kerbros_password: passwd.as_bytes().into(), username: username.into(), pid, } } - pub fn new_raw_password(pid: u32, username: &str, passwd: [u8; 16]) -> Self { + pub fn new_raw_password(pid: u32, username: &str, passwd: &[u8]) -> Self { Self { - kerbros_password: passwd, + kerbros_password: passwd.into(), username: username.into(), pid, } From 785341e883d84470da04b7e55cf94d5cb09d15b9 Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 24 Mar 2026 15:48:56 +0100 Subject: [PATCH 058/203] fix port binding --- Cargo.lock | 293 ++++++++++++++++- Cargo.toml | 2 +- editions.yaml | 12 +- macros/Cargo.toml | 3 +- macros/src/lib.rs | 15 +- macros/src/protos.rs | 54 ++- proxy-common/src/lib.rs | 5 +- proxy/Cargo.toml | 2 + proxy/src/lib.rs | 2 + prudplite/Cargo.toml | 18 + prudplite/src/crypto/insecure.rs | 14 + prudplite/src/crypto/mod.rs | 9 + prudplite/src/crypto/secure.rs | 27 ++ prudplite/src/lib.rs | 309 ++++++++++++++++++ prudplite/src/main.rs | 45 +++ prudplite/src/packet.rs | 223 +++++++++++++ prudpv0/src/server.rs | 4 +- rnex-core/Cargo.toml | 5 + .../src/executables/backend_server_secure.rs | 1 + rnex-core/src/executables/friends_backend.rs | 65 +++- rnex-core/src/grpc/account.rs | 65 ++-- rnex-core/src/kerberos/mod.rs | 13 +- rnex-core/src/lib.rs | 15 +- rnex-core/src/nex/account.rs | 12 +- rnex-core/src/nex/auth_handler.rs | 245 +++++++++----- rnex-core/src/nex/common.rs | 6 +- rnex-core/src/nex/friends_handler.rs | 56 +++- rnex-core/src/nex/matchmake.rs | 19 +- rnex-core/src/nex/user.rs | 20 +- rnex-core/src/prudp/socket_addr.rs | 13 +- rnex-core/src/prudp/station_url.rs | 140 +++----- rnex-core/src/prudp/ticket.rs | 12 +- .../src/rmc/protocols/account_management.rs | 4 + rnex-core/src/rmc/protocols/auth.rs | 33 +- rnex-core/src/rmc/protocols/matchmake.rs | 13 +- rnex-core/src/rmc/protocols/mod.rs | 1 + rnex-core/src/rmc/protocols/notifications.rs | 17 +- rnex-core/src/rmc/protocols/secure.rs | 1 + rnex-core/src/rmc/structures/matchmake.rs | 14 +- rnex-core/src/rmc/structures/networking.rs | 66 +++- rnex-core/src/rmc/structures/primitives.rs | 19 +- rnex-core/src/rmc/structures/ranking.rs | 52 --- rnex-core/src/rnex_proxy_common.rs | 8 +- 43 files changed, 1532 insertions(+), 420 deletions(-) create mode 100644 prudplite/Cargo.toml create mode 100644 prudplite/src/crypto/insecure.rs create mode 100644 prudplite/src/crypto/mod.rs create mode 100644 prudplite/src/crypto/secure.rs create mode 100644 prudplite/src/lib.rs create mode 100644 prudplite/src/main.rs create mode 100644 prudplite/src/packet.rs create mode 100644 rnex-core/src/rmc/protocols/account_management.rs diff --git a/Cargo.lock b/Cargo.lock index b7ebf9f..b010331 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -149,7 +149,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -162,12 +162,31 @@ dependencies = [ "inout", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -187,6 +206,12 @@ dependencies = [ "typenum", ] +[[package]] +name = "data-encoding" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" + [[package]] name = "deranged" version = "0.4.0" @@ -229,6 +254,50 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -250,6 +319,18 @@ dependencies = [ "wasi", ] +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + [[package]] name = "gimli" version = "0.31.1" @@ -471,6 +552,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "openssl-probe" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" + [[package]] name = "parking_lot" version = "0.12.4" @@ -512,6 +599,12 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "powerfmt" version = "0.2.0" @@ -543,6 +636,7 @@ dependencies = [ "cfg-if", "log", "proxy-common", + "prudplite", "prudpv0", "prudpv1", "rnex-core", @@ -559,6 +653,20 @@ dependencies = [ "tokio", ] +[[package]] +name = "prudplite" +version = "0.1.0" +dependencies = [ + "bytemuck", + "futures-util", + "log", + "proxy-common", + "rnex-core", + "tokio", + "tokio-tungstenite", + "v-byte-helpers", +] + [[package]] name = "prudpv0" version = "0.1.0" @@ -604,6 +712,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rand" version = "0.8.5" @@ -611,8 +725,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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", ] [[package]] @@ -622,7 +746,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.5", ] [[package]] @@ -631,7 +765,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", ] [[package]] @@ -660,7 +803,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -683,7 +826,7 @@ dependencies = [ "md-5", "once_cell", "paste", - "rand", + "rand 0.8.5", "rc4", "simplelog", "thiserror", @@ -714,6 +857,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pki-types" version = "1.12.0" @@ -740,12 +895,44 @@ version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.219" @@ -766,6 +953,17 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" @@ -941,6 +1139,51 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" +dependencies = [ + "futures-util", + "log", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tungstenite", +] + +[[package]] +name = "tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.9.2", + "rustls", + "rustls-pki-types", + "sha1", + "thiserror", + "utf-8", +] + [[package]] name = "typenum" version = "1.18.0" @@ -1015,6 +1258,15 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -1099,7 +1351,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", - "windows-link", + "windows-link 0.1.3", "windows-result", "windows-strings", ] @@ -1132,13 +1384,19 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-result" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -1147,7 +1405,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -1168,6 +1426,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -1232,6 +1499,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" + [[package]] name = "zerocopy" version = "0.8.26" diff --git a/Cargo.toml b/Cargo.toml index 9d6ea8a..046a20f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,4 @@ members = [ "rnex-core", "prudpv1", "prudpv0" -, "proxy", "proxy-common"] +, "proxy", "proxy-common", "prudplite"] diff --git a/editions.yaml b/editions.yaml index 1c025b0..5458ec6 100644 --- a/editions.yaml +++ b/editions.yaml @@ -1,7 +1,17 @@ splatoon: features: - - rmc_struct_header - prudpv1 + - v3-8-15 + settings: + AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" + RNEX_VIRTUAL_PORT_INSECURE: "1:10" + RNEX_VIRTUAL_PORT_SECURE: "1:10" + RNEX_DEFAULT_PORT: 6000 +splatoon2: + features: + - v4-3-11 + - prudplite + - nx settings: AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" RNEX_VIRTUAL_PORT_INSECURE: "1:10" diff --git a/macros/Cargo.toml b/macros/Cargo.toml index dca135c..f748300 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "macros" version = "0.0.0" -authors = ["DJMrTV "] +authors = ["RusticMaple "] description = "A `cargo generate` template for quick-starting a procedural macro crate" keywords = ["template", "proc_macro", "procmacro"] edition = "2018" @@ -14,4 +14,3 @@ doctest = false quote = "1.0.38" proc-macro2 = "1.0.93" syn = { version = "2.0.98", features = ["full"] } - diff --git a/macros/src/lib.rs b/macros/src/lib.rs index d088561..d0fc909 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -48,7 +48,11 @@ impl Parse for ProtoInputParams { fn gen_serialize_data_struct( s: DataStruct, struct_attr: Option<&Attribute>, -) -> (proc_macro2::TokenStream, proc_macro2::TokenStream, proc_macro2::TokenStream) { +) -> ( + proc_macro2::TokenStream, + proc_macro2::TokenStream, + proc_macro2::TokenStream, +) { let serialize_base_content = { let mut serialize_content = quote! {}; @@ -123,8 +127,6 @@ fn gen_serialize_data_struct( let mut size_content = quote! { 0 }; for f in &s.fields { - - let ident = f.ident.as_ref().unwrap(); size_content.append_all(quote! { @@ -135,12 +137,11 @@ fn gen_serialize_data_struct( size_content }; let write_size = if let Some(_) = struct_attr { - quote!{ #write_size + if rnex_core::config::FEATURE_HAS_STRUCT_HEADER{ 5 } else { 0 } } + quote! { #write_size + if rnex_core::config::FEATURE_HAS_STRUCT_HEADER{ 5 } else { 0 } } } else { write_size }; - // generate base with extends stuff let serialize_base_content = if let Some(attr) = struct_attr { @@ -215,7 +216,7 @@ fn gen_serialize_data_struct( deserialize_base_content }; - let write_size = quote!{ + let write_size = quote! { fn serialize_write_size(&self) -> rnex_core::rmc::structures::Result{ Ok(#write_size) } @@ -390,7 +391,7 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { Ok(val) }; - (serialize_base_content, deserialize_base_content, quote!{}) + (serialize_base_content, deserialize_base_content, quote! {}) } Data::Union(_) => { unimplemented!() diff --git a/macros/src/protos.rs b/macros/src/protos.rs index 7dd7bf1..2e95e71 100644 --- a/macros/src/protos.rs +++ b/macros/src/protos.rs @@ -1,47 +1,46 @@ use proc_macro2::{Ident, Span, TokenStream}; use quote::{quote, ToTokens}; -use syn::{LitInt, LitStr, ReturnType, Type}; use syn::token::{Brace, Paren, Semi}; +use syn::{Attribute, LitInt, LitStr, ReturnType, Type}; -pub struct ProtoMethodData{ +pub struct ProtoMethodData { pub id: LitInt, pub name: Ident, pub parameters: Vec<(Ident, Type)>, pub ret_val: ReturnType, } - /// This is a representation of the code generated by `rmc_proto` it serves to split the logic of /// acquiring data from the actual generation to tidy up the process into first getting then /// generating. /// /// Use the [`ToTokens`] trait to generate the actual code. -pub struct RmcProtocolData{ +pub struct RmcProtocolData { pub has_returns: bool, pub id: LitInt, pub name: Ident, - pub methods: Vec + pub methods: Vec, } -impl RmcProtocolData{ - fn generate_raw_trait(&self, tokens: &mut TokenStream){ - let Self{ +impl RmcProtocolData { + fn generate_raw_trait(&self, tokens: &mut TokenStream) { + let Self { has_returns, name, id, - methods + methods, } = self; // this gives us the name which the identifier of the corresponding Raw trait let raw_name = Ident::new(&format!("Raw{}", name), name.span()); - // boilerplate tokens which all raw traits need - quote!{ + quote! { #[doc(hidden)] #[allow(unused_must_use)] pub trait #raw_name: #name - }.to_tokens(tokens); + } + .to_tokens(tokens); // generate the body of the raw protocol trait Brace::default().surround(tokens, |tokens|{ @@ -191,9 +190,10 @@ impl RmcProtocolData{ }); }); - quote!{ + quote! { impl #raw_name for T{} - }.to_tokens(tokens); + } + .to_tokens(tokens); } fn generate_raw_remote_trait(&self, tokens: &mut TokenStream) { @@ -208,13 +208,13 @@ impl RmcProtocolData{ // this gives us the name which the identifier of the corresponding Raw trait let remote_name = Ident::new(&format!("Remote{}", name), name.span()); - // boilerplate tokens which all raw traits need - quote!{ + quote! { #[doc(hidden)] #[allow(unused_must_use)] pub trait #remote_name: rnex_core::rmc::protocols::HasRmcConnection - }.to_tokens(tokens); + } + .to_tokens(tokens); // generate the body of the raw protocol trait Brace::default().surround(tokens, |tokens|{ @@ -299,35 +299,29 @@ impl RmcProtocolData{ }) } }); - - } - fn generate_raw_info(&self, tokens: &mut TokenStream){ - let Self{ - name, - id, - .. - } = self; + fn generate_raw_info(&self, tokens: &mut TokenStream) { + let Self { name, id, .. } = self; let raw_info_name = Ident::new(&format!("Raw{}Info", name), Span::call_site()); - - quote!{ + quote! { #[doc(hidden)] pub struct #raw_info_name; impl #raw_info_name { pub const PROTOCOL_ID: u16 = #id; } - }.to_tokens(tokens); + } + .to_tokens(tokens); } } -impl ToTokens for RmcProtocolData{ +impl ToTokens for RmcProtocolData { fn to_tokens(&self, tokens: &mut TokenStream) { self.generate_raw_trait(tokens); self.generate_raw_info(tokens); self.generate_raw_remote_trait(tokens); } -} \ No newline at end of file +} diff --git a/proxy-common/src/lib.rs b/proxy-common/src/lib.rs index 93c16c8..3bd902d 100644 --- a/proxy-common/src/lib.rs +++ b/proxy-common/src/lib.rs @@ -1,5 +1,6 @@ use log::{error, info}; use rnex_core::{ + PID, executables::common::{OWN_IP_PUBLIC, try_get_ip}, prudp::{socket_addr::PRUDPSockAddr, virtual_port::VirtualPort}, reggie::{RemoteEdgeNodeHolder, UnitPacketWrite}, @@ -83,7 +84,7 @@ impl ProxyStartupParam { let self_public: SocketAddrV4 = match try_get_env("SERVER_IP_PUBLIC") { Ok(v) => v, Err(e) => try_get_ip() - .map(|v| SocketAddrV4::new(v, RNEX_DEFAULT_PORT)) + .map(|v| SocketAddrV4::new(v, self_private.port())) .map_err(move |v| Error::PubAddrGetErr(Box::new(e), v))?, }; @@ -175,7 +176,7 @@ pub async fn setup_edge_node_connection( pub async fn new_backend_connection( param: &ProxyStartupParam, addr: PRUDPSockAddr, - pid: u32, + pid: PID, ) -> Option { info!("attempting to connect to: {}", param.forward_destination); let mut stream = match TcpStream::connect(param.forward_destination).await { diff --git a/proxy/Cargo.toml b/proxy/Cargo.toml index fa56ab2..98e8b2b 100644 --- a/proxy/Cargo.toml +++ b/proxy/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" tokio = { version = "1.47.0", features = ["full"] } prudpv0 = { path = "../prudpv0", optional = true } prudpv1 = { path = "../prudpv1", optional = true } +prudplite = { path = "../prudplite", optional = true } proxy-common = { path = "../proxy-common" } cfg-if = "1.0.4" rnex-core = { path = "../rnex-core", version = "0.1.1" } @@ -15,6 +16,7 @@ log = "0.4.25" [features] prudpv0 = ["dep:prudpv0"] prudpv1 = ["dep:prudpv1"] +prudplite = ["dep:prudplite"] friends = ["prudpv0", "prudpv0/friends"] splatoon = ["prudpv1"] diff --git a/proxy/src/lib.rs b/proxy/src/lib.rs index 2c52a9a..ea5b02c 100644 --- a/proxy/src/lib.rs +++ b/proxy/src/lib.rs @@ -8,6 +8,8 @@ cfg_if! { pub use prudpv0::*; } else if #[cfg(feature = "prudpv1")] { pub use prudpv1::*; + } else if #[cfg(feature = "prudplite")]{ + pub use prudplite::*; } else { compile_error!("no proxy type has been set"); } diff --git a/prudplite/Cargo.toml b/prudplite/Cargo.toml new file mode 100644 index 0000000..902b1a7 --- /dev/null +++ b/prudplite/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "prudplite" +version = "0.1.0" +edition = "2024" + +[features] +nx = [] +v4-3-11 = [] + +[dependencies] +rnex-core = { path = "../rnex-core", version = "0.1.1" } +tokio = { version = "1.47.0", features = ["full"] } +bytemuck = { version = "1.23.1", features = ["derive"] } +proxy-common = {path = "../proxy-common"} +tokio-tungstenite = {version = "0.28.0", features = ["rustls", "rustls-tls-native-roots"]} +log = "0.4.25" +futures-util = "0.3.31" +v-byte-helpers = { git = "https://github.com/RusticMaple/VByteMacros", version = "0.1.1" } diff --git a/prudplite/src/crypto/insecure.rs b/prudplite/src/crypto/insecure.rs new file mode 100644 index 0000000..34d0f93 --- /dev/null +++ b/prudplite/src/crypto/insecure.rs @@ -0,0 +1,14 @@ +use rnex_core::PID; + +use crate::crypto::Crypto; + +pub struct Insecure; + +impl Crypto for Insecure { + fn new_connection(&self, data: &[u8]) -> Option<(PID, Vec)> { + Some((100, vec![])) + } + fn new() -> Self { + Self + } +} diff --git a/prudplite/src/crypto/mod.rs b/prudplite/src/crypto/mod.rs new file mode 100644 index 0000000..38d8091 --- /dev/null +++ b/prudplite/src/crypto/mod.rs @@ -0,0 +1,9 @@ +use rnex_core::PID; + +pub mod insecure; +pub mod secure; + +pub trait Crypto: 'static + Send + Sync { + fn new_connection(&self, data: &[u8]) -> Option<(PID, Vec)>; + fn new() -> Self; +} diff --git a/prudplite/src/crypto/secure.rs b/prudplite/src/crypto/secure.rs new file mode 100644 index 0000000..4aff759 --- /dev/null +++ b/prudplite/src/crypto/secure.rs @@ -0,0 +1,27 @@ +use rnex_core::{ + PID, executables::common::SECURE_SERVER_ACCOUNT, nex::account::Account, + prudp::ticket::read_secure_connection_data, rmc::structures::RmcSerialize, +}; + +use crate::crypto::Crypto; + +pub struct Secure(&'static Account); + +impl Crypto for Secure { + fn new_connection(&self, data: &[u8]) -> Option<(PID, Vec)> { + let (_, pid, check_value) = read_secure_connection_data(data, &self.0)?; + + let check_value_response = check_value + 1; + + let data = bytemuck::bytes_of(&check_value_response); + + let mut response = Vec::new(); + + data.serialize(&mut response).ok()?; + + Some((pid, response)) + } + fn new() -> Self { + Self(&SECURE_SERVER_ACCOUNT) + } +} diff --git a/prudplite/src/lib.rs b/prudplite/src/lib.rs new file mode 100644 index 0000000..05938d7 --- /dev/null +++ b/prudplite/src/lib.rs @@ -0,0 +1,309 @@ +pub mod crypto; +mod packet; + +use std::{collections::HashMap, net::SocketAddr, sync::Arc}; + +use crate::{ + crypto::{Crypto, insecure::Insecure, secure::Secure}, + packet::{LiteHeader, LitePacket, PacketSpecificData, StreamTypes, create_packet_from}, +}; +use futures_util::{SinkExt, StreamExt}; +use log::{error, info, warn}; +use proxy_common::{ProxyStartupParam, new_backend_connection}; +use rnex_core::{ + PID, + prudp::{ + socket_addr::PRUDPSockAddr, + types_flags::{ + TypesFlags, + flags::{ACK, NEED_ACK, RELIABLE}, + types::{CONNECT, DATA, DISCONNECT, SYN}, + }, + virtual_port::VirtualPort, + }, + util::SplittableBufferConnection, +}; +use tokio::net::{TcpListener, TcpStream}; +use tokio_tungstenite::{ + WebSocketStream, + tungstenite::{ + Bytes, Message, client::IntoClientRequest, http::header::ACCESS_CONTROL_REQUEST_METHOD, + }, +}; + +struct ConnectionState { + param: Arc, + active: bool, + websocket: WebSocketStream, + pid: PID, + backend_conn: SplittableBufferConnection, + addr: PRUDPSockAddr, + incoming_reliable: HashMap>, + client_reliable_counter: u16, + server_reliable_counter: u16, +} + +impl ConnectionState { + pub async fn handle_incoming_prudp(&mut self, packet: LitePacket, sorted: bool) { + let Some(header) = packet.header() else { + warn!("invalid data on connection"); + return; + }; + + if (header.types_flags.get_flags() & NEED_ACK) != 0 { + let data = create_packet_from( + LiteHeader { + stream_types: StreamTypes::new( + self.param.virtual_port.get_stream_type(), + self.addr.virtual_port.get_stream_type(), + ), + source_port: self.param.virtual_port.get_port_number(), + destination_port: self.addr.virtual_port.get_port_number(), + fragment_id: header.fragment_id, + types_flags: TypesFlags::default() + .types(header.types_flags.get_types()) + .flags(ACK), + sequence_id: header.sequence_id, + ..Default::default() + }, + &[], + &[], + ); + let data: Bytes = data.into(); + if header.types_flags.get_types() == DISCONNECT { + self.websocket.send(Message::Binary(data.clone())).await; + self.websocket.send(Message::Binary(data.clone())).await; + } + self.websocket.send(Message::Binary(data)).await; + } + + if (header.types_flags.get_flags() & ACK) != 0 { + // we can just safely ignore acks, we ARE sending over tcp after all already guarantees that our packets will arrive + // we can however not guarantee the order of incoming client packets so we should still take care of that + // (the client might be doing some funny things which we dont know of) + return; + } + + if (header.types_flags.get_flags() & RELIABLE != 0) & !sorted { + self.incoming_reliable.insert(header.sequence_id, packet); + if self.incoming_reliable.len() > 5 { + self.active = false; + warn!("client is spamming out of order reliable packets, throwing out"); + } + return; + } + + match header.types_flags.get_types() { + DATA => { + if header.fragment_id != 0 { + warn!("fragmented packets arent yet supported"); + return; + } + + let Some(payload) = packet.payload() else { + return; + }; + self.backend_conn.send(payload.into()).await; + } + PING => {} + v => { + info!("unimplemented packet type: {}", v); + } + } + } + pub async fn process_reliable(&mut self) { + while let Some(v) = self.incoming_reliable.remove(&self.client_reliable_counter) { + self.handle_incoming_prudp(v, true).await; + self.client_reliable_counter += 1; + } + } + pub async fn handle_connection(&mut self) { + while self.active { + tokio::select! { + v = self.websocket.next() => { + match v { + Some(Ok(Message::Binary(v))) => { + self.handle_incoming_prudp(LitePacket::new(v), false).await; + } + _ => { + info!("client disconnected or errored out"); + return; + } + } + } + v = self.backend_conn.recv() => { + + } + } + } + } +} + +pub async fn websocket_thread_unconnected( + param: Arc, + crypto: Arc, + conn: TcpStream, + addr: SocketAddr, +) { + let mut websocket = match tokio_tungstenite::accept_async(conn).await { + Ok(v) => v, + Err(e) => { + error!("error accepting websocket connection: {}", e); + return; + } + }; + + while let Some(Ok(v)) = websocket.next().await { + match v { + Message::Binary(b) => { + let packet = LitePacket::new(b); + + let Some(header) = packet.header() else { + error!("got malformed message, disconnecting"); + return; + }; + + match header.types_flags.get_types() { + SYN => { + let Some(supported) = packet.packet_specific_iter() else { + error!("got malformed message, disconnecting"); + return; + }; + + let Some(PacketSpecificData::SupportedFunctions(s)) = supported + .into_iter() + .find(|v| matches!(v, PacketSpecificData::SupportedFunctions(_))) + else { + error!("got malformed message, disconnecting"); + return; + }; + + let data = create_packet_from( + LiteHeader { + destination_port: header.source_port, + source_port: param.virtual_port.get_port_number(), + stream_types: StreamTypes::new( + param.virtual_port.get_stream_type(), + header.stream_types.source(), + ), + fragment_id: 0, + sequence_id: 0, + types_flags: TypesFlags::default().types(SYN).flags(ACK), + ..Default::default() + }, + &[ + PacketSpecificData::SupportedFunctions(s & 0xFF), + PacketSpecificData::ConnectionSignature([0; 16]), + ], + &[], + ); + websocket.send(Message::Binary(data.into())).await; + } + CONNECT => { + let Some(supported) = packet.packet_specific_iter() else { + error!("got malformed message, disconnecting"); + return; + }; + + let Some(PacketSpecificData::SupportedFunctions(s)) = supported + .into_iter() + .find(|v| matches!(v, PacketSpecificData::SupportedFunctions(_))) + else { + error!("got malformed message, disconnecting"); + return; + }; + + let Some(data) = packet.payload() else { + error!("got malformed message, disconnecting"); + return; + }; + + let Some((pid, data)) = crypto.new_connection(data) else { + error!("invalid login data"); + return; + }; + + let data = create_packet_from( + LiteHeader { + destination_port: header.source_port, + source_port: param.virtual_port.get_port_number(), + stream_types: StreamTypes::new( + param.virtual_port.get_stream_type(), + header.stream_types.source(), + ), + fragment_id: 0, + sequence_id: 0, + types_flags: TypesFlags::default().types(CONNECT).flags(ACK), + ..Default::default() + }, + &[ + PacketSpecificData::SupportedFunctions(s & 0xFF), + PacketSpecificData::ConnectionSignature([0; 16]), + ], + &data, + ); + websocket.send(Message::Binary(data.into())).await; + + let addr = PRUDPSockAddr::new( + addr, + VirtualPort::new(header.source_port, header.stream_types.source()), + ); + let Some(backend_conn) = new_backend_connection(¶m, addr, pid).await + else { + error!("unable to connect to backend"); + return; + }; + let mut connection = ConnectionState { + active: true, + addr, + pid, + backend_conn, + client_reliable_counter: 2, + server_reliable_counter: 1, + param, + incoming_reliable: HashMap::new(), + websocket, + }; + + connection.handle_connection().await; + break; + } + v => { + error!( + "invalid packet type for unconnected client {}, disconnecting", + v, + ); + } + } + } + v => { + error!("non binary message({:?}) , disconnecting", v); + return; + } + } + } +} + +pub async fn start_proxy(param: ProxyStartupParam) { + let param = Arc::new(param); + let crypto = Arc::new(C::new()); + let listener = TcpListener::bind(param.self_private) + .await + .expect("unable to bind to port"); + + while let Ok((connection, addr)) = listener.accept().await { + let param = param.clone(); + let crypto = crypto.clone(); + tokio::spawn(websocket_thread_unconnected( + param, crypto, connection, addr, + )); + } +} + +pub async fn start_secure(param: ProxyStartupParam) { + start_proxy::(param).await; +} + +pub async fn start_insecure(param: ProxyStartupParam) { + start_proxy::(param).await; +} diff --git a/prudplite/src/main.rs b/prudplite/src/main.rs new file mode 100644 index 0000000..b4d8a0e --- /dev/null +++ b/prudplite/src/main.rs @@ -0,0 +1,45 @@ +use futures_util::{SinkExt, StreamExt}; +use rnex_core::prudp::types_flags::{TypesFlags, flags::NEED_ACK, types::SYN}; +use tokio_tungstenite::tungstenite::{Message, client::IntoClientRequest, http::header}; + +use crate::packet::{LiteHeader, LitePacket, PacketSpecificData, StreamTypes, create_packet_from}; + +mod packet; + +const KEY: &str = "4eb18d39"; + +const URL: &str = "wss://g2DF33D01-lp1.s.n.srv.nintendo.net"; +#[tokio::main] +async fn main() { + let login = URL.into_client_request().unwrap(); + let (mut stream, response) = tokio_tungstenite::connect_async(login).await.unwrap(); + + println!("response: {:?}", response); + + let packet = create_packet_from( + LiteHeader { + stream_types: StreamTypes::new(10, 10), + source_port: 1, + destination_port: 1, + fragment_id: 0, + types_flags: TypesFlags::default().types(SYN).flags(NEED_ACK), + sequence_id: 0, + ..Default::default() + }, + &[PacketSpecificData::SupportedFunctions(0x8)], + &[], + ); + + println!("sending ack"); + stream.send(Message::Binary(packet.into())).await.unwrap(); + println!("waiting for response"); + let packet = stream.next().await.unwrap(); + let Message::Binary(packet) = packet.unwrap() else { + panic!() + }; + let packet = LitePacket::new(packet); + + let header = packet.header().unwrap(); + + println!("{:?}", header); +} diff --git a/prudplite/src/packet.rs b/prudplite/src/packet.rs new file mode 100644 index 0000000..bd8d87c --- /dev/null +++ b/prudplite/src/packet.rs @@ -0,0 +1,223 @@ +use std::{ + fmt::Debug, + io::{self, Cursor, Read, Write}, +}; + +use bytemuck::{Pod, Zeroable, bytes_of}; +use futures_util::Stream; +use rnex_core::prudp::types_flags::TypesFlags; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; + +#[derive(Pod, Zeroable, Copy, Clone, Default, Debug)] +#[repr(C)] +pub struct LiteHeader { + pub magic: u8, + pub packet_specific_length: u8, + pub payload_size: u16, + pub stream_types: StreamTypes, + pub source_port: u8, + pub destination_port: u8, + pub fragment_id: u8, + pub types_flags: TypesFlags, + pub sequence_id: u16, +} + +pub enum PacketSpecificData { + SupportedFunctions(u32), + ConnectionSignature([u8; 16]), + LiteSignature([u8; 16]), +} + +impl PacketSpecificData { + fn consume(reader: &mut impl Read) -> io::Result { + let mut option_id = 0; + reader.read_exact(&mut [option_id])?; + let mut size = 0; + reader.read_exact(&mut [size])?; + + match option_id { + 0 => { + if size != 4 { + Err(io::Error::other( + "invalid option size for supported functions", + )) + } else { + Ok(Self::SupportedFunctions(reader.read_le_u32()?)) + } + } + 1 => { + if size != 16 { + Err(io::Error::other( + "invalid option size for connection signature", + )) + } else { + Ok(Self::ConnectionSignature( + reader.read_struct(IS_BIG_ENDIAN)?, + )) + } + } + 0x80 => { + if size != 16 { + Err(io::Error::other("invalid option size for lite signature")) + } else { + Ok(Self::LiteSignature(reader.read_struct(IS_BIG_ENDIAN)?)) + } + } + _ => Err(io::Error::other("invalid option id")), + } + } + + fn write_size(&self) -> usize { + 2 + match self { + PacketSpecificData::SupportedFunctions(_) => 4, + Self::ConnectionSignature(_) => 16, + Self::LiteSignature(_) => 16, + } + } + + fn write_self(&self, writer: &mut impl Write) -> io::Result<()> { + match self { + PacketSpecificData::SupportedFunctions(v) => { + writer.write_all(&[0, 4])?; + writer.write_all(&v.to_le_bytes())?; + } + Self::ConnectionSignature(v) => { + writer.write_all(&[1, 16])?; + writer.write_all(&v[..])?; + } + Self::LiteSignature(v) => { + writer.write_all(&[0x80, 16])?; + writer.write_all(&v[..])?; + } + } + + Ok(()) + } +} + +pub struct LitePacket>(T); + +pub struct PacketSpecificIter<'a>(Cursor<&'a [u8]>); + +impl<'a> Iterator for PacketSpecificIter<'a> { + type Item = PacketSpecificData; + + fn next(&mut self) -> Option { + PacketSpecificData::consume(&mut self.0).ok() + } +} + +impl> LitePacket { + pub fn new(inner: T) -> Self { + Self(inner) + } + + pub fn header(&self) -> Option<&LiteHeader> { + bytemuck::try_from_bytes(self.0.as_ref().get(..size_of::())?).ok() + } + pub fn header_mut(&mut self) -> Option<&mut LiteHeader> + where + T: AsMut<[u8]>, + { + bytemuck::try_from_bytes_mut(self.0.as_mut().get_mut(..size_of::())?).ok() + } + + pub fn payload(&self) -> Option<&[u8]> { + let header = self.header()?; + self.0 + .as_ref() + .get(size_of::() + header.packet_specific_length as usize..) + } + + pub fn payload_mut(&mut self) -> Option<&mut [u8]> + where + T: AsMut<[u8]>, + { + let len = self.header()?.packet_specific_length; + self.0 + .as_mut() + .get_mut(size_of::() + len as usize..) + } + + pub fn packet_specific_raw(&self) -> Option<&[u8]> { + let header = self.header()?; + self.0.as_ref().get( + size_of::() + ..size_of::() + header.packet_specific_length as usize, + ) + } + pub fn packet_specific_raw_mut(&mut self) -> Option<&mut [u8]> + where + T: AsMut<[u8]>, + { + let len = self.header()?.packet_specific_length; + self.0 + .as_mut() + .get_mut(size_of::()..size_of::() + len as usize) + } + + pub fn packet_specific_iter(&self) -> Option { + self.packet_specific_raw() + .map(Cursor::new) + .map(PacketSpecificIter) + } +} + +pub fn create_packet_from( + header: LiteHeader, + specific_data: &[PacketSpecificData], + data: &[u8], +) -> Vec { + let specific_size: usize = specific_data.iter().map(|v| v.write_size()).sum(); + let mut packet = LitePacket::new(vec![ + 0u8; + size_of::() + specific_size + data.len() + ]); + + *packet.header_mut().expect("packet malformed in creation") = LiteHeader { + magic: 0x80, + packet_specific_length: specific_size as u8, + payload_size: data.len() as u16, + ..header + }; + + let mut cursor = Cursor::new( + packet + .packet_specific_raw_mut() + .expect("packet malformed in creation"), + ); + + for specific in specific_data { + specific.write_self(&mut cursor).unwrap(); + } + + packet + .payload_mut() + .expect("packet malformed in creation") + .copy_from_slice(data); + + packet.0 +} + +#[derive(Pod, Zeroable, Copy, Clone, Default)] +#[repr(transparent)] +pub struct StreamTypes(u8); + +impl Debug for StreamTypes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "({},{})", self.source(), self.destination()) + } +} + +impl StreamTypes { + pub fn new(source_stream: u8, dest_stream: u8) -> Self { + Self((source_stream & 0xF << 4) & dest_stream & 0xF) + } + + pub fn source(&self) -> u8 { + self.0 >> 4 + } + pub fn destination(&self) -> u8 { + self.0 & 0xF + } +} diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index aa603f7..1305d81 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -100,7 +100,7 @@ impl Server { }; /* we leave the sequence id as is for now as it defaults to 0 */ - *packet.checksum_mut().expect("packet malformed in creation") = + packet.checksum_mut().expect("packet malformed in creation") = self.crypto.calculate_checksum( packet .checksummed_data() @@ -434,7 +434,7 @@ impl Server { info!("len: {}", packet.0.len()); - let addr = PRUDPSockAddr::new(addr, header.source); + let addr = PRUDPSockAddr::new(SocketAddr::V4(addr), header.source); if let Some(conn) = self.get_connection(addr).await { let mut inner = conn.inner.lock().await; diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 69a4f9f..3a05177 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -34,6 +34,11 @@ ureq = "3.1.4" rmc_struct_header = [] guest_login = [] friends = ["guest_login"] +big_pid = [] +v3-8-15 = ["rmc_struct_header"] +v4-3-11 = ["v3-8-15"] +nx = ["big_pid"] + [[bench]] name = "rmc_serialization" diff --git a/rnex-core/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs index 51d9647..91b83b3 100644 --- a/rnex-core/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -17,6 +17,7 @@ async fn main() { if #[cfg(feature = "friends")]{ start_friends_backend().await; } else { + use rnex_core::executables::regular_backend; regular_backend::start_regular_backend().await } } diff --git a/rnex-core/src/executables/friends_backend.rs b/rnex-core/src/executables/friends_backend.rs index 2626fbe..7ea03b4 100644 --- a/rnex-core/src/executables/friends_backend.rs +++ b/rnex-core/src/executables/friends_backend.rs @@ -1,22 +1,65 @@ -use std::sync::{Arc, atomic::AtomicU32}; +use std::{ + io::Cursor, + net::SocketAddrV4, + sync::{Arc, atomic::AtomicU32}, +}; + +use log::error; +use tokio::net::TcpListener; use crate::{ - executables::common::new_simple_backend, - nex::friends_handler::{FriendsManager, FriendsUser}, + executables::common::{OWN_IP_PRIVATE, SERVER_PORT, new_simple_backend}, + nex::friends_handler::{FriendsGuest, FriendsManager, FriendsUser}, + reggie::UnitPacketRead, + rmc::{ + protocols::{RmcCallable, new_rmc_gateway_connection}, + structures::RmcSerialize, + }, + rnex_proxy_common::ConnectionInitData, }; pub async fn start_friends_backend() { let fm = Arc::new(FriendsManager { cid_counter: AtomicU32::new(1), }); + let listen = TcpListener::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) + .await + .unwrap(); + while let Ok((mut stream, _addr)) = listen.accept().await { + let buffer = match stream.read_buffer().await { + Ok(v) => v, + Err(e) => { + error!( + "an error ocurred whilest reading connection data buffer: {:?}", + e + ); + continue; + } + }; - new_simple_backend(move |c, r| { + let user_connection_data = ConnectionInitData::deserialize(&mut Cursor::new(buffer)); + + let c = match user_connection_data { + Ok(v) => v, + Err(e) => { + error!("an error ocurred whilest reading connection data: {:?}", e); + continue; + } + }; let fm = fm.clone(); - Arc::new_cyclic(move |this| FriendsUser { - fm, - addr: c.prudpsock_addr, - pid: c.pid, - }) - }) - .await; + if c.pid != 100 { + new_rmc_gateway_connection(stream.into(), move |r| { + Arc::new_cyclic(move |this| FriendsUser { + fm, + addr: c.prudpsock_addr, + pid: c.pid, + }) + }); + } else { + Arc::new_cyclic(move |this| FriendsGuest { + fm, + addr: c.prudpsock_addr, + }); + } + } } diff --git a/rnex-core/src/grpc/account.rs b/rnex-core/src/grpc/account.rs index a70149f..64be4e9 100644 --- a/rnex-core/src/grpc/account.rs +++ b/rnex-core/src/grpc/account.rs @@ -1,29 +1,27 @@ -use std::{env, result}; +use crate::grpc::account::Error::SomethingHappened; +use json::{JsonValue, object}; +use once_cell::sync::Lazy; +use rnex_core::PID; use std::array::TryFromSliceError; use std::ops::Deref; -use json::{object, JsonValue}; -use once_cell::sync::Lazy; +use std::{env, result}; use thiserror::Error; -use tokio::task::{spawn_blocking, JoinError}; -use crate::grpc::account::Error::SomethingHappened; -static API_KEY: Lazy = Lazy::new(||{ - let key = env::var("ACCOUNT_GQL_API_KEY") - .expect("no graphql ip specified"); +use tokio::task::{JoinError, spawn_blocking}; +static API_KEY: Lazy = Lazy::new(|| { + let key = env::var("ACCOUNT_GQL_API_KEY").expect("no graphql ip specified"); key }); -static CLIENT_URI: Lazy = Lazy::new(||{ +static CLIENT_URI: Lazy = Lazy::new(|| { env::var("ACCOUNT_GQL_URL") .ok() .and_then(|s| s.parse().ok()) .expect("no graphql ip specified") }); - - #[derive(Error, Debug)] -pub enum Error{ +pub enum Error { #[error(transparent)] RequestError(#[from] ureq::Error), #[error(transparent)] @@ -35,20 +33,20 @@ pub enum Error{ #[error("something happened")] SomethingHappened, #[error("error joining blocking task: {0}")] - Join(#[from] JoinError) + Join(#[from] JoinError), } pub type Result = result::Result; -pub struct Client;//(reqwest::Client); +pub struct Client; //(reqwest::Client); -impl Client{ +impl Client { pub async fn new() -> Result { //Ok(Self(reqwest::ClientBuilder::new().build()?)) Ok(Self) } - async fn do_request(&self, request_data: JsonValue) -> Result{ + async fn do_request(&self, request_data: JsonValue) -> Result { let request = ureq::post(CLIENT_URI.as_str()) .header("X-API-Key", API_KEY.deref()) .content_type("application/json"); @@ -70,28 +68,35 @@ impl Client{ */ } - pub async fn get_nex_password(&mut self , pid: u32) -> Result<[u8; 16]>{ - let req = self.do_request(object!{ - "query": r"query($pid: Int!){ + pub async fn get_nex_password(&mut self, pid: PID) -> Result<[u8; 16]> { + let req = self + .do_request(object! { + "query": r"query($pid: Int!){ userByPid(pid: $pid){ nexPassword } }", - "variables": { - "pid": pid - } - }).await?; + "variables": { + "pid": pid + } + }) + .await?; - let Some(val) = req.entries() + let Some(val) = req + .entries() .find(|v| v.0 == "data") - .ok_or(SomethingHappened)?.1 + .ok_or(SomethingHappened)? + .1 .entries() .find(|v| v.0 == "userByPid") - .ok_or(SomethingHappened)?.1 + .ok_or(SomethingHappened)? + .1 .entries() .find(|v| v.0 == "nexPassword") - .ok_or(SomethingHappened)?.1 - .as_str() else { + .ok_or(SomethingHappened)? + .1 + .as_str() + else { return Err(SomethingHappened); }; @@ -109,8 +114,6 @@ impl Client{ }*/ } - - /* pub struct Client(AccountClient>); @@ -148,4 +151,4 @@ impl Client{ Ok(response) } } -*/ \ No newline at end of file +*/ diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index 4b56f56..d02afa1 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -6,18 +6,21 @@ use hmac::Mac; use md5::{Digest, Md5}; use rc4::KeyInit; use rc4::cipher::StreamCipherCoreWrapper; -use rc4::consts::U16; use rc4::{Rc4, Rc4Core, StreamCipher}; use rnex_core::rmc::structures::RmcSerialize; use std::io::{Read, Write}; +use typenum::U16; use typenum::Unsigned; use rnex_core::rmc::structures::Result; +use rnex_core::PID; + cfg_if! { if #[cfg(feature = "friends")]{ pub type SESSION_KEY_LENGTH_TY = U16; } else { + use rc4::consts::U32; pub type SESSION_KEY_LENGTH_TY = U32; } } @@ -25,7 +28,7 @@ pub const SESSION_KEY_LENGTH: usize = SESSION_KEY_LENGTH_TY::USIZE; type Md5Hmac = Hmac; -pub fn derive_key(pid: u32, password: &[u8]) -> [u8; 16] { +pub fn derive_key(pid: PID, password: &[u8]) -> [u8; 16] { let iteration_count = 65000 + pid % 1024; // we do one iteration out here to ensure the key is always 16 bytes @@ -125,12 +128,12 @@ impl RmcSerialize for KerberosDateTime { #[repr(C, packed)] pub struct TicketInternalData { pub issued_time: KerberosDateTime, - pub pid: u32, + pub pid: PID, pub session_key: [u8; SESSION_KEY_LENGTH], } impl TicketInternalData { - pub(crate) fn new(pid: u32) -> Self { + pub(crate) fn new(pid: PID) -> Self { Self { issued_time: KerberosDateTime::now(), pid, @@ -162,7 +165,7 @@ impl TicketInternalData { #[repr(C, packed)] pub struct Ticket { pub session_key: [u8; SESSION_KEY_LENGTH], - pub pid: u32, + pub pid: PID, } impl Ticket { diff --git a/rnex-core/src/lib.rs b/rnex-core/src/lib.rs index 3920565..28bdd48 100644 --- a/rnex-core/src/lib.rs +++ b/rnex-core/src/lib.rs @@ -4,7 +4,10 @@ #![allow(async_fn_in_trait)] //#![warn(missing_docs)] - +#[cfg(feature = "big_pid")] +pub type PID = u64; +#[cfg(not(feature = "big_pid"))] +pub type PID = u32; extern crate self as rnex_core; @@ -12,18 +15,18 @@ pub mod prudp; pub mod rmc; //mod protocols; +pub mod common; +pub mod executables; pub mod grpc; pub mod kerberos; pub mod nex; -pub mod result; -pub mod versions; -pub mod common; pub mod reggie; +pub mod result; pub mod rnex_proxy_common; pub mod util; -pub mod executables; +pub mod versions; pub use macros::*; -pub mod config{ +pub mod config { pub const FEATURE_HAS_STRUCT_HEADER: bool = cfg!(feature = "rmc_struct_header"); } diff --git a/rnex-core/src/nex/account.rs b/rnex-core/src/nex/account.rs index b3a5bb6..eb542ff 100644 --- a/rnex-core/src/nex/account.rs +++ b/rnex-core/src/nex/account.rs @@ -1,16 +1,16 @@ use macros::RmcSerialize; +use rnex_core::PID; + #[derive(RmcSerialize, Clone)] pub struct Account { - pub pid: u32, + pub pid: PID, pub username: String, pub kerbros_password: Box<[u8]>, } impl Account { - pub fn new(pid: u32, username: &str, passwd: &str) -> Self { - let passwd_data = passwd.as_bytes(); - + pub fn new(pid: PID, username: &str, passwd: &str) -> Self { Self { kerbros_password: passwd.as_bytes().into(), username: username.into(), @@ -18,7 +18,7 @@ impl Account { } } - pub fn new_raw_password(pid: u32, username: &str, passwd: &[u8]) -> Self { + pub fn new_raw_password(pid: PID, username: &str, passwd: &[u8]) -> Self { Self { kerbros_password: passwd.into(), username: username.into(), @@ -26,7 +26,7 @@ impl Account { } } - pub fn get_login_data(&self) -> (u32, &[u8]) { + pub fn get_login_data(&self) -> (PID, &[u8]) { (self.pid, &self.kerbros_password) } } diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index 0ab6910..4d5392d 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -4,6 +4,7 @@ use crate::{define_rmc_proto, kerberos}; use cfg_if::cfg_if; use log::{info, warn}; use macros::rmc_struct; +use rnex_core::PID; use rnex_core::kerberos::{KerberosDateTime, Ticket, derive_key}; use rnex_core::nex::account::Account; use rnex_core::rmc::protocols::OnlyRemote; @@ -16,7 +17,7 @@ use rnex_core::rmc::structures::connection_data::ConnectionDataOld; use rnex_core::rmc::structures::qresult::QResult; use std::hash::{DefaultHasher, Hasher}; use std::net::SocketAddrV4; -use std::sync::{Arc, LazyLock, OnceLock}; +use std::sync::{Arc, LazyLock}; define_rmc_proto!( proto AuthClientProtocol{ @@ -33,8 +34,8 @@ pub struct AuthHandler { } pub fn generate_ticket( - source_act_login_data: (u32, &[u8]), - dest_act_login_data: (u32, &[u8]), + source_act_login_data: (PID, &[u8]), + dest_act_login_data: (PID, &[u8]), ) -> Box<[u8]> { let source_key = derive_key(source_act_login_data.0, source_act_login_data.1); let dest_key = derive_key(dest_act_login_data.0, dest_act_login_data.1); @@ -50,8 +51,28 @@ pub fn generate_ticket( encrypted_session_ticket } +pub fn generate_ticket_with_string_user_key( + source_act: PID, + dest_act_login_data: (PID, &[u8]), +) -> (String, Box<[u8]>) { + let source_key: [u8; 8] = rand::random(); + let key_string = hex::encode(source_key); + let key_data: [u8; 16] = key_string.as_bytes().try_into().unwrap(); + let dest_key = derive_key(dest_act_login_data.0, dest_act_login_data.1); -async fn get_login_data_by_pid(pid: u32) -> Option<(u32, Box<[u8]>)> { + let internal_data = kerberos::TicketInternalData::new(source_act); + + let encrypted_inner = internal_data.encrypt(dest_key); + let encrypted_session_ticket = Ticket { + pid: dest_act_login_data.0, + session_key: internal_data.session_key, + } + .encrypt(key_data, &encrypted_inner); + + (key_string, encrypted_session_ticket) +} + +async fn get_login_data_by_pid(pid: PID) -> Option<(PID, Box<[u8]>)> { if pid == GUEST_ACCOUNT.pid { let source_login_data = GUEST_ACCOUNT.get_login_data(); @@ -84,7 +105,7 @@ impl AuthHandler { pub async fn generate_ticket_from_name( &self, name: &str, - ) -> Result<(u32, Box<[u8]>), ErrorCode> { + ) -> Result<(PID, Box<[u8]>), ErrorCode> { #[cfg(feature = "guest_login")] { if name == GUEST_ACCOUNT.username { @@ -120,13 +141,39 @@ impl AuthHandler { generate_ticket(source_login_data, destination_login_data), )) } + + pub async fn generate_ticket_from_name_string_user_key( + &self, + name: &str, + ) -> Result<(PID, String, Box<[u8]>), ErrorCode> { + #[cfg(feature = "guest_login")] + { + if name == GUEST_ACCOUNT.username { + let source_login_data = GUEST_ACCOUNT.get_login_data(); + let destination_login_data = self.destination_server_acct.get_login_data(); + + return Ok(( + source_login_data.0, + generate_ticket(source_login_data, destination_login_data), + )); + } + } + let Ok(pid) = name.parse() else { + warn!("unable to connect to parse pid: {}", name); + return Err(ErrorCode::Core_InvalidArgument); + }; + let destination_login_data = self.destination_server_acct.get_login_data(); + + let data = generate_ticket_with_string_user_key(pid, destination_login_data); + Ok((pid, data.0, data.1)) + } } impl Auth for AuthHandler { async fn login( &self, name: String, - ) -> Result<(QResult, u32, Vec, ConnectionDataOld, String), ErrorCode> { + ) -> Result<(QResult, PID, Vec, ConnectionDataOld, String), ErrorCode> { let (pid, ticket) = self.generate_ticket_from_name(&name).await?; let result = QResult::success(Core_Unknown); @@ -157,103 +204,135 @@ impl Auth for AuthHandler { info!("data: {:?}", ret); Ok(ret) } + cfg_if! { - async fn login_ex( - &self, - name: String, - _extra_data: Any, - ) -> Result<(QResult, u32, Vec, ConnectionData, String), ErrorCode> { - let (pid, ticket) = self.generate_ticket_from_name(&name).await?; + if #[cfg(feature = "nx")]{ + async fn login_ex( + &self, + name: String, + _extra_data: Any, + ) -> Result<(QResult, PID, Vec, ConnectionData, String, String), ErrorCode> { + let (pid, key, ticket) = self.generate_ticket_from_name_string_user_key(&name).await?; - let result = QResult::success(Core_Unknown); + let result = QResult::success(Core_Unknown); - let mut hasher = DefaultHasher::new(); + let mut hasher = DefaultHasher::new(); - hasher.write(name.as_bytes()); + hasher.write(name.as_bytes()); - let Ok(addr) = self.control_server.get_url(hasher.finish()).await else { - warn!("no secure proxies"); - return Err(ErrorCode::Core_Exception); - }; + let Ok(addr) = self.control_server.get_url(hasher.finish()).await else { + warn!("no secure proxies"); + return Err(ErrorCode::Core_Exception); + }; - let connection_data = ConnectionData { - station_url: station_url_from_sock_addr(addr), - special_station_url: "".to_string(), - //date_time: KerberosDateTime::new(1,1,1,1,1,1), - date_time: KerberosDateTime::now(), - special_protocols: Vec::new(), - }; + let connection_data = ConnectionData { + station_url: station_url_from_sock_addr(addr), + special_station_url: "".to_string(), + //date_time: KerberosDateTime::new(1,1,1,1,1,1), + date_time: KerberosDateTime::now(), + special_protocols: Vec::new(), + }; - let ret = ( - result, - pid, - ticket.into(), - connection_data, - self.build_name.to_string(), - ); + let ret = ( + result, + pid, + ticket.into(), + connection_data, + self.build_name.to_string(), + key + ); - info!("data: {:?}", ret); - Ok(ret) - } + info!("data: {:?}", ret); + Ok(ret) + } + async fn request_ticket( + &self, + source_pid: PID, + destination_pid: PID, + ) -> Result<(QResult, Vec, String), ErrorCode> { + let Some((pid, _)) = get_login_data_by_pid(source_pid).await else { + return Err(ErrorCode::Core_Exception); + }; - async fn request_ticket( - &self, - source_pid: u32, - destination_pid: u32, - ) -> Result<(QResult, Vec), ErrorCode> { - let Some((pid, passwd)) = get_login_data_by_pid(source_pid).await else { - return Err(ErrorCode::Core_Exception); - }; + let desgination_login_data = if destination_pid == self.destination_server_acct.pid { + self.destination_server_acct.get_login_data() + } else { + return Err(ErrorCode::RendezVous_InvalidOperation); + }; - let desgination_login_data = if destination_pid == self.destination_server_acct.pid { - self.destination_server_acct.get_login_data() + let result = QResult::success(Core_Unknown); + + let ticket = generate_ticket_with_string_user_key(pid, desgination_login_data); + + Ok((result, ticket.1.into(), ticket.0)) + } } else { - return Err(ErrorCode::RendezVous_InvalidOperation); - }; + async fn login_ex( + &self, + name: String, + _extra_data: Any, + ) -> Result<(QResult, PID, Vec, ConnectionData, String), ErrorCode> { + let (pid, ticket) = self.generate_ticket_from_name(&name).await?; - let result = QResult::success(Core_Unknown); + let result = QResult::success(Core_Unknown); - let ticket = generate_ticket((pid, &passwd[..]), desgination_login_data); + let mut hasher = DefaultHasher::new(); - Ok((result, ticket.into())) + hasher.write(name.as_bytes()); + + let Ok(addr) = self.control_server.get_url(hasher.finish()).await else { + warn!("no secure proxies"); + return Err(ErrorCode::Core_Exception); + }; + + let connection_data = ConnectionData { + station_url: station_url_from_sock_addr(addr), + special_station_url: "".to_string(), + //date_time: KerberosDateTime::new(1,1,1,1,1,1), + date_time: KerberosDateTime::now(), + special_protocols: Vec::new(), + }; + + let ret = ( + result, + pid, + ticket.into(), + connection_data, + self.build_name.to_string(), + ); + + info!("data: {:?}", ret); + Ok(ret) + } + async fn request_ticket( + &self, + source_pid: PID, + destination_pid: PID, + ) -> Result<(QResult, Vec), ErrorCode> { + let Some((pid, passwd)) = get_login_data_by_pid(source_pid).await else { + return Err(ErrorCode::Core_Exception); + }; + + let desgination_login_data = if destination_pid == self.destination_server_acct.pid { + self.destination_server_acct.get_login_data() + } else { + return Err(ErrorCode::RendezVous_InvalidOperation); + }; + + let result = QResult::success(Core_Unknown); + + let ticket = generate_ticket((pid, &passwd[..]), desgination_login_data); + + Ok((result, ticket.into())) + } + } } async fn get_pid(&self, _username: String) -> Result { Err(ErrorCode::Core_Exception) } - async fn get_name(&self, _pid: u32) -> Result { + async fn get_name(&self, _pid: PID) -> Result { Err(ErrorCode::Core_Exception) } } - -#[cfg(test)] -mod test { - use rnex_core::rmc::response::RMCResponse; - use rnex_core::rmc::structures::RmcSerialize; - use rnex_core::rmc::structures::connection_data::ConnectionData; - use rnex_core::rmc::structures::qresult::QResult; - use std::io::Cursor; - - #[test] - fn test() { - return; - let stuff = hex::decode("200100000a0106000000028000000100010051b3995774000000a6321c7f78847c1c5e9fb825eb26bd91841f1a40d92fc694159666119cb13527f1463ac48ad42a63e6613ede67041554b1770978112e6f1f3e177a2bfc75933216dbe38f70133a1eb28e2ae32a4b5c4b0c3e3efd4c02907992e259b257270b57a9dbe7792f4721b07f8fafb9e32d50f2555c616a015c0000004b007072756470733a2f5049443d323b7369643d313b73747265616d3d31303b747970653d323b616464726573733d322e3234332e39352e3131333b706f72743d31303030313b4349443d3100000000000100002c153ba51f00000033006272616e63683a6f726967696e2f70726f6a6563742f7775702d61676d6a206275696c643a335f385f31355f323030345f3000").unwrap(); - let stuff = RMCResponse::new(&mut Cursor::new(stuff)).unwrap(); - - let rnex_core::rmc::response::RMCResponseResult::Success { .. } = stuff.response_result - else { - panic!() - }; - - // let stuff = hex::decode("0100010051B399577400000085F1736FCFBE93660275A3FE36FED6C2EFC57222AC99A9219CF54170A415B02DF1463AC48AD42A6307813FDE67041554B177097832ED000F892D9551A09F88E9CB0388DC1BC9527CC7384556A3287B2A349ABBF7E34A5A3EC14C2287CC7F78DA616BC3B03A035347FBD2E9A505C8EF42447CD809015F0000004E007072756470733A2F73747265616D3D31303B747970653D323B616464726573733D3139322E3136382E3137382E3132303B706F72743D31303030313B4349443D313B5049443D323B7369643D310000000000010000CDF53AA51F00000033006272616E63683A6F726967696E2F70726F6A6563742F7775702D61676D6A206275696C643A335F385F31355F323030345F3000").unwrap(); - let stuff = hex::decode("0100010051b399577400000037d3d4814d2b16dd546c94a75d32637b45f856b5abe73cf26cfaa235c5f2c1cef1463ac48ad42a637d873fde67041554b177097880cfa7e10bb810eaf686bfb0a0cf3d65b1f476ebc046d0855327986f557dca14fbb8594883c186b863f2206f22baa0309dbcc81da2f883cb2cdc12628ec7fced015c0000004b007072756470733a2f5049443d323b7369643d313b73747265616d3d31303b747970653d323b616464726573733d322e3234332e39352e3131333b706f72743d31303030313b4349443d310000000000010000b7f33aa51f00000033006272616e63683a6f726967696e2f70726f6a6563742f7775702d61676d6a206275696c643a335f385f31355f323030345f3000").unwrap(); - - let data = <(QResult, u32, Vec, ConnectionData, String) as RmcSerialize>::deserialize( - &mut Cursor::new(stuff), - ) - .unwrap(); - - println!("data: {:?}", data); - } -} diff --git a/rnex-core/src/nex/common.rs b/rnex-core/src/nex/common.rs index d2fa40f..48b080d 100644 --- a/rnex-core/src/nex/common.rs +++ b/rnex-core/src/nex/common.rs @@ -8,10 +8,12 @@ use rnex_core::rmc::response::ErrorCode::Core_Exception; use rnex_core::prudp::socket_addr::PRUDPSockAddr; use rnex_core::rmc::response::ErrorCode; +use rnex_core::PID; + pub async fn get_station_urls( station_urls: &[StationUrl], addr: PRUDPSockAddr, - pid: u32, + pid: PID, cid: u32, ) -> Result, ErrorCode> { let mut public_station: Option = None; @@ -66,7 +68,7 @@ pub async fn get_station_urls( public_station .options - .push(Address(*addr.regular_socket_addr.ip())); + .push(Address(addr.regular_socket_addr.ip().clone())); public_station .options .push(Port(addr.regular_socket_addr.port())); diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index a2d42ca..be5d684 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -1,5 +1,4 @@ use std::sync::{Arc, atomic::AtomicU32}; -use std::time::Duration; use log::info; use macros::rmc_struct; @@ -20,21 +19,33 @@ use rnex_core::{ }, }; use std::sync::atomic::Ordering::Relaxed; -use tokio::time::sleep; use rnex_core::rmc::protocols::friends::{GameKey, MiiV2, PrincipalBasicInfo}; +use rnex_core::PID; + define_rmc_proto!( proto FriendsUser{ Secure, Friends } ); +define_rmc_proto!( + proto FriendsGuest{ + Secure + } +); #[rmc_struct(FriendsUser)] pub struct FriendsUser { pub fm: Arc, pub addr: PRUDPSockAddr, - pub pid: u32, + pub pid: PID, +} + +#[rmc_struct(FriendsGuest)] +pub struct FriendsGuest { + pub fm: Arc, + pub addr: PRUDPSockAddr, } pub struct FriendsManager { @@ -50,9 +61,9 @@ impl FriendsManager { impl Friends for FriendsUser { async fn update_and_get_all_information( &self, - info: NNAInfo, - presence: NintendoPresenceV2, - date_time: KerberosDateTime, + _info: NNAInfo, + _presence: NintendoPresenceV2, + _date_time: KerberosDateTime, ) -> Result< ( PrincipalPreference, @@ -89,10 +100,10 @@ impl Friends for FriendsUser { nna_info: NNAInfo { principal_basic_info: PrincipalBasicInfo { pid: 101, - nnid: "dummyaccount".to_string(), + nnid: "dummy:3".to_string(), mii: MiiV2{ date_time: KerberosDateTime::now(), - name: "Dummy Account".to_string(), + name: "TheDummy".to_string(), mii_data: hex::decode("030000402bd7c32986a771f2dc6b35e31da15e37ff7c0000391e6f006f006d0069000000000000000000000000004040001065033568641e2013661a611821640f0000290052485000000000000000000000000000000000000000000000e838").unwrap(), unk: 0, unk2: 0, @@ -149,12 +160,37 @@ impl Secure for FriendsUser { async fn register_ex( &self, station_urls: Vec, - data: Any, + _data: Any, ) -> Result<(QResult, u32, StationUrl), ErrorCode> { info!("register"); self.register(station_urls).await } - async fn replace_url(&self, target: StationUrl, dest: StationUrl) -> Result<(), ErrorCode> { + async fn replace_url(&self, _target: StationUrl, _dest: StationUrl) -> Result<(), ErrorCode> { + Err(ErrorCode::Core_NotImplemented) + } +} + +impl Secure for FriendsGuest { + async fn register( + &self, + station_urls: Vec, + ) -> Result<(QResult, u32, StationUrl), ErrorCode> { + let cid = self.fm.next_cid(); + Ok(( + QResult::success(ErrorCode::Core_Unknown), + cid, + get_station_urls(&station_urls, self.addr, 100, cid).await?[0].clone(), + )) + } + async fn register_ex( + &self, + station_urls: Vec, + _data: Any, + ) -> Result<(QResult, u32, StationUrl), ErrorCode> { + info!("register"); + self.register(station_urls).await + } + async fn replace_url(&self, _target: StationUrl, _dest: StationUrl) -> Result<(), ErrorCode> { Err(ErrorCode::Core_NotImplemented) } } diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 732c1ea..0a155fa 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -2,6 +2,7 @@ use crate::nex::user::User; use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; use log::info; use rand::random; +use rnex_core::PID; use rnex_core::kerberos::KerberosDateTime; use rnex_core::rmc::protocols::notifications::notification_types::{ HOST_CHANGED, OWNERSHIP_CHANGED, @@ -208,7 +209,7 @@ impl ExtendedMatchmakeSession { .process_notification_event(NotificationEvent { pid_source: initiating_pid, notif_type: 122000, - param_1: self.session.gathering.self_gid, + param_1: self.session.gathering.self_gid as PID, param_2: other_pid, str_param: "".into(), param_3: 0, @@ -240,7 +241,7 @@ impl ExtendedMatchmakeSession { .process_notification_event(NotificationEvent { pid_source: initiating_pid, notif_type: 3001, - param_1: self.session.gathering.self_gid, + param_1: self.session.gathering.self_gid as PID, param_2: *pid, str_param: join_msg.clone(), param_3: self.connected_players.len() as _, @@ -261,7 +262,7 @@ impl ExtendedMatchmakeSession { .process_notification_event(NotificationEvent { pid_source: initiating_pid, notif_type: 3001, - param_1: self.session.gathering.self_gid, + param_1: self.session.gathering.self_gid as PID, param_2: older_pid, str_param: join_msg.clone(), param_3: self.connected_players.len() as _, @@ -393,7 +394,7 @@ impl ExtendedMatchmakeSession { Ok(true) } - pub async fn migrate_ownership(&mut self, initiator_pid: u32) -> Result<(), ErrorCode> { + pub async fn migrate_ownership(&mut self, initiator_pid: PID) -> Result<(), ErrorCode> { let players: Vec<_> = self .connected_players .iter() @@ -414,7 +415,7 @@ impl ExtendedMatchmakeSession { self.broadcast_notification(&NotificationEvent { pid_source: initiator_pid, notif_type: OWNERSHIP_CHANGED, - param_1: self.session.gathering.self_gid, + param_1: self.session.gathering.self_gid as PID, param_2: new_owner.pid, ..Default::default() }) @@ -423,7 +424,7 @@ impl ExtendedMatchmakeSession { Ok(()) } - pub async fn migrate_host(&mut self, initiator_pid: u32) -> Result<(), ErrorCode> { + pub async fn migrate_host(&mut self, initiator_pid: PID) -> Result<(), ErrorCode> { // let players: Vec<_> = self.connected_players.iter().filter_map(|p| p.upgrade()).collect(); self.session.gathering.host_pid = self.session.gathering.owner_pid; @@ -431,7 +432,7 @@ impl ExtendedMatchmakeSession { self.broadcast_notification(&NotificationEvent { pid_source: initiator_pid, notif_type: HOST_CHANGED, - param_1: self.session.gathering.self_gid, + param_1: self.session.gathering.self_gid as PID, ..Default::default() }) .await; @@ -441,7 +442,7 @@ impl ExtendedMatchmakeSession { pub async fn remove_player_from_session( &mut self, - pid: u32, + pid: PID, message: &str, ) -> Result<(), ErrorCode> { self.connected_players @@ -468,7 +469,7 @@ impl ExtendedMatchmakeSession { .process_notification_event(NotificationEvent { notif_type: 3008, pid_source: pid, - param_1: self.session.gathering.self_gid, + param_1: self.session.gathering.self_gid as PID, param_2: pid, str_param: message.to_owned(), ..Default::default() diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 1666d56..d8450e9 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -9,9 +9,10 @@ use crate::rmc::protocols::nat_traversal::{ NatTraversal, RawNatTraversal, RawNatTraversalInfo, RemoteNatTraversal, RemoteNatTraversalConsole, }; +use rnex_core::PID; use rnex_core::prudp::station_url::StationUrl; use rnex_core::prudp::station_url::UrlOptions::{ - Address, NatFiltering, NatMapping, NatType, Port, PrincipalID, RVConnectionID, + Address, NatFiltering, NatMapping, Port, RVConnectionID, }; use rnex_core::rmc::protocols::matchmake_ext::{ MatchmakeExt, RawMatchmakeExt, RawMatchmakeExtInfo, RemoteMatchmakeExt, @@ -31,10 +32,7 @@ use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification use log::info; use macros::rmc_struct; use rnex_core::prudp::socket_addr::PRUDPSockAddr; -use rnex_core::prudp::station_url::nat_types::PUBLIC; -use rnex_core::rmc::response::ErrorCode::{ - Core_Exception, Core_InvalidArgument, RendezVous_AccountExpired, -}; +use rnex_core::rmc::response::ErrorCode::{Core_InvalidArgument, RendezVous_AccountExpired}; use rnex_core::rmc::structures::qresult::QResult; use std::sync::{Arc, Weak}; use tokio::sync::{Mutex, RwLock}; @@ -52,7 +50,7 @@ define_rmc_proto!( #[rmc_struct(UserProtocol)] pub struct User { - pub pid: u32, + pub pid: PID, pub ip: PRUDPSockAddr, pub this: Weak, pub remote: RemoteConsole, @@ -423,7 +421,7 @@ impl Matchmake for User { .process_notification_event(NotificationEvent { notif_type: 110000, pid_source: self.pid, - param_1: gid, + param_1: gid as PID, param_2: self.pid, param_3: 0, str_param: "".to_string(), @@ -444,7 +442,7 @@ impl Matchmake for User { .process_notification_event(NotificationEvent { notif_type: 4000, pid_source: self.pid, - param_1: gid, + param_1: gid as PID, param_2: self.pid, param_3: 0, str_param: "".to_string(), @@ -459,7 +457,7 @@ impl Matchmake for User { async fn migrate_gathering_ownership( &self, gid: u32, - candidates: Vec, + candidates: Vec, _participants_only: bool, ) -> Result<(), ErrorCode> { let session = self.matchmake_manager.get_session(gid).await?; @@ -479,8 +477,8 @@ impl Matchmake for User { .process_notification_event(NotificationEvent { notif_type: 4000, pid_source: self.pid, - param_1: gid, - param_2: *candidate, + param_1: gid as PID, + param_2: *candidate as PID, param_3: 0, str_param: "".to_string(), }) diff --git a/rnex-core/src/prudp/socket_addr.rs b/rnex-core/src/prudp/socket_addr.rs index 4ffac83..e7cdf94 100644 --- a/rnex-core/src/prudp/socket_addr.rs +++ b/rnex-core/src/prudp/socket_addr.rs @@ -3,19 +3,19 @@ use macros::RmcSerialize; use md5::digest::Mac; use rnex_core::prudp::virtual_port::VirtualPort; use std::io::Write; -use std::net::SocketAddrV4; +use std::net::{IpAddr, SocketAddr}; type Md5Hmac = Hmac; #[derive(Eq, PartialEq, Hash, Debug, Copy, Clone, Ord, PartialOrd, RmcSerialize)] #[rmc_struct(0)] pub struct PRUDPSockAddr { - pub regular_socket_addr: SocketAddrV4, + pub regular_socket_addr: SocketAddr, pub virtual_port: VirtualPort, } impl PRUDPSockAddr { - pub fn new(regular_socket_addr: SocketAddrV4, virtual_port: VirtualPort) -> Self { + pub fn new(regular_socket_addr: SocketAddr, virtual_port: VirtualPort) -> Self { Self { regular_socket_addr, virtual_port, @@ -23,9 +23,12 @@ impl PRUDPSockAddr { } pub fn calculate_connection_signature(&self) -> [u8; 16] { - let mut hmac = Md5Hmac::new_from_slice(&[0; 16]).expect("fuck"); + let mut hmac = Md5Hmac::new_from_slice(&[0; 16]).expect("?"); - let data = self.regular_socket_addr.ip().octets().to_vec(); + let data = match self.regular_socket_addr.ip() { + IpAddr::V4(v) => v.octets().to_vec(), + IpAddr::V6(v) => v.octets().to_vec(), + }; //data.extend_from_slice(&self.regular_socket_addr.port().to_be_bytes()); hmac.write_all(&data) diff --git a/rnex-core/src/prudp/station_url.rs b/rnex-core/src/prudp/station_url.rs index a4665c2..e2d4abf 100644 --- a/rnex-core/src/prudp/station_url.rs +++ b/rnex-core/src/prudp/station_url.rs @@ -1,32 +1,35 @@ -use std::net::Ipv4Addr; +use crate::prudp::station_url::Type::{PRUDP, PRUDPS, UDP}; +use crate::prudp::station_url::UrlOptions::{ + Address, ConnectionID, NatFiltering, NatMapping, NatType, PID, PMP, Platform, Port, + PrincipalID, RVConnectionID, StreamID, StreamType, UPNP, +}; +use crate::rmc::structures::Error::StationUrlInvalid; +use crate::rmc::structures::RmcSerialize; +use crate::rmc::structures::helpers::DummyFormatWriter; use log::error; use std::fmt::{Debug, Display, Formatter, Write}; use std::io::Read; -use crate::prudp::station_url::Type::{PRUDP, PRUDPS, UDP}; -use crate::prudp::station_url::UrlOptions::{Address, ConnectionID, NatFiltering, NatMapping, NatType, Platform, PMP, Port, PrincipalID, RVConnectionID, StreamID, StreamType, UPNP, PID}; -use crate::rmc::structures::Error::StationUrlInvalid; -use crate::rmc::structures::helpers::DummyFormatWriter; -use crate::rmc::structures::RmcSerialize; +use std::net::IpAddr; #[derive(Clone, Copy, PartialEq, Eq)] -pub enum Type{ +pub enum Type { UDP, PRUDP, - PRUDPS + PRUDPS, } -pub mod nat_types{ +pub mod nat_types { pub const BEHIND_NAT: u8 = 1; pub const PUBLIC: u8 = 2; } #[derive(Clone, Eq, PartialEq)] pub enum UrlOptions { - Address(Ipv4Addr), + Address(IpAddr), Port(u16), StreamType(u8), StreamID(u8), ConnectionID(u8), - PrincipalID(u32), + PrincipalID(rnex_core::PID), NatType(u8), NatMapping(u8), NatFiltering(u8), @@ -35,82 +38,52 @@ pub enum UrlOptions { Platform(u8), PMP(u8), PID(u32), - } #[derive(Clone, PartialEq, Eq)] -pub struct StationUrl{ +pub struct StationUrl { pub url_type: Type, - pub options: Vec + pub options: Vec, } -impl StationUrl{ - pub fn read_options(options: &str) -> Option>{ +impl StationUrl { + pub fn read_options(options: &str) -> Option> { let mut options_out = Vec::new(); - for option in options.split(';'){ - if option == "" { continue; } + for option in options.split(';') { + if option == "" { + continue; + } let mut option_parts = option.split('='); - let option_name= option_parts.next()?.to_ascii_lowercase(); + let option_name = option_parts.next()?.to_ascii_lowercase(); let option_value = option_parts.next()?; - match option_name.as_ref(){ - "address" => { - options_out.push(Address(option_value.parse().ok()?)) - }, - "port" => { - options_out.push(Port(option_value.parse().ok()?)) - } - "natf" => { - options_out.push(NatFiltering(option_value.parse().ok()?)) - } - "natm" => { - options_out.push(NatMapping(option_value.parse().ok()?)) - } - "sid" => { - options_out.push(StreamID(option_value.parse().ok()?)) - } - "upnp" => { - options_out.push(UPNP(option_value.parse().ok()?)) - } - "type" => { - options_out.push(NatType(option_value.parse().ok()?)) - } - "stream" => { - options_out.push(StreamType(option_value.parse().ok()?)) - } - "RVCID" => { - options_out.push(RVConnectionID(option_value.parse().ok()?)) - } - "rvcid" => { - options_out.push(RVConnectionID(option_value.parse().ok()?)) - } - "pl" => { - options_out.push(Platform(option_value.parse().ok()?)) - } - "pmp" => { - options_out.push(PMP(option_value.parse().ok()?)) - }, - "pid" => { - options_out.push(PID(option_value.parse().ok()?)) - }, - "PID" => { - options_out.push(PID(option_value.parse().ok()?)) - }, + match option_name.as_ref() { + "address" => options_out.push(Address(option_value.parse().ok()?)), + "port" => options_out.push(Port(option_value.parse().ok()?)), + "natf" => options_out.push(NatFiltering(option_value.parse().ok()?)), + "natm" => options_out.push(NatMapping(option_value.parse().ok()?)), + "sid" => options_out.push(StreamID(option_value.parse().ok()?)), + "upnp" => options_out.push(UPNP(option_value.parse().ok()?)), + "type" => options_out.push(NatType(option_value.parse().ok()?)), + "stream" => options_out.push(StreamType(option_value.parse().ok()?)), + "RVCID" => options_out.push(RVConnectionID(option_value.parse().ok()?)), + "rvcid" => options_out.push(RVConnectionID(option_value.parse().ok()?)), + "pl" => options_out.push(Platform(option_value.parse().ok()?)), + "pmp" => options_out.push(PMP(option_value.parse().ok()?)), + "pid" => options_out.push(PID(option_value.parse().ok()?)), + "PID" => options_out.push(PID(option_value.parse().ok()?)), _ => { error!("unimplemented option type, skipping: {}", option_name); } } - - - } Some(options_out) } } -impl TryFrom<&str> for StationUrl{ +impl TryFrom<&str> for StationUrl { type Error = (); fn try_from(value: &str) -> Result { @@ -118,35 +91,30 @@ impl TryFrom<&str> for StationUrl{ let options = &options[2..]; - let url_type = match url_type{ + let url_type = match url_type { "udp" => UDP, "prudp" => PRUDP, "prudps" => PRUDPS, - _ => return Err(()) + _ => return Err(()), }; let options = Self::read_options(options).ok_or(())?; - Ok( - Self{ - url_type, - options - } - ) + Ok(Self { url_type, options }) } } -impl Display for StationUrl{ +impl Display for StationUrl { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let url_type_str = match self.url_type{ + let url_type_str = match self.url_type { UDP => "udp:/", PRUDP => "prudp:/", - PRUDPS => "prudps:/" + PRUDPS => "prudps:/", }; - write!(f, "{}",url_type_str)?; + write!(f, "{}", url_type_str)?; - for option in &self.options{ - match option{ + for option in &self.options { + match option { Address(v) => write!(f, "address={}", v)?, Port(v) => write!(f, "port={}", v)?, StreamType(v) => write!(f, "stream={}", v)?, @@ -168,15 +136,15 @@ impl Display for StationUrl{ } } -impl<'a> Into for &'a StationUrl{ +impl<'a> Into for &'a StationUrl { fn into(self) -> String { let url = self.to_string(); - - url[0..url.len()-1].into() + + url[0..url.len() - 1].into() } } -impl RmcSerialize for StationUrl{ +impl RmcSerialize for StationUrl { fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let str = String::deserialize(reader)?; @@ -197,9 +165,9 @@ impl RmcSerialize for StationUrl{ } } -impl Debug for StationUrl{ +impl Debug for StationUrl { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let str: String = self.into(); f.write_str(&str) } -} \ No newline at end of file +} diff --git a/rnex-core/src/prudp/ticket.rs b/rnex-core/src/prudp/ticket.rs index 9fd094d..98e181f 100644 --- a/rnex-core/src/prudp/ticket.rs +++ b/rnex-core/src/prudp/ticket.rs @@ -2,7 +2,7 @@ use std::io::Cursor; use log::{error, info}; use rc4::{KeyInit, Rc4, Rc4Core, StreamCipher, cipher::StreamCipherCoreWrapper}; -use typenum::{U16, U32}; +use typenum::U16; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::{ @@ -10,19 +10,17 @@ use crate::{ nex::account::Account, rmc::structures::RmcSerialize, }; +use rnex_core::PID; pub fn read_secure_connection_data( data: &[u8], act: &Account, -) -> Option<([u8; SESSION_KEY_LENGTH], u32, u32)> { +) -> Option<([u8; SESSION_KEY_LENGTH], PID, u32)> { let mut cursor = Cursor::new(data); let mut ticket_data: Vec = Vec::deserialize(&mut cursor).ok()?; let mut request_data: Vec = Vec::deserialize(&mut cursor).ok()?; - info!( - "done - request data" - ); + info!("done request data {}", SESSION_KEY_LENGTH); let ticket_data_size = ticket_data.len(); @@ -62,7 +60,7 @@ pub fn read_secure_connection_data( let mut reqest_data_cursor = Cursor::new(request_data); - let pid: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?; + let pid: PID = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?; if pid != ticket_source_pid { let ticket_created_on = issued_time.to_regular_time(); diff --git a/rnex-core/src/rmc/protocols/account_management.rs b/rnex-core/src/rmc/protocols/account_management.rs new file mode 100644 index 0000000..541d1f6 --- /dev/null +++ b/rnex-core/src/rmc/protocols/account_management.rs @@ -0,0 +1,4 @@ +use macros::rmc_proto; + +#[rmc_proto(25)] +pub trait AccountManagement {} diff --git a/rnex-core/src/rmc/protocols/auth.rs b/rnex-core/src/rmc/protocols/auth.rs index 594d9dd..ca387f9 100644 --- a/rnex-core/src/rmc/protocols/auth.rs +++ b/rnex-core/src/rmc/protocols/auth.rs @@ -1,9 +1,21 @@ use crate::rmc::structures::connection_data::{ConnectionData, ConnectionDataOld}; +use cfg_if::cfg_if; use macros::{method_id, rmc_proto}; +use rnex_core::PID; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::any::Any; use rnex_core::rmc::structures::qresult::QResult; +cfg_if! { + if #[cfg(feature = "nx")]{ + type LOGIN_EX_RET = (QResult, PID, Vec, ConnectionData, String, String); + type REQUEST_TICKET_RET = (QResult, Vec, String); + } else { + type LOGIN_EX_RET = (QResult, PID, Vec, ConnectionData, String); + type REQUEST_TICKET_RET = (QResult, Vec); + } +} + /// This is the representation for `Ticket Granting`(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) #[rmc_proto(10)] @@ -14,25 +26,22 @@ pub trait Auth { async fn login( &self, name: String, - ) -> Result<(QResult, u32, Vec, ConnectionDataOld, String), ErrorCode>; + ) -> Result<(QResult, PID, Vec, ConnectionDataOld, String), ErrorCode>; /// representation of the `LoginEx` method(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) #[method_id(2)] - async fn login_ex( - &self, - name: String, - extra_data: Any, - ) -> Result<(QResult, u32, Vec, ConnectionData, String), ErrorCode>; + async fn login_ex(&self, name: String, extra_data: Any) -> Result; - /// representation of the `RequestTicket` method(for details see the - /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) #[method_id(3)] async fn request_ticket( &self, - source_pid: u32, - destination_pid: u32, - ) -> Result<(QResult, Vec), ErrorCode>; + source_pid: PID, + destination_pid: PID, + ) -> Result; + + /// representation of the `RequestTicket` method(for details see the + /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) /// representation of the `GetPID` method(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) @@ -42,7 +51,7 @@ pub trait Auth { /// representation of the `LoginWithContext` method(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) #[method_id(5)] - async fn get_name(&self, pid: u32) -> Result; + async fn get_name(&self, pid: PID) -> Result; // `LoginWithContext` is left out here because we don't need it right now and versioning still // needs to be figured out diff --git a/rnex-core/src/rmc/protocols/matchmake.rs b/rnex-core/src/rmc/protocols/matchmake.rs index 595127a..94edce3 100644 --- a/rnex-core/src/rmc/protocols/matchmake.rs +++ b/rnex-core/src/rmc/protocols/matchmake.rs @@ -2,8 +2,10 @@ use macros::{method_id, rmc_proto}; use rnex_core::prudp::station_url::StationUrl; use rnex_core::rmc::response::ErrorCode; +use rnex_core::PID; + #[rmc_proto(21)] -pub trait Matchmake{ +pub trait Matchmake { #[method_id(2)] async fn unregister_gathering(&self, gid: u32) -> Result; #[method_id(41)] @@ -11,5 +13,10 @@ pub trait Matchmake{ #[method_id(42)] async fn update_session_host(&self, gid: u32, change_owner: bool) -> Result<(), ErrorCode>; #[method_id(44)] - async fn migrate_gathering_ownership(&self, gid: u32, candidates: Vec, participants_only: bool) -> Result<(), ErrorCode>; -} \ No newline at end of file + async fn migrate_gathering_ownership( + &self, + gid: u32, + candidates: Vec, + participants_only: bool, + ) -> Result<(), ErrorCode>; +} diff --git a/rnex-core/src/rmc/protocols/mod.rs b/rnex-core/src/rmc/protocols/mod.rs index 6896cf3..8feb2f3 100644 --- a/rnex-core/src/rmc/protocols/mod.rs +++ b/rnex-core/src/rmc/protocols/mod.rs @@ -1,5 +1,6 @@ #![allow(async_fn_in_trait)] +pub mod account_management; pub mod auth; pub mod friends; pub mod matchmake; diff --git a/rnex-core/src/rmc/protocols/notifications.rs b/rnex-core/src/rmc/protocols/notifications.rs index 164bf83..eef5c6c 100644 --- a/rnex-core/src/rmc/protocols/notifications.rs +++ b/rnex-core/src/rmc/protocols/notifications.rs @@ -1,19 +1,21 @@ -use macros::{method_id, rmc_proto, rmc_struct, RmcSerialize}; +use macros::{RmcSerialize, method_id, rmc_proto, rmc_struct}; -pub mod notification_types{ +use rnex_core::PID; + +pub mod notification_types { pub const OWNERSHIP_CHANGED: u32 = 4000; pub const HOST_CHANGED: u32 = 110000; } #[derive(RmcSerialize, Debug, Default, Clone)] #[rmc_struct(0)] -pub struct NotificationEvent{ - pub pid_source: u32, +pub struct NotificationEvent { + pub pid_source: PID, pub notif_type: u32, - pub param_1: u32, - pub param_2: u32, + pub param_1: PID, + pub param_2: PID, pub str_param: String, - pub param_3: u32, + pub param_3: PID, } #[rmc_proto(14, NoReturn)] @@ -21,4 +23,3 @@ pub trait Notification { #[method_id(1)] async fn process_notification_event(&self, event: NotificationEvent); } - diff --git a/rnex-core/src/rmc/protocols/secure.rs b/rnex-core/src/rmc/protocols/secure.rs index 3df23c6..503bf93 100644 --- a/rnex-core/src/rmc/protocols/secure.rs +++ b/rnex-core/src/rmc/protocols/secure.rs @@ -12,6 +12,7 @@ pub trait Secure { &self, station_urls: Vec, ) -> Result<(QResult, u32, StationUrl), ErrorCode>; + #[method_id(4)] async fn register_ex( &self, diff --git a/rnex-core/src/rmc/structures/matchmake.rs b/rnex-core/src/rmc/structures/matchmake.rs index 9194b97..a1518d1 100644 --- a/rnex-core/src/rmc/structures/matchmake.rs +++ b/rnex-core/src/rmc/structures/matchmake.rs @@ -1,14 +1,16 @@ +use macros::RmcSerialize; use rnex_core::kerberos::KerberosDateTime; use rnex_core::rmc::structures::variant::Variant; -use macros::RmcSerialize; + +use rnex_core::PID; // rmc structure #[derive(RmcSerialize, Debug, Clone, Default)] #[rmc_struct(0)] pub struct Gathering { pub self_gid: u32, - pub owner_pid: u32, - pub host_pid: u32, + pub owner_pid: PID, + pub host_pid: PID, pub minimum_participants: u16, pub maximum_participants: u16, pub participant_policy: u32, @@ -73,7 +75,7 @@ pub struct MatchmakeSessionSearchCriteria { #[rmc_struct(0)] pub struct AutoMatchmakeParam { pub matchmake_session: MatchmakeSession, - pub additional_participants: Vec, + pub additional_participants: Vec, pub gid_for_participation_check: u32, pub auto_matchmake_option: u32, pub join_message: String, @@ -86,7 +88,7 @@ pub struct AutoMatchmakeParam { #[rmc_struct(0)] pub struct CreateMatchmakeSessionParam { pub matchmake_session: MatchmakeSession, - pub additional_participants: Vec, + pub additional_participants: Vec, pub gid_for_participation_check: u32, pub create_matchmake_session_option: u32, pub join_message: String, @@ -103,7 +105,7 @@ pub struct MatchmakeBlockListParam { #[rmc_struct(0)] pub struct JoinMatchmakeSessionParam { pub gid: u32, - pub additional_participants: Vec, + pub additional_participants: Vec, pub gid_for_participation_check: u32, pub join_matchmake_session_open: u32, pub join_matchmake_session_behavior: u8, diff --git a/rnex-core/src/rmc/structures/networking.rs b/rnex-core/src/rmc/structures/networking.rs index 03627af..bc95b9e 100644 --- a/rnex-core/src/rmc/structures/networking.rs +++ b/rnex-core/src/rmc/structures/networking.rs @@ -1,9 +1,37 @@ -use std::io::{Read, Write}; -use std::net::{Ipv4Addr, SocketAddrV4}; +use crate::rmc::structures::{Error, Result, RmcSerialize}; use rnex_core::prudp::virtual_port::VirtualPort; -use crate::rmc::structures::RmcSerialize; +use std::io::{Read, Write}; +use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -impl RmcSerialize for SocketAddrV4{ +impl RmcSerialize for SocketAddr { + fn deserialize(reader: &mut impl std::io::Read) -> Result + where + Self: Sized, + { + let val: u8 = reader.read_struct(IS_BIG_ENDIAN)?; + match val { + 4 => Ok(SocketAddr::V4(SocketAddrV4::deserialize(reader)?)), + 6 => Ok(SocketAddr::V6(SocketAddrV6::deserialize(reader)?)), + v => Err(Error::UnexpectedValue(v as u64)), + } + } + fn serialize(&self, writer: &mut impl Write) -> Result<()> { + match self { + SocketAddr::V4(v) => { + writer.write_all(&[4])?; + v.serialize(writer)?; + } + SocketAddr::V6(v) => { + writer.write_all(&[6])?; + v.serialize(writer)?; + } + } + Ok(()) + } +} + +impl RmcSerialize for SocketAddrV4 { fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.ip().to_bits().serialize(writer)?; self.port().serialize(writer)?; @@ -21,9 +49,35 @@ impl RmcSerialize for SocketAddrV4{ Ok(6) } } +impl RmcSerialize for SocketAddrV6 { + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { + self.ip().to_bits().serialize(writer)?; + self.port().serialize(writer)?; + self.flowinfo().serialize(writer)?; + self.scope_id().serialize(writer)?; + Ok(()) + } -impl RmcSerialize for VirtualPort{ + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { + let ip = u128::deserialize(reader)?; + let port = u16::deserialize(reader)?; + let flowinfo = u32::deserialize(reader)?; + let scope_id = u32::deserialize(reader)?; + + Ok(SocketAddrV6::new( + Ipv6Addr::from_bits(ip), + port, + flowinfo, + scope_id, + )) + } + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(6) + } +} + +impl RmcSerialize for VirtualPort { fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { self.0.serialize(writer)?; @@ -36,4 +90,4 @@ impl RmcSerialize for VirtualPort{ fn serialize_write_size(&self) -> crate::rmc::structures::Result { Ok(1) } -} \ No newline at end of file +} diff --git a/rnex-core/src/rmc/structures/primitives.rs b/rnex-core/src/rmc/structures/primitives.rs index 3bdd835..e3888d4 100644 --- a/rnex-core/src/rmc/structures/primitives.rs +++ b/rnex-core/src/rmc/structures/primitives.rs @@ -1,5 +1,5 @@ use crate::rmc::structures::RmcSerialize; -use bytemuck::bytes_of; +use bytemuck::{bytes_of, bytes_of_mut}; use std::io::{Read, Write}; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; @@ -110,6 +110,23 @@ impl RmcSerialize for u64 { } } +impl RmcSerialize for u128 { + #[inline(always)] + fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { + Ok(writer.write_all(bytes_of(self))?) + } + #[inline(always)] + fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { + let mut data = 0u128; + reader.read_exact(&mut bytes_of_mut(&mut data))?; + Ok(data) + } + #[inline(always)] + fn serialize_write_size(&self) -> crate::rmc::structures::Result { + Ok(8) + } +} + impl RmcSerialize for i64 { #[inline(always)] fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { diff --git a/rnex-core/src/rmc/structures/ranking.rs b/rnex-core/src/rmc/structures/ranking.rs index 1782cba..778c5cf 100644 --- a/rnex-core/src/rmc/structures/ranking.rs +++ b/rnex-core/src/rmc/structures/ranking.rs @@ -20,55 +20,3 @@ struct UploadCompetitionData { struct UserData { name: [u16; 0x10], } - -#[cfg(test)] -mod test { - use crate::rmc::structures::ranking::{UploadCompetitionData, UserData}; - use bytemuck::from_bytes; - use rnex_core::rmc::structures::RmcSerialize; - use std::io::Cursor; - - #[test] - fn test() { - return; - let data: [u8; 0xBD] = [ - 0x00, 0xB8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xA0, - 0x00, 0x00, 0x49, 0x00, 0x7A, 0x00, 0x7A, 0x00, 0x79, 0x00, 0x53, 0x00, 0x50, 0x00, - 0x46, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1F, 0x5E, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x90, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x14, 0x87, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00, - ]; - - let mut cursor = Cursor::new(data); - - let data = - UploadCompetitionData::deserialize(&mut cursor).expect("unable to deserialize data"); - - let user_data: &UserData = from_bytes(&data.player_data.0[..size_of::()]); - - let pos = user_data - .name - .iter() - .position(|v| *v == 0x0000) - .unwrap_or(0x10); - - let mut name = user_data.name[0..pos].to_vec(); - - name.iter_mut().for_each(|v| *v = v.swap_bytes()); - - let name = String::from_utf16(&name).expect("unable to get name"); - - println!("{:?}", name); - - assert!(u8::deserialize(&mut cursor).is_err()) - } -} diff --git a/rnex-core/src/rnex_proxy_common.rs b/rnex-core/src/rnex_proxy_common.rs index 29cb161..7f2c363 100644 --- a/rnex-core/src/rnex_proxy_common.rs +++ b/rnex-core/src/rnex_proxy_common.rs @@ -1,11 +1,9 @@ +use crate::{PID, prudp::socket_addr::PRUDPSockAddr}; use macros::RmcSerialize; -use crate::prudp::socket_addr::PRUDPSockAddr; #[derive(Debug, RmcSerialize)] #[rmc_struct(0)] -pub struct ConnectionInitData{ +pub struct ConnectionInitData { pub prudpsock_addr: PRUDPSockAddr, - pub pid: u32, - + pub pid: PID, } - From b6b7d2559d218938e4fed81f3749439c8e0b6f5d Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 24 Mar 2026 15:20:38 +0100 Subject: [PATCH 059/203] fix type errors in auth_handler.rs --- rnex-core/src/nex/auth_handler.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index 4d5392d..3fa5485 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -146,16 +146,16 @@ impl AuthHandler { &self, name: &str, ) -> Result<(PID, String, Box<[u8]>), ErrorCode> { - #[cfg(feature = "guest_login")] { if name == GUEST_ACCOUNT.username { let source_login_data = GUEST_ACCOUNT.get_login_data(); let destination_login_data = self.destination_server_acct.get_login_data(); - - return Ok(( + let ticket = generate_ticket_with_string_user_key( source_login_data.0, - generate_ticket(source_login_data, destination_login_data), - )); + destination_login_data, + ); + + return Ok((source_login_data.0, ticket.0, ticket.1)); } } let Ok(pid) = name.parse() else { From 4ad883a54d90a62a52e5d93e18ca22cd32c025a4 Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 24 Mar 2026 23:17:22 +0100 Subject: [PATCH 060/203] add debug logging to ticket generation for debugging --- rnex-core/Cargo.toml | 2 +- rnex-core/src/kerberos/mod.rs | 2 +- rnex-core/src/nex/auth_handler.rs | 80 +++++++++++++++++++ rnex-core/src/rmc/response.rs | 89 ++++++++++------------ rnex-core/src/rmc/structures/list.rs | 32 ++++---- rnex-core/src/rmc/structures/mod.rs | 51 ++++++------- rnex-core/src/rmc/structures/primitives.rs | 4 +- rnex-core/src/rmc/structures/qresult.rs | 25 +++--- rnex-core/src/rmc/structures/rmc_struct.rs | 60 +++++++++------ rnex-core/src/rmc/structures/string.rs | 13 ++-- 10 files changed, 227 insertions(+), 131 deletions(-) diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 3a05177..d44c000 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -17,7 +17,7 @@ rand = "0.8.5" cfg-if = "1.0.4" hmac = "0.12.1" md-5 = "^0.10.6" -tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "net", "sync", "fs"] } +tokio = { version = "1.43.0", features = ["full"] } hex = "0.4.3" macros = { path = "../macros" } diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index d02afa1..205c62a 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -161,7 +161,7 @@ impl TicketInternalData { } } -#[derive(Pod, Zeroable, Copy, Clone)] +#[derive(Pod, Zeroable, Debug, Copy, Clone)] #[repr(C, packed)] pub struct Ticket { pub session_key: [u8; SESSION_KEY_LENGTH], diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index 3fa5485..341dc93 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -134,6 +134,7 @@ impl AuthHandler { }; let source_login_data = (pid, &passwd[..]); + println!("{}, {:?}", pid, passwd); let destination_login_data = self.destination_server_acct.get_login_data(); Ok(( @@ -336,3 +337,82 @@ impl Auth for AuthHandler { Err(ErrorCode::Core_Exception) } } + +mod test { + use std::io::Cursor; + + use rc4::{KeyInit, Rc4, StreamCipher}; + use rnex_core::PID; + use rnex_core::kerberos::KerberosDateTime; + use rnex_core::rmc::structures::connection_data::ConnectionData; + use rnex_core::rmc::{ + response::ErrorCode, + structures::{RmcSerialize, qresult::QResult}, + }; + + use crate::kerberos::{self, derive_key}; + use crate::rmc; + use crate::rmc::message::RMCMessage; + use crate::rmc::response::{RMCResponse, RMCResponseResult}; + + #[test] + fn test() { + return; + let packet = [ + 26, 1, 0, 0, 10, 1, 30, 0, 0, 0, 1, 128, 0, 0, 1, 0, 1, 0, 86, 4, 0, 0, 116, 0, 0, 0, + 144, 209, 130, 175, 45, 215, 95, 55, 226, 192, 51, 54, 201, 84, 118, 150, 159, 164, 32, + 103, 134, 252, 199, 168, 178, 5, 6, 208, 206, 241, 94, 23, 136, 37, 109, 247, 156, 252, + 189, 233, 142, 115, 206, 72, 180, 57, 106, 223, 37, 59, 144, 208, 250, 197, 51, 202, + 185, 156, 51, 159, 219, 117, 250, 103, 184, 1, 103, 108, 15, 14, 174, 160, 192, 146, + 135, 10, 55, 125, 68, 181, 88, 127, 183, 34, 4, 213, 19, 146, 81, 56, 248, 213, 241, + 168, 205, 253, 29, 10, 123, 198, 177, 157, 247, 209, 113, 167, 231, 42, 214, 15, 12, + 200, 192, 230, 125, 227, 74, 0, 112, 114, 117, 100, 112, 115, 58, 47, 80, 73, 68, 61, + 50, 59, 115, 105, 100, 61, 49, 59, 115, 116, 114, 101, 97, 109, 61, 49, 48, 59, 116, + 121, 112, 101, 61, 50, 59, 97, 100, 100, 114, 101, 115, 115, 61, 57, 49, 46, 57, 56, + 46, 49, 50, 56, 46, 56, 54, 59, 112, 111, 114, 116, 61, 54, 48, 48, 49, 59, 67, 73, 68, + 61, 49, 0, 0, 0, 0, 0, 1, 0, 0, 162, 243, 240, 168, 31, 0, 0, 0, 51, 0, 98, 114, 97, + 110, 99, 104, 58, 111, 114, 105, 103, 105, 110, 47, 112, 114, 111, 106, 101, 99, 116, + 47, 119, 117, 112, 45, 97, 103, 109, 106, 32, 98, 117, 105, 108, 100, 58, 51, 95, 56, + 95, 49, 53, 95, 50, 48, 48, 52, 95, 48, 0, + ]; + let rmc_packet = RMCResponse::new(&mut Cursor::new(&packet)).unwrap(); + println!("{:?}", rmc_packet); + + let RMCResponseResult::Success { + call_id, + method_id, + data, + } = rmc_packet.response_result + else { + panic!(); + }; + + println!("{}", hex::encode(&data)); + + let mut data = + <(QResult, PID, Vec, ConnectionData, String) as RmcSerialize>::deserialize( + &mut Cursor::new(&data[..]), + ) + .unwrap(); + + println!("{:?}", data); + + let key = derive_key(1110, "AAAAAAAAAAAAAAAA".as_bytes()); + + let mut rc4 = Rc4::new((&key).into()); + + rc4.apply_keystream(&mut data.2); + println!("raw tick: {:?}", data.2); + + let tick: &kerberos::Ticket = + bytemuck::from_bytes(&data.2[..size_of::()]); + + let remainder = &data.2[size_of::()..]; + + println!("tick: {:?}", tick); + let data = as RmcSerialize>::deserialize(&mut Cursor::new(remainder)).unwrap(); + println!("inner ticket raw: {:?}", data); + + println!("{:?}", data); + } +} diff --git a/rnex-core/src/rmc/response.rs b/rnex-core/src/rmc/response.rs index c994f8b..b042877 100644 --- a/rnex-core/src/rmc/response.rs +++ b/rnex-core/src/rmc/response.rs @@ -2,17 +2,18 @@ // attributes but this gets it to not complain anymore #![allow(unused_parens)] -use std::io; -use std::io::{Read, Seek, Write}; -use std::mem::transmute; -use bytemuck::bytes_of; -use log::error; -use v_byte_helpers::EnumTryInto; -use v_byte_helpers::{ReadExtensions, IS_BIG_ENDIAN}; use crate::rmc::response::ErrorCode::Core_Exception; use crate::rmc::structures::qresult::ERROR_MASK; use crate::util::SendingBufferConnection; +use bytemuck::bytes_of; +use log::error; +use std::io; +use std::io::{Read, Seek, Write}; +use std::mem::transmute; +use v_byte_helpers::EnumTryInto; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; +#[derive(Debug, Clone)] pub enum RMCResponseResult { Success { call_id: u32, @@ -25,13 +26,14 @@ pub enum RMCResponseResult { }, } +#[derive(Debug, Clone)] pub struct RMCResponse { pub protocol_id: u8, pub response_result: RMCResponseResult, } impl RMCResponse { - pub fn new(stream: &mut (impl Seek + Read)) -> io::Result{ + pub fn new(stream: &mut (impl Seek + Read)) -> io::Result { // ignore the size for now this will only be used for checking let size: u32 = stream.read_struct(IS_BIG_ENDIAN)?; @@ -46,7 +48,7 @@ impl RMCResponse { let is_success: u8 = stream.read_struct(IS_BIG_ENDIAN)?; - let response_result = if is_success == 0x01{ + let response_result = if is_success == 0x01 { let call_id: u32 = stream.read_struct(IS_BIG_ENDIAN)?; let method_id: u32 = stream.read_struct(IS_BIG_ENDIAN)?; let method_id = method_id & (!0x8000); @@ -55,11 +57,10 @@ impl RMCResponse { stream.read(&mut data)?; - RMCResponseResult::Success { call_id, method_id, - data + data, } } else { let error_code: u32 = stream.read_struct(IS_BIG_ENDIAN)?; @@ -68,7 +69,7 @@ impl RMCResponse { RMCResponseResult::Error { error_code: { - match ErrorCode::try_from(error_code){ + match ErrorCode::try_from(error_code) { Ok(v) => v, Err(()) => { error!("invalid error code {:#010x}", error_code); @@ -77,36 +78,35 @@ impl RMCResponse { } }, call_id, - } }; - Ok(Self{ + Ok(Self { protocol_id, - response_result + response_result, }) } - pub fn get_call_id(&self) -> u32{ - match &self.response_result{ - RMCResponseResult::Success { call_id, ..} => *call_id, - RMCResponseResult::Error { call_id, .. } => *call_id + pub fn get_call_id(&self) -> u32 { + match &self.response_result { + RMCResponseResult::Success { call_id, .. } => *call_id, + RMCResponseResult::Error { call_id, .. } => *call_id, } } pub fn to_data(self) -> Vec { - generate_response(self.protocol_id, self.response_result).expect("failed to generate response") + generate_response(self.protocol_id, self.response_result) + .expect("failed to generate response") } } pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Result> { - let size = 1 + 1 + match &response { - RMCResponseResult::Success { - data, - .. - } => 4 + 4 + data.len(), - RMCResponseResult::Error { .. } => 4 + 4, - }; + let size = 1 + + 1 + + match &response { + RMCResponseResult::Success { data, .. } => 4 + 4 + data.len(), + RMCResponseResult::Error { .. } => 4 + 4, + }; let mut data_out = Vec::with_capacity(size + 4); @@ -119,7 +119,7 @@ pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Re RMCResponseResult::Success { call_id, method_id, - data + data, } => { data_out.push(1); data_out.write_all(bytes_of(&call_id))?; @@ -129,7 +129,7 @@ pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Re } RMCResponseResult::Error { call_id, - error_code + error_code, } => { data_out.push(0); let error_code_val: u32 = error_code.into(); @@ -151,23 +151,21 @@ pub async fn send_result( method_id: u32, call_id: u32, ) { - let response_result = match result { Ok(v) => RMCResponseResult::Success { call_id, method_id, - data: v + data: v, + }, + Err(e) => RMCResponseResult::Error { + call_id, + error_code: e.into(), }, - Err(e) => - RMCResponseResult::Error { - call_id, - error_code: e.into() - } }; - let response = RMCResponse{ + let response = RMCResponse { response_result, - protocol_id + protocol_id, }; send_response(connection, response).await @@ -177,7 +175,6 @@ pub async fn send_response(connection: &SendingBufferConnection, rmcresponse: RM connection.send(rmcresponse.to_data()).await; } - //taken from kinnays error list directly #[allow(nonstandard_style)] #[repr(u32)] @@ -464,25 +461,23 @@ impl Into for ErrorCode { #[cfg(test)] mod test { - use hmac::digest::consts::U5; - use hmac::digest::KeyInit; - use rc4::{Rc4, StreamCipher}; use crate::rmc::response::ErrorCode; + use hmac::digest::KeyInit; + use hmac::digest::consts::U5; + use rc4::{Rc4, StreamCipher}; #[test] fn test() { let data_orig = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 69, 4, 20]; let mut data = data_orig; - let mut rc4: Rc4 = - Rc4::new_from_slice("FUCKE".as_bytes().into()).expect("invalid key"); + let mut rc4: Rc4 = Rc4::new_from_slice("FUCKE".as_bytes().into()).expect("invalid key"); rc4.apply_keystream(&mut data); assert_ne!(data_orig, data); - let mut rc4: Rc4 = - Rc4::new_from_slice("FUCKE".as_bytes().into()).expect("invalid key"); + let mut rc4: Rc4 = Rc4::new_from_slice("FUCKE".as_bytes().into()).expect("invalid key"); rc4.apply_keystream(&mut data); @@ -494,4 +489,4 @@ mod test { let val: u32 = ErrorCode::Core_Unknown.into(); assert_eq!(val, 0x00010001) } -} \ No newline at end of file +} diff --git a/rnex-core/src/rmc/structures/list.rs b/rnex-core/src/rmc/structures/list.rs index 890be9a..7c7db8e 100644 --- a/rnex-core/src/rmc/structures/list.rs +++ b/rnex-core/src/rmc/structures/list.rs @@ -1,19 +1,17 @@ +use crate::rmc::structures::RmcSerialize; +use bytemuck::bytes_of; use std::io::{Read, Write}; use std::mem::MaybeUninit; -use bytemuck::bytes_of; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -use crate::rmc::structures::RmcSerialize; - - -// this is also for implementing `Buffer` this is tecnically not the same as its handled internaly +// this is also for implementing `Buffer` this is tecnically not the same as its handled internaly // probably but as it has the same mapping it doesn't matter and simplifies things -impl RmcSerialize for Vec{ +impl RmcSerialize for Vec { fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { let u32_len = self.len() as u32; writer.write_all(bytes_of(&u32_len))?; - for e in self{ + for e in self { e.serialize(writer)?; } @@ -21,27 +19,31 @@ impl RmcSerialize for Vec{ } fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { + println!("reading list"); let len: u32 = reader.read_struct(IS_BIG_ENDIAN)?; + println!("readijg list: {:?}", len); //let mut vec = Vec::with_capacity(len as usize); - let vec = (0..len).map(|_| T::deserialize(reader)).collect::, _>>()?; + let vec: Vec = (0..len) + .map(|_| T::deserialize(reader)) + .collect::, _>>()?; Ok(vec) } - + fn serialize_write_size(&self) -> crate::rmc::structures::Result { let mut val = 0u32; - for i in self{ + for i in self { val += i.serialize_write_size()?; } Ok(4 + val) } } -impl RmcSerialize for [T; LEN]{ +impl RmcSerialize for [T; LEN] { fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> { - for i in 0..LEN{ + for i in 0..LEN { self[i].serialize(writer)?; } @@ -51,20 +53,20 @@ impl RmcSerialize for [T; LEN]{ fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result { let mut arr = [const { MaybeUninit::::uninit() }; LEN]; - for i in 0..LEN{ + for i in 0..LEN { arr[i] = MaybeUninit::new(T::deserialize(reader)?); } // all of the elements are now initialized so it is safe to assume they are initialized - let arr = arr.map(|v| unsafe{ v.assume_init() }); + let arr = arr.map(|v| unsafe { v.assume_init() }); Ok(arr) } #[inline(always)] fn serialize_write_size(&self) -> crate::rmc::structures::Result { let mut val = 0u32; - for i in self{ + for i in self { val += i.serialize_write_size()?; } Ok(val) diff --git a/rnex-core/src/rmc/structures/mod.rs b/rnex-core/src/rmc/structures/mod.rs index 7a1610c..996cc4b 100644 --- a/rnex-core/src/rmc/structures/mod.rs +++ b/rnex-core/src/rmc/structures/mod.rs @@ -1,12 +1,12 @@ -use std::{fmt, io}; +use crate::rmc::structures::helpers::DummyWriter; use std::io::{Read, Write}; use std::string::FromUtf8Error; +use std::{fmt, io}; use thiserror::Error; -use crate::rmc::structures::helpers::DummyWriter; //ideas for the future: make a proc macro library which allows generation of struct reads #[derive(Error, Debug)] -pub enum Error{ +pub enum Error { #[error("Io Error: {0}")] Io(#[from] io::Error), #[error("UTF8 conversion Error: {0}")] @@ -18,51 +18,52 @@ pub enum Error{ #[error("an error occurred reading the station url")] StationUrlInvalid, #[error("error formatting text: {0}")] - FormatError(#[from] fmt::Error) + FormatError(#[from] fmt::Error), } pub type Result = std::result::Result; -pub mod string; pub mod any; -pub mod qresult; pub mod buffer; pub mod connection_data; -pub mod rmc_struct; -pub mod list; -pub mod qbuffer; -pub mod primitives; -pub mod matchmake; -pub mod variant; -pub mod ranking; -pub mod networking; pub mod helpers; +pub mod list; +pub mod matchmake; +pub mod networking; +pub mod primitives; +pub mod qbuffer; +pub mod qresult; +pub mod ranking; +pub mod rmc_struct; +pub mod string; +pub mod variant; -pub trait RmcSerialize{ +pub trait RmcSerialize { fn serialize(&self, writer: &mut impl Write) -> Result<()>; - fn serialize_write_size(&self) -> Result{ + fn serialize_write_size(&self) -> Result { let mut dummy = DummyWriter::new(); self.serialize(&mut dummy)?; Ok(dummy.get_total_len()) } - fn deserialize(reader: &mut impl Read) -> Result where Self: Sized; + fn deserialize(reader: &mut impl Read) -> Result + where + Self: Sized; - fn to_data(&self) -> Result>{ - let mut data = Vec::with_capacity( - self.serialize_write_size()? as usize - ); + fn to_data(&self) -> Result> { + let expected_size = self.serialize_write_size()?; + let mut data = Vec::with_capacity(expected_size as usize); self.serialize(&mut data)?; - debug_assert_eq!(self.serialize_write_size().unwrap(), data.len() as u32); + debug_assert_eq!(expected_size, data.len() as u32); Ok(data) } } -impl RmcSerialize for (){ +impl RmcSerialize for () { fn serialize(&self, _writer: &mut impl Write) -> Result<()> { Ok(()) } @@ -72,6 +73,4 @@ impl RmcSerialize for (){ fn serialize_write_size(&self) -> Result { Ok(0) } - - -} \ No newline at end of file +} diff --git a/rnex-core/src/rmc/structures/primitives.rs b/rnex-core/src/rmc/structures/primitives.rs index e3888d4..6ce1c2f 100644 --- a/rnex-core/src/rmc/structures/primitives.rs +++ b/rnex-core/src/rmc/structures/primitives.rs @@ -280,8 +280,8 @@ impl Self{ +impl QResult { + pub fn success(error_code: ErrorCode) -> Self { let val: u32 = error_code.into(); Self(val & (!ERROR_MASK)) } - pub fn error(error_code: ErrorCode) -> Self{ + pub fn error(error_code: ErrorCode) -> Self { let val: u32 = error_code.into(); Self(val | ERROR_MASK) } } -impl RmcSerialize for QResult{ +impl RmcSerialize for QResult { fn serialize(&self, writer: &mut impl Write) -> Result<()> { writer.write(bytes_of(self))?; Ok(()) } fn deserialize(reader: &mut impl Read) -> Result { - Ok(reader.read_struct(IS_BIG_ENDIAN)?) + let result: Self = reader.read_struct(IS_BIG_ENDIAN)?; + println!("reading qresult: {:x}", result.0); + Ok(result) } -} \ No newline at end of file + fn serialize_write_size(&self) -> Result { + Ok(4) + } +} diff --git a/rnex-core/src/rmc/structures/rmc_struct.rs b/rnex-core/src/rmc/structures/rmc_struct.rs index 52184bb..7660f96 100644 --- a/rnex-core/src/rmc/structures/rmc_struct.rs +++ b/rnex-core/src/rmc/structures/rmc_struct.rs @@ -1,15 +1,13 @@ - +use crate::rmc::structures::Result; use std::cmp::max; use std::fmt::Arguments; use std::io; use std::io::{ErrorKind, IoSlice, Read, Write}; -use crate::rmc::structures::Result; - #[repr(C, packed)] -struct StructureHeader{ +struct StructureHeader { version: u8, - length: u32 + length: u32, } #[cfg(feature = "rmc_struct_header")] @@ -38,7 +36,12 @@ impl Write for OnlyWriteVec<'_> { } #[cfg(feature = "rmc_struct_header")] -pub fn write_struct(writer: &mut T, version: u8, inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> { +pub fn write_struct( + writer: &mut T, + version: u8, + inner_size: u32, + pred: impl FnOnce(&mut T) -> Result<()>, +) -> Result<()> { use bytemuck::bytes_of; writer.write_all(&[version])?; @@ -50,29 +53,31 @@ pub fn write_struct(writer: &mut T, version: u8, inner_size: u32, pred Ok(()) } - - #[cfg(not(feature = "rmc_struct_header"))] -pub fn write_struct(writer: &mut T, _version: u8, _inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> { +pub fn write_struct( + writer: &mut T, + _version: u8, + _inner_size: u32, + pred: impl FnOnce(&mut T) -> Result<()>, +) -> Result<()> { pred(writer) } - -pub struct SubRead<'a, T: Read>{ +pub struct SubRead<'a, T: Read> { left_to_read: usize, - origin: &'a mut T + origin: &'a mut T, } -impl<'a, T: Read> SubRead<'a, T>{ - pub const fn new(origin: &'a mut T, left_to_read: usize) -> Self{ - Self{ +impl<'a, T: Read> SubRead<'a, T> { + pub const fn new(origin: &'a mut T, left_to_read: usize) -> Self { + Self { left_to_read, - origin + origin, } } } -impl Read for SubRead<'_, T>{ +impl Read for SubRead<'_, T> { #[inline(always)] fn read(&mut self, buf: &mut [u8]) -> io::Result { let max_read = max(self.left_to_read, buf.len()); @@ -83,8 +88,11 @@ impl Read for SubRead<'_, T>{ #[inline(always)] fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { - if buf.len() > self.left_to_read{ - return Err(io::Error::new(ErrorKind::UnexpectedEof, "Would run over end of SubRead")); + if buf.len() > self.left_to_read { + return Err(io::Error::new( + ErrorKind::UnexpectedEof, + "Would run over end of SubRead", + )); } self.left_to_read -= buf.len(); self.origin.read_exact(buf) @@ -92,10 +100,14 @@ impl Read for SubRead<'_, T>{ } #[cfg(feature = "rmc_struct_header")] -pub fn read_struct(reader: &mut R, version: u8, pred: impl FnOnce(&mut SubRead) -> Result) -> Result { +pub fn read_struct( + reader: &mut R, + version: u8, + pred: impl FnOnce(&mut SubRead) -> Result, +) -> Result { use crate::rmc::structures::Error::VersionMismatch; - use v_byte_helpers::ReadExtensions; use v_byte_helpers::IS_BIG_ENDIAN; + use v_byte_helpers::ReadExtensions; let ver: u8 = reader.read_struct(IS_BIG_ENDIAN)?; if ver != version { @@ -108,6 +120,10 @@ pub fn read_struct(reader: &mut R, version: u8, pred: impl Fn } #[cfg(not(feature = "rmc_struct_header"))] -pub fn read_struct(mut reader: &mut R, _version: u8, pred: impl FnOnce(&mut R) -> Result) -> Result { +pub fn read_struct( + mut reader: &mut R, + _version: u8, + pred: impl FnOnce(&mut R) -> Result, +) -> Result { Ok(pred(&mut reader)?) } diff --git a/rnex-core/src/rmc/structures/string.rs b/rnex-core/src/rmc/structures/string.rs index 1231956..8830822 100644 --- a/rnex-core/src/rmc/structures/string.rs +++ b/rnex-core/src/rmc/structures/string.rs @@ -1,18 +1,18 @@ -use std::io::{Read, Write}; +use super::{Result, RmcSerialize}; use bytemuck::bytes_of; use log::error; +use std::io::{Read, Write}; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -use super::{Result, RmcSerialize}; -impl RmcSerialize for String{ +impl RmcSerialize for String { fn deserialize(reader: &mut impl Read) -> Result { let len: u16 = reader.read_struct(IS_BIG_ENDIAN)?; - if len == 0{ + if len == 0 { return Ok("".to_string()); } let mut data = vec![0; len as usize]; reader.read_exact(&mut data)?; - if *data.last().unwrap() != 0{ + if *data.last().unwrap() != 0 { error!("unable to find null terminator... continuing anyways"); } data.pop(); @@ -27,7 +27,7 @@ impl RmcSerialize for String{ } } -impl RmcSerialize for &str{ +impl RmcSerialize for &str { fn deserialize(_reader: &mut impl Read) -> Result { panic!("cannot serialize to &str") } @@ -45,4 +45,3 @@ impl RmcSerialize for &str{ Ok(2 + self.as_bytes().len() as u32 + 1) } } - From aa18d1ee3ebd0c51a30051b01e3faa5a13b143cb Mon Sep 17 00:00:00 2001 From: Maple Date: Wed, 25 Mar 2026 00:42:30 +0100 Subject: [PATCH 061/203] fix prudpv1 --- prudpv1/src/prudp/packet.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/prudpv1/src/prudp/packet.rs b/prudpv1/src/prudp/packet.rs index a4d87e9..5a27d33 100644 --- a/prudpv1/src/prudp/packet.rs +++ b/prudpv1/src/prudp/packet.rs @@ -17,6 +17,7 @@ use rnex_core::prudp::virtual_port::VirtualPort; use std::fmt::{Debug, Formatter}; use std::io; use std::io::{Cursor, Read, Seek, Write}; +use std::net::SocketAddr; use std::net::SocketAddrV4; use thiserror::Error; use v_byte_helpers::SwapEndian; @@ -281,7 +282,7 @@ impl PRUDPV1Packet { pub fn source_sockaddr(&self, socket_addr_v4: SocketAddrV4) -> PRUDPSockAddr { PRUDPSockAddr { - regular_socket_addr: socket_addr_v4, + regular_socket_addr: SocketAddr::V4(socket_addr_v4), virtual_port: self.header.source_port, } } From 55b39597979b89c017bb37beb85122d6336a846e Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 6 Apr 2026 13:35:55 +0000 Subject: [PATCH 062/203] Add NEX results and fix timers --- Cargo.lock | 372 +++++++++++++++++++++++- rnex-core/Cargo.toml | 4 +- rnex-core/src/nex/matchmake.rs | 32 +- rnex-core/src/nex/user.rs | 152 +++++++++- rnex-core/src/rmc/message.rs | 3 +- rnex-core/src/rmc/protocols/ranking.rs | 54 ++-- rnex-core/src/rmc/structures/qbuffer.rs | 3 +- rnex-core/src/rmc/structures/ranking.rs | 18 +- 8 files changed, 586 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b010331..d34993e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -162,6 +162,35 @@ dependencies = [ "inout", ] +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fc4bff745c9b4c7fb1e97b25d13153da2bc7796260141df62378998d070207f" +dependencies = [ + "cookie", + "document-features", + "idna", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + [[package]] name = "core-foundation" version = "0.10.1" @@ -232,12 +261,38 @@ dependencies = [ "subtle", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + [[package]] name = "dotenv" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "flate2" version = "1.1.5" @@ -254,6 +309,15 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + [[package]] name = "futures-core" version = "0.3.31" @@ -337,6 +401,12 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + [[package]] name = "hex" version = "0.4.3" @@ -393,6 +463,118 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "inout" version = "0.1.4" @@ -441,6 +623,18 @@ version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + [[package]] name = "lock_api" version = "0.4.13" @@ -605,6 +799,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -828,6 +1031,8 @@ dependencies = [ "paste", "rand 0.8.5", "rc4", + "serde", + "serde_json", "simplelog", "thiserror", "tokio", @@ -935,24 +1140,47 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", "syn 2.0.104", ] +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + [[package]] name = "sha1" version = "0.10.6" @@ -1018,6 +1246,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + [[package]] name = "subtle" version = "2.6.1" @@ -1046,6 +1280,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -1108,6 +1353,16 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tokio" version = "1.47.1" @@ -1209,11 +1464,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d39cb1dbab692d82a977c0392ffac19e188bd9186a9f32806f0aaa859d75585a" dependencies = [ "base64", + "cookie_store", "flate2", "log", "percent-encoding", "rustls", "rustls-pki-types", + "serde", + "serde_json", "ureq-proto", "utf-8", "webpki-roots", @@ -1231,12 +1489,29 @@ dependencies = [ "log", ] +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "utf-8" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "v-byte-helpers" version = "0.1.1" @@ -1505,6 +1780,35 @@ version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.8.26" @@ -1525,8 +1829,68 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "zerofrom" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index d44c000..ff2b7b3 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -25,7 +25,9 @@ paste = "1.0.15" typenum = "1.18.0" json = "0.12.4" anyhow = "1.0.100" -ureq = "3.1.4" +ureq = { version = "3.1.4", features = [ "json" ] } +serde = { version = "1.0.228", features = [ "derive" ] } +serde_json = "1.0.149" [dev-dependencies] # criterion = "0.7.0" diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 0a155fa..032fbad 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -247,27 +247,29 @@ impl ExtendedMatchmakeSession { param_3: self.connected_players.len() as _, }) .await; - } + } } for old_conns in &old_particip { let Some(old_conns) = old_conns.upgrade() else { continue; }; - - let older_pid = old_conns.pid; - - initiating_user - .remote - .process_notification_event(NotificationEvent { - pid_source: initiating_pid, - notif_type: 3001, - param_1: self.session.gathering.self_gid as PID, - param_2: older_pid, - str_param: join_msg.clone(), - param_3: self.connected_players.len() as _, - }) - .await; + if old_conns.pid != self.session.gathering.host_pid{ + continue; + } + for new_conn_pid in conns.iter().filter_map(Weak::upgrade).map(|c| c.pid){ + old_conns + .remote + .process_notification_event(NotificationEvent { + pid_source: initiating_pid, + notif_type: 3001, + param_1: self.session.gathering.self_gid as PID, + param_2: new_conn_pid, + str_param: join_msg.clone(), + param_3: self.connected_players.len() as _, + }) + .await; + } } } pub fn has_active_players(&self) -> bool { diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index d8450e9..2e63b98 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -5,10 +5,14 @@ use crate::nex::remote_console::RemoteConsole; use crate::rmc::protocols::matchmake::{ Matchmake, RawMatchmake, RawMatchmakeInfo, RemoteMatchmake, }; +use serde::{Serialize, Deserialize}; +use std::env; +use std::str::FromStr; use crate::rmc::protocols::nat_traversal::{ NatTraversal, RawNatTraversal, RawNatTraversalInfo, RemoteNatTraversal, RemoteNatTraversalConsole, }; +use rnex_core::kerberos::KerberosDateTime; use rnex_core::PID; use rnex_core::prudp::station_url::StationUrl; use rnex_core::prudp::station_url::UrlOptions::{ @@ -29,12 +33,15 @@ use rnex_core::rmc::structures::matchmake::{ }; use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; -use log::info; +use log::{info, error}; use macros::rmc_struct; +use rnex_core::rmc::structures::qbuffer::QBuffer; use rnex_core::prudp::socket_addr::PRUDPSockAddr; use rnex_core::rmc::response::ErrorCode::{Core_InvalidArgument, RendezVous_AccountExpired}; use rnex_core::rmc::structures::qresult::QResult; use std::sync::{Arc, Weak}; +use rnex_core::rmc::protocols::ranking::{CompetitionRankingScoreData, CompetitionRankingGetParam, CompetitionRankingScoreInfo}; +use rnex_core::rmc::structures::ranking::{UploadCompetitionData}; use tokio::sync::{Mutex, RwLock}; define_rmc_proto!( @@ -582,4 +589,145 @@ impl NatTraversal for User { } } -impl Ranking for User {} +#[derive(Serialize, Deserialize)] +pub struct CompetitionPostResults { + pub splatfest_id: u32, + pub score: u32, + pub team_id: u8, + pub team_win: u8, + pub user: PID, +} + +// Seperate function because I cannot give a fuck right now +fn fetch_team_votes(fest_id: u32) -> Result, ErrorCode> { + let endpoint_votes = env::var("RNEX_SPLATOON_RESULTS_VOTES_GET").map_err(|_| { + error!("RNEX_SPLATOON_RESULTS_VOTES_GET not set"); + ErrorCode::RendezVous_InvalidConfiguration + })?; + + let url_votes = format!("{}?splatfest_id={}", endpoint_votes, fest_id); + let mut response = ureq::get(&url_votes).call().map_err(|e| { + error!("GET for votes failed: {:?}", e); + ErrorCode::RendezVous_InvalidConfiguration + })?; + + let body = response.body_mut().read_to_string().map_err(|e| { + error!("failed to read votes body: {:?}", e); + ErrorCode::RendezVous_InvalidConfiguration + })?; + + let body = body.trim().trim_start_matches('[').trim_end_matches(']'); + let votes: Result, _> = body + .split(',') + .map(|s| u32::from_str(s.trim())) + .collect(); + + votes.map_err(|e| { + error!("failed to parse votes: {:?}", e); + ErrorCode::RendezVous_InvalidConfiguration + }) +} + +impl Ranking for User { + async fn competition_ranking_get_param( + &self, + param: CompetitionRankingGetParam, + ) -> Result, ErrorCode> { + let fest_id = param.festival_ids.get(0).copied().unwrap_or(0); + + let endpoint_results = env::var("RNEX_SPLATOON_RESULTS_GET") + .map_err(|_| { + error!("RNEX_SPLATOON_RESULTS_GET not set"); + ErrorCode::RendezVous_InvalidConfiguration + })?; + + let url_results = format!("{}?splatfest_id={}", endpoint_results, fest_id); + let response_results = ureq::get(&url_results).call(); + + let results: Vec = match response_results { + Ok(mut res) => res + .body_mut() + .read_json() + .map_err(|e| { + error!("failed to parse JSON: {:?}", e); + ErrorCode::RendezVous_InvalidConfiguration + })?, + Err(e) => { + error!("GET failed: {:?}", e); + return Err(ErrorCode::RendezVous_InvalidConfiguration); + } + }; + + let team_votes = fetch_team_votes(fest_id)?; + + let score_data: Vec = results + .iter() + .map(|r| CompetitionRankingScoreData { + unk: 1, + pid: r.user, + score: r.score, + modified: KerberosDateTime::now(), + unk2: 1, + appdata: QBuffer(vec![]), + }) + .collect(); + + let info = CompetitionRankingScoreInfo { + fest_id, + score_data, + unk: 0, + team_wins: results.iter().map(|r| r.team_win as u32).collect(), + team_votes, + }; + + Ok(vec![info]) + } + + async fn upload_competition_ranking_score(&self, param: UploadCompetitionData) -> Result { + info!("fest results for user {:?}:", self.pid); + info!("fest id: {:?}", param.splatfest_id); + info!("score: {:?}", param.score); + info!("team id: {:?}", param.team_id); + info!("did current team win: {:?}", param.team_win); + + let endpoint = match env::var("RNEX_SPLATOON_RESULTS_POST") { + Ok(url) => url, + Err(_) => { + error!("RNEX_SPLATOON_RESULTS_POST not set"); + return Ok(false); + } + }; + + let payload = CompetitionPostResults { + splatfest_id: param.splatfest_id, + score: param.score, + team_id: param.team_id, + team_win: param.team_win, + user: self.pid, + }; + + let json_body = match serde_json::to_string(&payload) { + Ok(j) => j, + Err(e) => { + error!("error making json_body: {:?}", e); + return Ok(false); + } + }; + + let response = ureq::post(&endpoint) + .header("Content-Type", "application/json") + .send(json_body); + + match response { + Ok(res) => { + info!("POST worked: {}", res.status()); + } + Err(e) => { + error!("POST borked: {:?}", e); + } + } + + Ok(true) + } +} + diff --git a/rnex-core/src/rmc/message.rs b/rnex-core/src/rmc/message.rs index cf951bf..4fcdfbe 100644 --- a/rnex-core/src/rmc/message.rs +++ b/rnex-core/src/rmc/message.rs @@ -42,7 +42,8 @@ impl RMCMessage{ error!("received incorrect rmc packet: expected size {} but found {}", size, header_size + rest_of_data.len()); } - + // println!("rmc packet: protoid: {}, method id: {}", protocol_id, method_id); + // println!("{}", hex::encode(&rest_of_data)); //stream. Ok(Self{ diff --git a/rnex-core/src/rmc/protocols/ranking.rs b/rnex-core/src/rmc/protocols/ranking.rs index 93dcb87..b9dba06 100644 --- a/rnex-core/src/rmc/protocols/ranking.rs +++ b/rnex-core/src/rmc/protocols/ranking.rs @@ -1,33 +1,51 @@ -use macros::{rmc_struct, rmc_proto, RmcSerialize}; +use macros::{rmc_struct, rmc_proto, RmcSerialize, method_id}; + +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::rmc::structures::qbuffer::QBuffer; + +use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::structures::ranking::UploadCompetitionData; #[derive(RmcSerialize, Debug, Default, Clone)] -struct ResultsRange{ - offset: u32, - size: u32 +#[rmc_struct(0)] +pub struct ResultsRange{ + pub offset: u32, + pub size: u32 } #[derive(RmcSerialize, Debug, Default, Clone)] #[rmc_struct(1)] -struct CompetitionRankingGetParam{ - unk: u32, - range: ResultsRange, - festival_ids: Vec, +pub struct CompetitionRankingGetParam { + pub unk: u32, + pub range: ResultsRange, + pub festival_ids: Vec, } #[derive(RmcSerialize, Debug, Default, Clone)] #[rmc_struct(0)] -struct CompetitionRankingScoreInfo{ - fest_id: u32, - score_data: Vec, - unk: u32, - team_wins: Vec, - team_votes: Vec +pub struct CompetitionRankingScoreInfo{ + pub fest_id: u32, + pub score_data: Vec, + pub unk: u32, + pub team_wins: Vec, + pub team_votes: Vec } - +#[derive(RmcSerialize, Debug, Clone)] +#[rmc_struct(0)] +pub struct CompetitionRankingScoreData{ + pub unk: u32, + pub pid: u32, + pub score: u32, + pub modified: KerberosDateTime, + pub unk2: u8, + pub appdata: QBuffer +} #[rmc_proto(112)] pub trait Ranking{ - //#[method_id(16)] - //async fn competition_ranking_get_param(&self, param: CompetitionRankingGetParam) -> Result,ErrorCode>; -} \ No newline at end of file + #[method_id(16)] + async fn competition_ranking_get_param(&self, param: CompetitionRankingGetParam) -> Result,ErrorCode>; + #[method_id(18)] + async fn upload_competition_ranking_score(&self, param: UploadCompetitionData) -> Result; +} diff --git a/rnex-core/src/rmc/structures/qbuffer.rs b/rnex-core/src/rmc/structures/qbuffer.rs index fb30e64..2f7b23a 100644 --- a/rnex-core/src/rmc/structures/qbuffer.rs +++ b/rnex-core/src/rmc/structures/qbuffer.rs @@ -3,8 +3,7 @@ use bytemuck::bytes_of; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::rmc::structures::{Result, RmcSerialize}; - -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct QBuffer(pub Vec); impl RmcSerialize for QBuffer{ diff --git a/rnex-core/src/rmc/structures/ranking.rs b/rnex-core/src/rmc/structures/ranking.rs index 778c5cf..773889d 100644 --- a/rnex-core/src/rmc/structures/ranking.rs +++ b/rnex-core/src/rmc/structures/ranking.rs @@ -4,15 +4,15 @@ use rnex_core::rmc::structures::qbuffer::QBuffer; #[derive(RmcSerialize, Debug)] #[rmc_struct(0)] -struct UploadCompetitionData { - winning_team: u32, - splatfest_id: u32, - unk_2: u32, - unk_3: u32, - team_id_1: u8, - team_id_2: u8, - unk_5: u32, - player_data: QBuffer, +pub struct UploadCompetitionData{ + pub unk_1/*?*/: u32, + pub splatfest_id: u32, + pub unk_2/*?*/: u32, + pub score: u32, + pub team_id: u8, + pub team_win: u8, + pub is_first_upload: bool, + pub appdata: QBuffer, } #[derive(Copy, Clone, Pod, Zeroable)] From 0ef484ffd255f4406edb4c2772dc86e3fd00aa2e Mon Sep 17 00:00:00 2001 From: Maple Date: Mon, 6 Apr 2026 16:42:08 +0200 Subject: [PATCH 063/203] fix friends --- Cargo.lock | 1 + proxy-common/Cargo.toml | 1 + proxy-common/src/lib.rs | 19 ++++++++--------- prudpv0/src/packet.rs | 1 + rnex-core/src/rnex_proxy_common.rs | 33 +++++++++++++++++++++++++++++- 5 files changed, 43 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b010331..f681663 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -647,6 +647,7 @@ dependencies = [ name = "proxy-common" version = "0.1.0" dependencies = [ + "hex", "log", "rnex-core", "thiserror", diff --git a/proxy-common/Cargo.toml b/proxy-common/Cargo.toml index 6ba9ba7..bd13ffa 100644 --- a/proxy-common/Cargo.toml +++ b/proxy-common/Cargo.toml @@ -8,3 +8,4 @@ thiserror = "2.0.12" rnex-core = { path = "../rnex-core", version = "0.1.1" } tokio = { version = "1.47.0", features = ["full"] } log = "0.4.25" +hex = "0.4.3" diff --git a/proxy-common/src/lib.rs b/proxy-common/src/lib.rs index 3bd902d..dc6ed11 100644 --- a/proxy-common/src/lib.rs +++ b/proxy-common/src/lib.rs @@ -187,17 +187,14 @@ pub async fn new_backend_connection( } }; - if let Err(e) = stream - .send_buffer( - &ConnectionInitData { - prudpsock_addr: addr, - pid: pid, - } - .to_data() - .unwrap(), - ) - .await - { + let data = ConnectionInitData { + prudpsock_addr: addr, + pid: pid, + } + .to_data() + .unwrap(); + + if let Err(e) = stream.send_buffer(&data).await { error!("unable to send establishment data to backend: {}", e); return None; }; diff --git a/prudpv0/src/packet.rs b/prudpv0/src/packet.rs index e94ab46..50bfe55 100644 --- a/prudpv0/src/packet.rs +++ b/prudpv0/src/packet.rs @@ -268,6 +268,7 @@ pub fn new_connect_packet( .checksummed_data() .expect("packet malformed in creation"), ); + info!("header: {:?}", packet.header()); packet.0 } diff --git a/rnex-core/src/rnex_proxy_common.rs b/rnex-core/src/rnex_proxy_common.rs index 7f2c363..d103e43 100644 --- a/rnex-core/src/rnex_proxy_common.rs +++ b/rnex-core/src/rnex_proxy_common.rs @@ -1,9 +1,40 @@ use crate::{PID, prudp::socket_addr::PRUDPSockAddr}; use macros::RmcSerialize; -#[derive(Debug, RmcSerialize)] +#[derive(Debug, RmcSerialize, PartialEq, Eq)] #[rmc_struct(0)] pub struct ConnectionInitData { pub prudpsock_addr: PRUDPSockAddr, pub pid: PID, } + +#[cfg(test)] +mod test { + use std::{ + io::Cursor, + net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4}, + }; + + use crate::{ + prudp::{socket_addr::PRUDPSockAddr, virtual_port::VirtualPort}, + rmc::structures::RmcSerialize, + rnex_proxy_common::ConnectionInitData, + }; + + #[test] + fn test() { + let data = ConnectionInitData { + prudpsock_addr: PRUDPSockAddr { + regular_socket_addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::BROADCAST, 19293)), + virtual_port: VirtualPort::new(10, 2), + }, + pid: 100, + }; + + let ser = data.to_data().unwrap(); + + let de = ConnectionInitData::deserialize(&mut Cursor::new(ser)).unwrap(); + + assert_eq!(data, de); + } +} From 5392e08ea239575c3c2c8c8c900a8c0372de09b9 Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 6 Apr 2026 22:09:38 +0200 Subject: [PATCH 064/203] Temporary debugging --- rnex-core/src/nex/user.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 2e63b98..f16e813 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -659,6 +659,12 @@ impl Ranking for User { }; let team_votes = fetch_team_votes(fest_id)?; + let mut wins = vec![0u32, 0u32]; + for r in &results { + if r.team_win == 1 && (r.team_id == 0 || r.team_id == 1) { + wins[r.team_id as usize] += 1; + } + } let score_data: Vec = results .iter() @@ -672,11 +678,16 @@ impl Ranking for User { }) .collect(); + println!("Fest id: {:?}", fest_id); + println!("Score data: {:?}", score_data); + println!("Wins: {:?}", wins); + println!("Votes: {:?}", team_votes); + let info = CompetitionRankingScoreInfo { fest_id, score_data, unk: 0, - team_wins: results.iter().map(|r| r.team_win as u32).collect(), + team_wins: wins, team_votes, }; From 26fc8cb077a6f648ffb943f7b59a4e6a1af6486f Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 6 Apr 2026 22:34:40 +0200 Subject: [PATCH 065/203] Remove debugging statements --- rnex-core/src/nex/user.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index f16e813..c86ae73 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -677,11 +677,6 @@ impl Ranking for User { appdata: QBuffer(vec![]), }) .collect(); - - println!("Fest id: {:?}", fest_id); - println!("Score data: {:?}", score_data); - println!("Wins: {:?}", wins); - println!("Votes: {:?}", team_votes); let info = CompetitionRankingScoreInfo { fest_id, From c5677e304da1f1d177cafd40b6e147e4605ed5e6 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 11 Apr 2026 16:36:57 +0200 Subject: [PATCH 066/203] add more debugging logs --- prudpv0/src/server.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 1305d81..ce6cd21 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -284,6 +284,9 @@ impl Server { }); let mut conns = self.connections.write().await; + if conns.contains_key(&addr) { + error!("client already connected but tried to connect again"); + } conns.insert(addr, conn.clone()); drop(conns); @@ -346,7 +349,8 @@ impl Server { ); while let Some((_, mut packet)) = { let ctr = conn.client_packet_counter; - conn.packet_queue.remove(&ctr) + let packet = conn.packet_queue.remove(&ctr); + packet } { info!("processing packet: {}", conn.client_packet_counter); let Some(payload) = packet.payload_mut() else { From 1c8352a23536eed274e144215d7343bcd0b0537b Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 11 Apr 2026 18:16:20 +0200 Subject: [PATCH 067/203] actually delete connection if someone disconnects --- prudpv0/src/server.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index ce6cd21..63fefe7 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -414,6 +414,10 @@ impl Server { ); drop(inner); + let mut conns = self.connections.write().await; + conns.remove(&addr); + drop(conns); + self.socket.send_to(&packet, addr.regular_socket_addr).await; self.socket.send_to(&packet, addr.regular_socket_addr).await; self.socket.send_to(&packet, addr.regular_socket_addr).await; From dd4015b2c4b49d196ea29d53bbaf5c96d681fd31 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 11 Apr 2026 20:02:10 +0200 Subject: [PATCH 068/203] tie connections to a session id + prudp socket address --- prudpv0/src/server.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 63fefe7..4921b3f 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -73,7 +73,7 @@ pub struct Server { param: ProxyStartupParam, socket: UdpSocket, crypto: C, - connections: RwLock>>>, + connections: RwLock>>>, } impl Server { @@ -167,8 +167,9 @@ impl Server { self.clone().send_data_packet(conn.clone(), &data).await; } } - async fn timeout_thread(self: Arc, conn: Arc>) { + async fn timeout_thread(self: Arc, conn: Weak>) { loop { + let Some(conn) = conn.upgrade() else { break }; sleep(Duration::from_secs(3)); let mut inner = conn.inner.lock().await; @@ -214,7 +215,7 @@ impl Server { drop(inner); let mut conns = self.connections.write().await; - conns.remove(&conn.addr); + conns.remove(&(conn.addr, conn.session_id)); drop(conns); break; } @@ -284,10 +285,10 @@ impl Server { }); let mut conns = self.connections.write().await; - if conns.contains_key(&addr) { + if conns.contains_key(&(addr, header.session_id)) { error!("client already connected but tried to connect again"); } - conns.insert(addr, conn.clone()); + conns.insert((addr, header.session_id), conn.clone()); drop(conns); spawn({ @@ -297,7 +298,7 @@ impl Server { }); spawn({ let this = self.clone(); - let conn = conn.clone(); + let conn = Arc::downgrade(&conn); this.timeout_thread(conn) }); @@ -325,7 +326,7 @@ impl Server { return; }; - let Some(res) = self.get_connection(addr).await else { + let Some(res) = self.get_connection((addr, header.session_id)).await else { warn!("data packet on inactive connection from: {:?}", addr); return; }; @@ -372,7 +373,7 @@ impl Server { info!("got ping"); let header = packet.header().unwrap(); - let Some(conn) = self.get_connection(addr).await else { + let Some(conn) = self.get_connection((addr, header.session_id)).await else { warn!("ping on inactive connection: {:?}", addr); return; }; @@ -398,7 +399,7 @@ impl Server { info!("got disconnect"); let header = packet.header().unwrap(); - let Some(conn) = self.get_connection(addr).await else { + let Some(conn) = self.get_connection((addr, header.session_id)).await else { warn!("ping on inactive connection: {:?}", addr); return; }; @@ -415,14 +416,17 @@ impl Server { drop(inner); let mut conns = self.connections.write().await; - conns.remove(&addr); + conns.remove(&(addr, header.session_id)); drop(conns); self.socket.send_to(&packet, addr.regular_socket_addr).await; self.socket.send_to(&packet, addr.regular_socket_addr).await; self.socket.send_to(&packet, addr.regular_socket_addr).await; } - async fn get_connection(&self, addr: PRUDPSockAddr) -> Option>> { + async fn get_connection( + &self, + addr: (PRUDPSockAddr, u8), + ) -> Option>> { let rd = self.connections.read().await; let res = rd.get(&addr).cloned(); drop(rd); @@ -444,7 +448,7 @@ impl Server { let addr = PRUDPSockAddr::new(SocketAddr::V4(addr), header.source); - if let Some(conn) = self.get_connection(addr).await { + if let Some(conn) = self.get_connection((addr, header.session_id)).await { let mut inner = conn.inner.lock().await; inner.last_action = Instant::now(); drop(inner); From b503363e5698cb547c8c3b90bd43f47336968d3c Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 11 Apr 2026 20:24:13 +0200 Subject: [PATCH 069/203] add check setting status --- rnex-core/src/nex/friends_handler.rs | 4 ++++ rnex-core/src/rmc/protocols/friends.rs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index be5d684..09e9c9d 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -143,6 +143,10 @@ impl Friends for FriendsUser { false, )) } + + async fn check_setting_status(&self) -> Result { + Ok(0xFF) + } } impl Secure for FriendsUser { diff --git a/rnex-core/src/rmc/protocols/friends.rs b/rnex-core/src/rmc/protocols/friends.rs index 775016e..07dcd1a 100644 --- a/rnex-core/src/rmc/protocols/friends.rs +++ b/rnex-core/src/rmc/protocols/friends.rs @@ -143,4 +143,6 @@ pub trait Friends { ), ErrorCode, >; + #[method_id(19)] + async fn check_setting_status(&self) -> Result; } From 8164317b1980259fb25d1ce9d7ded934201fd398 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 11 Apr 2026 21:59:37 +0200 Subject: [PATCH 070/203] fix friends connection --- prudpv0/src/server.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 4921b3f..34c7647 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -6,7 +6,6 @@ use std::{ Arc, LazyLock, Weak, atomic::{AtomicBool, AtomicU32}, }, - thread::sleep, time::Duration, }; @@ -30,7 +29,7 @@ use tokio::{ net::{TcpSocket, UdpSocket}, spawn, sync::{Mutex, RwLock}, - time::Instant, + time::{Instant, sleep}, }; use crate::{ @@ -170,7 +169,7 @@ impl Server { async fn timeout_thread(self: Arc, conn: Weak>) { loop { let Some(conn) = conn.upgrade() else { break }; - sleep(Duration::from_secs(3)); + sleep(Duration::from_secs(3)).await; let mut inner = conn.inner.lock().await; if (Instant::now() - inner.last_action).as_secs() > 5 { @@ -259,6 +258,7 @@ impl Server { }; let pid = ci.get_user_id(); + println!("user with pid {} is connecting", pid); let buf_conn = new_backend_connection(&self.param, addr, pid).await; let Some(buf_conn) = buf_conn else { error!("unable to connect to backend"); From 7dd6265eddff46be751098d2c4d1746ccf03420f Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 12 Apr 2026 17:10:07 +0200 Subject: [PATCH 071/203] fix guest login on backend --- rnex-core/src/executables/friends_backend.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rnex-core/src/executables/friends_backend.rs b/rnex-core/src/executables/friends_backend.rs index 7ea03b4..74983f7 100644 --- a/rnex-core/src/executables/friends_backend.rs +++ b/rnex-core/src/executables/friends_backend.rs @@ -56,9 +56,11 @@ pub async fn start_friends_backend() { }) }); } else { - Arc::new_cyclic(move |this| FriendsGuest { - fm, - addr: c.prudpsock_addr, + new_rmc_gateway_connection(stream.into(), move |r| { + Arc::new_cyclic(move |this| FriendsGuest { + fm, + addr: c.prudpsock_addr, + }) }); } } From 3c651e874c413650c129acfbef7c62ddc50c3344 Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 12 Apr 2026 18:05:52 +0200 Subject: [PATCH 072/203] start work on implementing account management for friends --- rnex-core/src/nex/friends_handler.rs | 20 ++++++++++++++++++- .../src/rmc/protocols/account_management.rs | 19 ++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 09e9c9d..36d08dc 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -2,6 +2,9 @@ use std::sync::{Arc, atomic::AtomicU32}; use log::info; use macros::rmc_struct; +use rnex_core::rmc::protocols::account_management::{ + AccountManagement, RawAccountManagement, RawAccountManagementInfo, RemoteAccountManagement, +}; use rnex_core::rmc::protocols::friends::{Friends, RawFriends, RawFriendsInfo, RemoteFriends}; use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; use rnex_core::{ @@ -32,7 +35,8 @@ define_rmc_proto!( ); define_rmc_proto!( proto FriendsGuest{ - Secure + Secure, + AccountManagement } ); #[rmc_struct(FriendsUser)] @@ -198,3 +202,17 @@ impl Secure for FriendsGuest { Err(ErrorCode::Core_NotImplemented) } } + +impl AccountManagement for FriendsGuest { + async fn nintendo_create_account( + &self, + principal_name: String, + key: String, + groups: u32, + email: String, + auth_data: Any, + ) -> Result<(PID, String), ErrorCode> { + println!("{}, {}, {}, {}", principal_name, key, groups, email); + Err(ErrorCode::Core_NotImplemented) + } +} diff --git a/rnex-core/src/rmc/protocols/account_management.rs b/rnex-core/src/rmc/protocols/account_management.rs index 541d1f6..64bd3bc 100644 --- a/rnex-core/src/rmc/protocols/account_management.rs +++ b/rnex-core/src/rmc/protocols/account_management.rs @@ -1,4 +1,19 @@ -use macros::rmc_proto; +use macros::{method_id, rmc_proto}; + +use rnex_core::{ + PID, + rmc::{response::ErrorCode, structures::any::Any}, +}; #[rmc_proto(25)] -pub trait AccountManagement {} +pub trait AccountManagement { + #[method_id(27)] + async fn nintendo_create_account( + &self, + principal_name: String, + key: String, + groups: u32, + email: String, + auth_data: Any, + ) -> Result<(PID, String), ErrorCode>; +} From 2fc2a0ac1ef954675ba6f42e40fa431dbaba582a Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 12 Apr 2026 18:56:08 +0200 Subject: [PATCH 073/203] implement nintendo_create_account --- rnex-core/src/grpc/account.rs | 36 +++++++++++++++++++ rnex-core/src/nex/friends_handler.rs | 30 ++++++++++++++++ .../src/rmc/protocols/account_management.rs | 13 ++++++- rnex-core/src/rmc/protocols/friends.rs | 6 ++-- 4 files changed, 81 insertions(+), 4 deletions(-) diff --git a/rnex-core/src/grpc/account.rs b/rnex-core/src/grpc/account.rs index 64be4e9..d6ad140 100644 --- a/rnex-core/src/grpc/account.rs +++ b/rnex-core/src/grpc/account.rs @@ -103,6 +103,42 @@ impl Client { Ok(val.as_bytes().try_into().map_err(|_| SomethingHappened)?) } + pub async fn get_pid_from_token(&mut self, token: String) -> Result { + let req = self + .do_request(object! { + "query": + r"query($token: String!){ + token(tokenData: $token){ + pid + } + }", + "variables": { + "token": token + } + }) + .await?; + // this breaks switch nex servers and should be fixed eventually + let Some(val) = req + .entries() + .find(|v| v.0 == "data") + .ok_or(SomethingHappened)? + .1 + .entries() + .find(|v| v.0 == "token") + .ok_or(SomethingHappened)? + .1 + .entries() + .find(|v| v.0 == "pid") + .ok_or(SomethingHappened)? + .1 + .as_u32() + else { + return Err(SomethingHappened); + }; + + Ok(val) + } + /*pub async fn get_user_data(&mut self , pid: u32) -> Result{ let req = Request::new(GetUserDataRequest{ pid diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 36d08dc..42e5c71 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -1,5 +1,8 @@ +use std::io::{Cursor, Write}; use std::sync::{Arc, atomic::AtomicU32}; +use bytemuck::bytes_of; +use hmac::Mac; use log::info; use macros::rmc_struct; use rnex_core::rmc::protocols::account_management::{ @@ -27,6 +30,9 @@ use rnex_core::rmc::protocols::friends::{GameKey, MiiV2, PrincipalBasicInfo}; use rnex_core::PID; +use crate::rmc::protocols::account_management::NintendoCreateAccountData; +use rnex_core::rmc::structures::RmcSerialize; + define_rmc_proto!( proto FriendsUser{ Secure, @@ -153,6 +159,8 @@ impl Friends for FriendsUser { } } +type HMacMd5 = hmac::Hmac; + impl Secure for FriendsUser { async fn register( &self, @@ -213,6 +221,28 @@ impl AccountManagement for FriendsGuest { auth_data: Any, ) -> Result<(PID, String), ErrorCode> { println!("{}, {}, {}, {}", principal_name, key, groups, email); + if auth_data.name == "NintendoCreateAccountData" { + let Ok(data) = + NintendoCreateAccountData::deserialize(&mut Cursor::new(&auth_data.data)) + else { + return Err(ErrorCode::Authentication_InvalidParam); + }; + + let pid = data.nna_info.principal_basic_info.pid; + info!("create account: {}", pid); + + let Ok(mut mac) = HMacMd5::new_from_slice(key.as_bytes()) else { + return Err(ErrorCode::Authentication_InvalidParam); + }; + + mac.write_all(bytes_of(&pid)) + .expect("failed to write to hmac???"); + let mac = mac.finalize().into_bytes(); + + let hex_str = hex::encode(mac); + + return Ok((pid, hex_str)); + } Err(ErrorCode::Core_NotImplemented) } } diff --git a/rnex-core/src/rmc/protocols/account_management.rs b/rnex-core/src/rmc/protocols/account_management.rs index 64bd3bc..8ef2d9e 100644 --- a/rnex-core/src/rmc/protocols/account_management.rs +++ b/rnex-core/src/rmc/protocols/account_management.rs @@ -1,10 +1,21 @@ -use macros::{method_id, rmc_proto}; +use macros::{RmcSerialize, method_id, rmc_proto}; use rnex_core::{ PID, rmc::{response::ErrorCode, structures::any::Any}, }; +use crate::{kerberos::KerberosDateTime, rmc::protocols::friends::NNAInfo}; + +#[derive(RmcSerialize, Debug, Clone)] +#[rmc_struct(0)] +pub struct NintendoCreateAccountData { + pub nna_info: NNAInfo, + pub nex_token: String, + pub birthday: KerberosDateTime, + pub unk: u64, +} + #[rmc_proto(25)] pub trait AccountManagement { #[method_id(27)] diff --git a/rnex-core/src/rmc/protocols/friends.rs b/rnex-core/src/rmc/protocols/friends.rs index 07dcd1a..3f6138f 100644 --- a/rnex-core/src/rmc/protocols/friends.rs +++ b/rnex-core/src/rmc/protocols/friends.rs @@ -2,7 +2,7 @@ use macros::{RmcSerialize, method_id, rmc_proto}; use rnex_core::{kerberos::KerberosDateTime, rmc::response::ErrorCode}; -#[derive(RmcSerialize)] +#[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] pub struct MiiV2 { pub name: String, @@ -12,7 +12,7 @@ pub struct MiiV2 { pub date_time: KerberosDateTime, } -#[derive(RmcSerialize)] +#[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] pub struct PrincipalBasicInfo { pub pid: u32, @@ -21,7 +21,7 @@ pub struct PrincipalBasicInfo { pub unk: u8, } -#[derive(RmcSerialize)] +#[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] pub struct NNAInfo { pub principal_basic_info: PrincipalBasicInfo, From 6d139075886665b270442bec7dc070bbeca9e660 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 12 Apr 2026 22:15:15 +0200 Subject: [PATCH 074/203] Dynamically define access key --- editions.yaml | 2 ++ proxy-common/src/lib.rs | 5 +++++ prudpv0/src/crypto/friends_common.rs | 2 +- prudpv1/src/executables/proxy_insecure.rs | 2 +- prudpv1/src/executables/proxy_secure.rs | 2 +- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/editions.yaml b/editions.yaml index 5458ec6..7a6869c 100644 --- a/editions.yaml +++ b/editions.yaml @@ -7,6 +7,7 @@ splatoon: RNEX_VIRTUAL_PORT_INSECURE: "1:10" RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 6000 + RNEX_ACCESS_KEY: "6f599f81" splatoon2: features: - v4-3-11 @@ -25,3 +26,4 @@ friends: RNEX_VIRTUAL_PORT_INSECURE: "1:10" RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 6000 + RNEX_ACCESS_KEY: "ridfebb9" diff --git a/proxy-common/src/lib.rs b/proxy-common/src/lib.rs index dc6ed11..9c18f2e 100644 --- a/proxy-common/src/lib.rs +++ b/proxy-common/src/lib.rs @@ -31,6 +31,11 @@ const RNEX_DEFAULT_PORT: u16 = match u16::from_str_radix(env!("RNEX_DEFAULT_PORT Err(_) => panic!("unable to get default port from env"), }; +const RNEX_ACCESS_KEY: u16 = match u16::from_str_radix(env!("RNEX_ACCESS_KEY"), 10) { + Ok(v) => v, + Err(_) => panic!("unable to get access key from env"), +}; + #[derive(Error, Debug)] pub enum Error { #[error("error getting environment variable \"{0}\": {1}")] diff --git a/prudpv0/src/crypto/friends_common.rs b/prudpv0/src/crypto/friends_common.rs index b11af1d..6ae6e42 100644 --- a/prudpv0/src/crypto/friends_common.rs +++ b/prudpv0/src/crypto/friends_common.rs @@ -1,5 +1,5 @@ use hmac::Hmac; use md5::Md5; -pub const ACCESS_KEY: &str = "ridfebb9"; +pub const ACCESS_KEY: &str = RNEX_ACCESS_KEY; pub type HmacMd5 = Hmac; diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index 975f837..4049566 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -43,7 +43,7 @@ pub async fn start() { .expect("unable to start router"); let mut socket_secure = router_secure - .add_socket(VirtualPort::new(1, 10), Unsecure("6f599f81")) + .add_socket(VirtualPort::new(1, 10), Unsecure(RNEX_ACCESS_KEY)) .await .expect("unable to add socket"); diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index 8446391..a16360e 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -30,7 +30,7 @@ pub async fn start() { let mut socket_secure = router_secure .add_socket( VirtualPort::new(1, 10), - Secure("6f599f81", SECURE_SERVER_ACCOUNT.clone()), + Secure(RNEX_ACCESS_KEY, SECURE_SERVER_ACCOUNT.clone()), ) .await .expect("unable to add socket"); From fc39e3295b249e53818876654f57a90f8650cc56 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 12 Apr 2026 22:33:02 +0200 Subject: [PATCH 075/203] Correctly evaluate access key --- proxy-common/src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/proxy-common/src/lib.rs b/proxy-common/src/lib.rs index 9c18f2e..75665a0 100644 --- a/proxy-common/src/lib.rs +++ b/proxy-common/src/lib.rs @@ -31,10 +31,7 @@ const RNEX_DEFAULT_PORT: u16 = match u16::from_str_radix(env!("RNEX_DEFAULT_PORT Err(_) => panic!("unable to get default port from env"), }; -const RNEX_ACCESS_KEY: u16 = match u16::from_str_radix(env!("RNEX_ACCESS_KEY"), 10) { - Ok(v) => v, - Err(_) => panic!("unable to get access key from env"), -}; +const RNEX_ACCESS_KEY: &'static str = env!("RNEX_ACCESS_KEY"); #[derive(Error, Debug)] pub enum Error { From c9c4a575b572bde91d454f1dceececd20db41250 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 12 Apr 2026 22:35:07 +0200 Subject: [PATCH 076/203] oops --- proxy-common/src/lib.rs | 2 +- prudpv0/src/crypto/friends_common.rs | 1 + prudpv1/src/executables/proxy_insecure.rs | 1 + prudpv1/src/executables/proxy_secure.rs | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/proxy-common/src/lib.rs b/proxy-common/src/lib.rs index 75665a0..5cc13b7 100644 --- a/proxy-common/src/lib.rs +++ b/proxy-common/src/lib.rs @@ -31,7 +31,7 @@ const RNEX_DEFAULT_PORT: u16 = match u16::from_str_radix(env!("RNEX_DEFAULT_PORT Err(_) => panic!("unable to get default port from env"), }; -const RNEX_ACCESS_KEY: &'static str = env!("RNEX_ACCESS_KEY"); +pub const RNEX_ACCESS_KEY: &'static str = env!("RNEX_ACCESS_KEY"); #[derive(Error, Debug)] pub enum Error { diff --git a/prudpv0/src/crypto/friends_common.rs b/prudpv0/src/crypto/friends_common.rs index 6ae6e42..a8f1629 100644 --- a/prudpv0/src/crypto/friends_common.rs +++ b/prudpv0/src/crypto/friends_common.rs @@ -1,5 +1,6 @@ use hmac::Hmac; use md5::Md5; +use proxy_common::RNEX_ACCESS_KEY; pub const ACCESS_KEY: &str = RNEX_ACCESS_KEY; pub type HmacMd5 = Hmac; diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index 4049566..06299d1 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -19,6 +19,7 @@ use std::time::Duration; use tokio::net::TcpStream; use tokio::task; use tokio::time::sleep; +use proxy_common::RNEX_ACCESS_KEY; pub async fn start() { /*let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER) diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index a16360e..6bf3434 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -21,6 +21,7 @@ use std::time::Duration; use tokio::net::TcpStream; use tokio::task; use tokio::time::sleep; +use proxy_common::RNEX_ACCESS_KEY; pub async fn start() { let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) From 2f4d42d3ed8970178eae62556a5f697351ea052b Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 12 Apr 2026 23:35:55 +0200 Subject: [PATCH 077/203] Start work on super mario maker --- editions.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/editions.yaml b/editions.yaml index 7a6869c..50e589a 100644 --- a/editions.yaml +++ b/editions.yaml @@ -27,3 +27,13 @@ friends: RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 6000 RNEX_ACCESS_KEY: "ridfebb9" +super-mario-maker: + features: + - prudpv1 + - v3-8-15 + settings: + AUTH_REPORT_VERSION: "branch:origin/project/wup-ama build:3_8_29_3022_0" + RNEX_VIRTUAL_PORT_INSECURE: "1:10" + RNEX_VIRTUAL_PORT_SECURE: "1:10" + RNEX_DEFAULT_PORT: 6000 + RNEX_ACCESS_KEY: "9f2b4678" \ No newline at end of file From 7e22acda5988e86ec2dd5805cdbb250b2495317f Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 13 Apr 2026 00:27:30 +0200 Subject: [PATCH 078/203] Basic test for SMM functionality --- rnex-core/src/nex/datastore.rs | 31 ++++++++++ rnex-core/src/nex/mod.rs | 1 + rnex-core/src/rmc/protocols/datastore.rs | 74 ++++++++++++++++++++++++ rnex-core/src/rmc/protocols/mod.rs | 1 + 4 files changed, 107 insertions(+) create mode 100644 rnex-core/src/nex/datastore.rs create mode 100644 rnex-core/src/rmc/protocols/datastore.rs diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs new file mode 100644 index 0000000..c24f75c --- /dev/null +++ b/rnex-core/src/nex/datastore.rs @@ -0,0 +1,31 @@ +use rnex_core::rmc::protocols::datastore::DataStore; +// use crate::define_rmc_proto; +// use macros::rmc_struct; +use rnex_core::prudp::socket_addr::PRUDPSockAddr; +use std::sync::{Weak}; +use rnex_core::PID; +use crate::nex::remote_console::RemoteConsole; +use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::protocols::datastore::{GetMetaInfo, GetMetaParam}; + +pub struct User { + pub pid: PID, + pub ip: PRUDPSockAddr, + pub this: Weak, + pub remote: RemoteConsole, +} + +impl DataStore for User { + async fn get_meta(&self, metaparam: GetMetaParam) -> Result { + // // bogus + // let info: GetMetaInfo = GetMetaInfo { + // dataid: 10, + // owner: 1121, + // size: 1024, + // name: "idk" + // } + + // just trying to see what methods it tries to use + Err(rnex_core::rmc::response::ErrorCode::DataStore_NotFound) + } +} \ No newline at end of file diff --git a/rnex-core/src/nex/mod.rs b/rnex-core/src/nex/mod.rs index 0f52c13..2f628cd 100644 --- a/rnex-core/src/nex/mod.rs +++ b/rnex-core/src/nex/mod.rs @@ -5,3 +5,4 @@ pub mod friends_handler; pub mod matchmake; pub mod remote_console; pub mod user; +pub mod datastore; \ No newline at end of file diff --git a/rnex-core/src/rmc/protocols/datastore.rs b/rnex-core/src/rmc/protocols/datastore.rs new file mode 100644 index 0000000..796281d --- /dev/null +++ b/rnex-core/src/rmc/protocols/datastore.rs @@ -0,0 +1,74 @@ +use macros::{method_id, rmc_proto, RmcSerialize, rmc_struct}; +use crate::rmc::response::ErrorCode; +use rnex_core::rmc::structures::qbuffer::QBuffer; + +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::PID; + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct PersistenceTarget { + pub owner: PID, + pub persistence_slot_id: u16, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct Permission { + pub permission: u8, + pub recipient_ids: Vec, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct RatingInfoWithSlot { + pub slot: i8, + pub rating: RatingInfo, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct RatingInfo { + pub total_value: i64, + pub count: u32, + pub initial_value: i64, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct GetMetaParam { + pub dataid: u64, + pub persistence_target: PersistenceTarget, + pub result_option: u8, + pub access_password: u64, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct GetMetaInfo { + pub dataid: u64, + pub owner: PID, + pub size: u32, + pub name: &'static str, + pub data_type: u16, + pub meta_binary: QBuffer, + pub permission: Permission, + pub del_permission: Permission, + pub created_time: KerberosDateTime, + pub updated_time: KerberosDateTime, + pub period: u16, + pub status: u8, + pub reffered_count: u32, + pub refer_dat_id: u32, + pub flag: u32, + pub referred_time: KerberosDateTime, + pub expire_time: KerberosDateTime, + pub tags: Vec<&'static str>, + pub ratings: Vec, +} + +#[rmc_proto(115)] +pub trait DataStore{ + #[method_id(8)] + async fn get_meta(&self, metaparam: GetMetaParam) -> Result; +} \ No newline at end of file diff --git a/rnex-core/src/rmc/protocols/mod.rs b/rnex-core/src/rmc/protocols/mod.rs index 8feb2f3..e3f1364 100644 --- a/rnex-core/src/rmc/protocols/mod.rs +++ b/rnex-core/src/rmc/protocols/mod.rs @@ -10,6 +10,7 @@ pub mod nat_traversal; pub mod notifications; pub mod ranking; pub mod secure; +pub mod datastore; use crate::result::ResultExtension; use crate::rmc::message::RMCMessage; From 35ac0e9f4649cb61a039e3a20e576f0140976fe4 Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 13 Apr 2026 00:30:10 +0200 Subject: [PATCH 079/203] Compiler pissing me off --- rnex-core/src/nex/datastore.rs | 4 ++-- rnex-core/src/rmc/protocols/datastore.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index c24f75c..a3b55c8 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -16,7 +16,7 @@ pub struct User { } impl DataStore for User { - async fn get_meta(&self, metaparam: GetMetaParam) -> Result { + async fn get_meta(&self, metaparam: GetMetaParam) -> Result { // // bogus // let info: GetMetaInfo = GetMetaInfo { // dataid: 10, @@ -26,6 +26,6 @@ impl DataStore for User { // } // just trying to see what methods it tries to use - Err(rnex_core::rmc::response::ErrorCode::DataStore_NotFound) + Err(ErrorCode::DataStore_NotFound) } } \ No newline at end of file diff --git a/rnex-core/src/rmc/protocols/datastore.rs b/rnex-core/src/rmc/protocols/datastore.rs index 796281d..d1eb4ff 100644 --- a/rnex-core/src/rmc/protocols/datastore.rs +++ b/rnex-core/src/rmc/protocols/datastore.rs @@ -1,5 +1,5 @@ use macros::{method_id, rmc_proto, RmcSerialize, rmc_struct}; -use crate::rmc::response::ErrorCode; +use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::qbuffer::QBuffer; use rnex_core::kerberos::KerberosDateTime; @@ -70,5 +70,5 @@ pub struct GetMetaInfo { #[rmc_proto(115)] pub trait DataStore{ #[method_id(8)] - async fn get_meta(&self, metaparam: GetMetaParam) -> Result; + async fn get_meta(&self, metaparam: GetMetaParam) -> Result; } \ No newline at end of file From 535e448541b7cc29d286ccee8915d36cf1e32b9c Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 13 Apr 2026 00:36:12 +0200 Subject: [PATCH 080/203] long sigh --- rnex-core/src/nex/datastore.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index a3b55c8..83b7cce 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -1,5 +1,5 @@ use rnex_core::rmc::protocols::datastore::DataStore; -// use crate::define_rmc_proto; +use crate::define_rmc_proto; // use macros::rmc_struct; use rnex_core::prudp::socket_addr::PRUDPSockAddr; use std::sync::{Weak}; @@ -8,14 +8,20 @@ use crate::nex::remote_console::RemoteConsole; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::protocols::datastore::{GetMetaInfo, GetMetaParam}; -pub struct User { +define_rmc_proto!( + proto DataStoreUser { + DataStore + } +); + +pub struct DataStoreUser { pub pid: PID, pub ip: PRUDPSockAddr, - pub this: Weak, + pub this: Weak, pub remote: RemoteConsole, } -impl DataStore for User { +impl DataStore for DataStoreUser { async fn get_meta(&self, metaparam: GetMetaParam) -> Result { // // bogus // let info: GetMetaInfo = GetMetaInfo { From f020ed86341a44373b5a1714715af05ebd1bbfb3 Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 13 Apr 2026 00:38:38 +0200 Subject: [PATCH 081/203] ACTUALLY define the protocol Maple, why --- rnex-core/src/nex/datastore.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index 83b7cce..e6b532e 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -1,12 +1,12 @@ -use rnex_core::rmc::protocols::datastore::DataStore; use crate::define_rmc_proto; -// use macros::rmc_struct; +use macros::rmc_struct; use rnex_core::prudp::socket_addr::PRUDPSockAddr; use std::sync::{Weak}; use rnex_core::PID; -use crate::nex::remote_console::RemoteConsole; +use rnex_core::nex::remote_console::RemoteConsole; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::protocols::datastore::{GetMetaInfo, GetMetaParam}; +use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore}; define_rmc_proto!( proto DataStoreUser { @@ -14,6 +14,7 @@ define_rmc_proto!( } ); +#[rmc_struct(DataStoreUser)] pub struct DataStoreUser { pub pid: PID, pub ip: PRUDPSockAddr, From 3a4eb78d2c3f042de0f9be84fc7a16da126137cc Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 13 Apr 2026 10:43:51 +0200 Subject: [PATCH 082/203] ACTUALLY define the protocol thanks maple for helping out --- rnex-core/src/nex/datastore.rs | 18 +++--------------- rnex-core/src/nex/user.rs | 4 +++- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index e6b532e..30a6ff7 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -5,24 +5,12 @@ use std::sync::{Weak}; use rnex_core::PID; use rnex_core::nex::remote_console::RemoteConsole; use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::protocols::secure::{Secure, RawSecure, RawSecureInfo, RemoteSecure}; use rnex_core::rmc::protocols::datastore::{GetMetaInfo, GetMetaParam}; use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore}; +use crate::nex::user::User; -define_rmc_proto!( - proto DataStoreUser { - DataStore - } -); - -#[rmc_struct(DataStoreUser)] -pub struct DataStoreUser { - pub pid: PID, - pub ip: PRUDPSockAddr, - pub this: Weak, - pub remote: RemoteConsole, -} - -impl DataStore for DataStoreUser { +impl DataStore for User { async fn get_meta(&self, metaparam: GetMetaParam) -> Result { // // bogus // let info: GetMetaInfo = GetMetaInfo { diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index c86ae73..f271355 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -26,6 +26,7 @@ use rnex_core::rmc::protocols::matchmake_extension::{ }; use rnex_core::rmc::protocols::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking}; use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; +use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore}; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::any::Any; use rnex_core::rmc::structures::matchmake::{ @@ -51,7 +52,8 @@ define_rmc_proto!( MatchmakeExt, Matchmake, NatTraversal, - Ranking + Ranking, + DataStore } ); From 0fe0b754a152812525fb21a5a19849fecf8afc94 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 14 Apr 2026 09:00:49 +0200 Subject: [PATCH 083/203] More work on datastore --- Cargo.lock | 1973 +++++++++++++++++++++- build-edition.sh | 3 +- editions.yaml | 3 +- rnex-core/Cargo.toml | 7 +- rnex-core/src/nex/datastore.rs | 48 +- rnex-core/src/nex/mod.rs | 3 +- rnex-core/src/nex/s3presigner.rs | 72 + rnex-core/src/rmc/protocols/datastore.rs | 94 +- 8 files changed, 2097 insertions(+), 106 deletions(-) create mode 100644 rnex-core/src/nex/s3presigner.rs diff --git a/Cargo.lock b/Cargo.lock index ce7b5e9..3e1d57d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,21 +2,18 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -49,6 +46,21 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.5.0" @@ -56,31 +68,483 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] -name = "backtrace" -version = "0.3.75" +name = "aws-config" +version = "1.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "11493b0bad143270fb8ad284a096dd529ba91924c5409adeac856cc1bf047dbc" dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", + "aws-credential-types", + "aws-runtime", + "aws-sdk-sso", + "aws-sdk-ssooidc", + "aws-sdk-sts", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "hex", + "http 1.3.1", + "sha1", + "time", + "tokio", + "tracing", + "url", + "zeroize", ] +[[package]] +name = "aws-credential-types" +version = "1.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f20799b373a1be121fe3005fba0c2090af9411573878f224df44b42727fcaf7" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "zeroize", +] + +[[package]] +name = "aws-lc-rs" +version = "1.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.39.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + +[[package]] +name = "aws-runtime" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc0651c57e384202e47153c1260b84a9936e19803d747615edf199dc3b98d17" +dependencies = [ + "aws-credential-types", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "bytes-utils", + "fastrand", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "http-body 1.0.1", + "percent-encoding", + "pin-project-lite", + "tracing", + "uuid", +] + +[[package]] +name = "aws-sdk-s3" +version = "1.129.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d4e8410fadbc0ee453145dd77a4958227b18b05bf67c2795d0a8b8596c9aa0f" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-checksums", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "bytes", + "fastrand", + "hex", + "hmac", + "http 0.2.12", + "http 1.3.1", + "http-body 1.0.1", + "lru", + "percent-encoding", + "regex-lite", + "sha2", + "tracing", + "url", +] + +[[package]] +name = "aws-sdk-sso" +version = "1.97.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aadc669e184501caaa6beafb28c6267fc1baef0810fb58f9b205485ca3f2567" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.3.1", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-ssooidc" +version = "1.99.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1342a7db8f358d3de0aed2007a0b54e875458e39848d54cc1d46700b2bfcb0a8" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.3.1", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-sts" +version = "1.101.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab41ad64e4051ecabeea802d6a17845a91e83287e1dd249e6963ea1ba78c428a" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-query", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "fastrand", + "http 0.2.12", + "http 1.3.1", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sigv4" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0b660013a6683ab23797778e21f1f854744fdf05f68204b4cca4c8c04b5d1f4" +dependencies = [ + "aws-credential-types", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "crypto-bigint 0.5.5", + "form_urlencoded", + "hex", + "hmac", + "http 0.2.12", + "http 1.3.1", + "p256", + "percent-encoding", + "ring", + "sha2", + "subtle", + "time", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-async" +version = "1.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffcaf626bdda484571968400c326a244598634dc75fd451325a54ad1a59acfc" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "aws-smithy-checksums" +version = "0.64.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6750f3dd509b0694a4377f0293ed2f9630d710b1cebe281fa8bac8f099f88bc6" +dependencies = [ + "aws-smithy-http", + "aws-smithy-types", + "bytes", + "crc-fast", + "hex", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "md-5", + "pin-project-lite", + "sha1", + "sha2", + "tracing", +] + +[[package]] +name = "aws-smithy-eventstream" +version = "0.60.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf09d74e5e32f76b8762da505a3cd59303e367a664ca67295387baa8c1d7548" +dependencies = [ + "aws-smithy-types", + "bytes", + "crc32fast", +] + +[[package]] +name = "aws-smithy-http" +version = "0.63.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1ab2dc1c2c3749ead27180d333c42f11be8b0e934058fb4b2258ee8dbe5231" +dependencies = [ + "aws-smithy-eventstream", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "bytes-utils", + "futures-core", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "percent-encoding", + "pin-project-lite", + "pin-utils", + "tracing", +] + +[[package]] +name = "aws-smithy-http-client" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a2f165a7feee6f263028b899d0a181987f4fa7179a6411a32a439fba7c5f769" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "h2 0.3.27", + "h2 0.4.13", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper 1.9.0", + "hyper-rustls 0.24.2", + "hyper-rustls 0.27.8", + "hyper-util", + "pin-project-lite", + "rustls 0.21.12", + "rustls 0.23.31", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.4", + "tower", + "tracing", +] + +[[package]] +name = "aws-smithy-json" +version = "0.62.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9648b0bb82a2eedd844052c6ad2a1a822d1f8e3adee5fbf668366717e428856a" +dependencies = [ + "aws-smithy-types", +] + +[[package]] +name = "aws-smithy-observability" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06c2315d173edbf1920da8ba3a7189695827002e4c0fc961973ab1c54abca9c" +dependencies = [ + "aws-smithy-runtime-api", +] + +[[package]] +name = "aws-smithy-query" +version = "0.60.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a56d79744fb3edb5d722ef79d86081e121d3b9422cb209eb03aea6aa4f21ebd" +dependencies = [ + "aws-smithy-types", + "urlencoding", +] + +[[package]] +name = "aws-smithy-runtime" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028999056d2d2fd58a697232f9eec4a643cf73a71cf327690a7edad1d2af2110" +dependencies = [ + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-http-client", + "aws-smithy-observability", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "pin-project-lite", + "pin-utils", + "tokio", + "tracing", +] + +[[package]] +name = "aws-smithy-runtime-api" +version = "1.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876ab3c9c29791ba4ba02b780a3049e21ec63dabda09268b175272c3733a79e6" +dependencies = [ + "aws-smithy-async", + "aws-smithy-types", + "bytes", + "http 0.2.12", + "http 1.3.1", + "pin-project-lite", + "tokio", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-types" +version = "1.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d73dbfbaa8e4bc57b9045137680b958d274823509a360abfd8e1d514d40c95c" +dependencies = [ + "base64-simd", + "bytes", + "bytes-utils", + "futures-core", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "itoa", + "num-integer", + "pin-project-lite", + "pin-utils", + "ryu", + "serde", + "time", + "tokio", + "tokio-util", +] + +[[package]] +name = "aws-smithy-xml" +version = "0.60.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce02add1aa3677d022f8adf81dcbe3046a95f17a1b1e8979c145cd21d3d22b3" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "aws-types" +version = "1.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47c8323699dd9b3c8d5b3c13051ae9cdef58fd179957c882f8374dd8725962d9" +dependencies = [ + "aws-credential-types", + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "rustc_version", + "tracing", +] + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + [[package]] name = "bitflags" version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -118,17 +582,36 @@ dependencies = [ ] [[package]] -name = "bytes" -version = "1.10.1" +name = "byteorder" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "bytes-utils" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" +dependencies = [ + "bytes", + "either", +] [[package]] name = "cc" -version = "1.2.31" +version = "1.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" +checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -162,6 +645,30 @@ dependencies = [ "inout", ] +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "cookie" version = "0.18.1" @@ -216,6 +723,33 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc-fast" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd92aca2c6001b1bf5ba0ff84ee74ec8501b52bbef0cac80bf25a6c1d87a83d" +dependencies = [ + "crc", + "digest", + "rustversion", + "spin 0.10.0", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -225,6 +759,43 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -241,6 +812,27 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.4.0" @@ -257,6 +849,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -287,12 +880,109 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve", + "rfc6979", + "signature 1.6.4", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest", + "ff", + "generic-array", + "group", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "flate2" version = "1.1.5" @@ -303,12 +993,35 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + [[package]] name = "fnv" 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 = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "form_urlencoded" version = "1.2.2" @@ -318,12 +1031,56 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + [[package]] name = "futures-core" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + [[package]] name = "futures-macro" version = "0.3.31" @@ -354,9 +1111,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", + "futures-io", "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -396,16 +1155,90 @@ dependencies = [ ] [[package]] -name = "gimli" -version = "0.31.1" +name = "group" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.3.1", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.1.5", +] [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hex" @@ -413,6 +1246,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -422,6 +1264,26 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.3.1" @@ -433,12 +1295,151 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.3.1", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2 0.4.13", + "http 1.3.1", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.32", + "log", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2b52f86d1d4bc0d6b4e6826d960b1b333217e07d36b882dca570a5e1c48895b" +dependencies = [ + "http 1.3.1", + "hyper 1.9.0", + "hyper-util", + "rustls 0.23.31", + "rustls-native-certs", + "tokio", + "tokio-rustls 0.26.4", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "hyper 1.9.0", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.3", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.63" @@ -572,7 +1573,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", ] [[package]] @@ -585,21 +1586,26 @@ dependencies = [ ] [[package]] -name = "io-uring" -version = "0.7.9" +name = "ipnet" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] [[package]] name = "js-sys" @@ -618,10 +1624,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" [[package]] -name = "libc" -version = "0.2.174" +name = "lazy_static" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin 0.9.8", +] + +[[package]] +name = "libc" +version = "0.2.185" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libredox" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +dependencies = [ + "bitflags", + "libc", + "plain", + "redox_syscall 0.7.4", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "pkg-config", + "vcpkg", +] [[package]] name = "litemap" @@ -651,6 +1694,15 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "lru" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" +dependencies = [ + "hashbrown 0.16.1", +] + [[package]] name = "macros" version = "0.0.0" @@ -698,13 +1750,29 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.4" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "wasi", - "windows-sys 0.59.0", + "windows-sys 0.61.2", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", ] [[package]] @@ -713,6 +1781,26 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -720,6 +1808,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -731,15 +1820,6 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.21.3" @@ -752,6 +1832,29 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" +[[package]] +name = "outref" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" + +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "ecdsa", + "elliptic-curve", + "sha2", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.4" @@ -770,9 +1873,9 @@ checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.17", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -781,6 +1884,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -799,6 +1911,49 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der 0.7.10", + "pkcs8 0.10.2", + "spki 0.7.3", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.10", + "spki 0.7.3", +] + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "potential_utf" version = "0.1.4" @@ -999,6 +2154,32 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex-lite" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + [[package]] name = "ring" version = "0.17.14" @@ -1018,6 +2199,9 @@ name = "rnex-core" version = "0.1.1" dependencies = [ "anyhow", + "aws-config", + "aws-sdk-s3", + "base64", "bytemuck", "cfg-if", "chrono", @@ -1034,7 +2218,9 @@ dependencies = [ "rc4", "serde", "serde_json", + "sha2", "simplelog", + "sqlx", "thiserror", "tokio", "typenum", @@ -1043,10 +2229,45 @@ dependencies = [ ] [[package]] -name = "rustc-demangle" -version = "0.1.26" +name = "rsa" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "signature 2.2.0", + "spki 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] [[package]] name = "rustls" @@ -1054,11 +2275,12 @@ version = "0.23.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ + "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.103.4", "subtle", "zeroize", ] @@ -1084,12 +2306,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustls-webpki" version = "0.103.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -1101,6 +2334,12 @@ version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + [[package]] name = "schannel" version = "0.1.28" @@ -1116,6 +2355,30 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + [[package]] name = "security-framework" version = "3.5.1" @@ -1139,6 +2402,12 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + [[package]] name = "serde" version = "1.0.228" @@ -1182,6 +2451,18 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha1" version = "0.10.6" @@ -1193,6 +2474,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1208,6 +2500,26 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -1236,15 +2548,248 @@ name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] [[package]] name = "socket2" -version = "0.6.0" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.10", +] + +[[package]] +name = "sqlx" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" +dependencies = [ + "base64", + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.15.5", + "hashlink", + "indexmap", + "log", + "memchr", + "once_cell", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "thiserror", + "tracing", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.104", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 2.0.104", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" +dependencies = [ + "atoi", + "base64", + "bitflags", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" +dependencies = [ + "atoi", + "base64", + "bitflags", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "thiserror", + "tracing", + "url", ] [[package]] @@ -1253,6 +2798,17 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + [[package]] name = "subtle" version = "2.6.1" @@ -1365,43 +2921,65 @@ dependencies = [ ] [[package]] -name = "tokio" -version = "1.47.1" +name = "tinyvec" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", - "socket2", + "socket2 0.6.3", "tokio-macros", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", "syn 2.0.104", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls", + "rustls 0.23.31", "tokio", ] @@ -1413,14 +2991,87 @@ checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" dependencies = [ "futures-util", "log", - "rustls", + "rustls 0.23.31", "rustls-native-certs", "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.4", "tungstenite", ] +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "tungstenite" version = "0.28.0" @@ -1429,11 +3080,11 @@ checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ "bytes", "data-encoding", - "http", + "http 1.3.1", "httparse", "log", "rand 0.9.2", - "rustls", + "rustls 0.23.31", "rustls-pki-types", "sha1", "thiserror", @@ -1446,12 +3097,33 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" + [[package]] name = "untrusted" version = "0.9.0" @@ -1469,7 +3141,7 @@ dependencies = [ "flate2", "log", "percent-encoding", - "rustls", + "rustls 0.23.31", "rustls-pki-types", "serde", "serde_json", @@ -1485,7 +3157,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2" dependencies = [ "base64", - "http", + "http 1.3.1", "httparse", "log", ] @@ -1501,6 +3173,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" @@ -1513,6 +3191,16 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "uuid" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "v-byte-helpers" version = "0.1.1" @@ -1522,12 +3210,33 @@ dependencies = [ "macros 0.1.1", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -1543,6 +3252,12 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -1610,6 +3325,16 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "whoami" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +dependencies = [ + "libredox", + "wasite", +] + [[package]] name = "winapi-util" version = "0.1.9" @@ -1684,13 +3409,22 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -1699,7 +3433,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -1711,34 +3445,67 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "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]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1751,24 +3518,48 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -1787,6 +3578,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + [[package]] name = "yoke" version = "0.8.1" diff --git a/build-edition.sh b/build-edition.sh index 5d65fc3..ede64d3 100755 --- a/build-edition.sh +++ b/build-edition.sh @@ -10,4 +10,5 @@ echo $EDITION_FEATURES echo ENV SETTINGS: env -OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl +#OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl +OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 cargo build --release --features "$EDITION_FEATURES" diff --git a/editions.yaml b/editions.yaml index 50e589a..40c2e10 100644 --- a/editions.yaml +++ b/editions.yaml @@ -31,9 +31,10 @@ super-mario-maker: features: - prudpv1 - v3-8-15 + - datastore settings: AUTH_REPORT_VERSION: "branch:origin/project/wup-ama build:3_8_29_3022_0" RNEX_VIRTUAL_PORT_INSECURE: "1:10" RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 6000 - RNEX_ACCESS_KEY: "9f2b4678" \ No newline at end of file + RNEX_ACCESS_KEY: "9f2b4678" diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index ff2b7b3..07e5dd8 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -28,6 +28,11 @@ anyhow = "1.0.100" ureq = { version = "3.1.4", features = [ "json" ] } serde = { version = "1.0.228", features = [ "derive" ] } serde_json = "1.0.149" +sqlx = { version = "0.8.6", optional = true } +aws-sdk-s3 = { version = "1.129.0", optional = true } +aws-config = { version = "1.8.15", optional = true } +base64 = "0.22.1" +sha2 = "0.10.9" [dev-dependencies] # criterion = "0.7.0" @@ -40,7 +45,7 @@ big_pid = [] v3-8-15 = ["rmc_struct_header"] v4-3-11 = ["v3-8-15"] nx = ["big_pid"] - +datastore = ["dep:sqlx", "v3-8-15", "dep:aws-sdk-s3", "dep:aws-config"] [[bench]] name = "rmc_serialization" diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index 30a6ff7..9299906 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -4,23 +4,53 @@ use rnex_core::prudp::socket_addr::PRUDPSockAddr; use std::sync::{Weak}; use rnex_core::PID; use rnex_core::nex::remote_console::RemoteConsole; +use rnex_core::nex::s3presigner::S3Presigner; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::protocols::secure::{Secure, RawSecure, RawSecureInfo, RemoteSecure}; -use rnex_core::rmc::protocols::datastore::{GetMetaInfo, GetMetaParam}; -use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore}; +use rnex_core::rmc::protocols::datastore::{CompletePostParam, GetMetaInfo, GetMetaParam, KeyValue, RateCustomRankingParam}; +use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore, PreparePostParam, ReqPostInfo}; use crate::nex::user::User; impl DataStore for User { async fn get_meta(&self, metaparam: GetMetaParam) -> Result { - // // bogus - // let info: GetMetaInfo = GetMetaInfo { - // dataid: 10, - // owner: 1121, - // size: 1024, - // name: "idk" - // } + println!("dataid: {}", metaparam.dataid); + println!("access password: {}", metaparam.access_password); // just trying to see what methods it tries to use Err(ErrorCode::DataStore_NotFound) } + + async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result { + let data_id: u64 = 9400001; + let presigner = S3Presigner::new("https://s3.perditum.com", "miku".into()).await; + + let key = format!("data/{}.bin", data_id); + + let (upload_url, fields) = presigner.generate_presigned_post(&key).await; + + let form_fields = fields.into_iter().map(|(k, v)| { + KeyValue { key: k, value: v } + }).collect(); + + Ok(ReqPostInfo { + dataid: data_id, + url: upload_url, + request_headers: vec![], + form_fields, + root_ca_cert: vec![], + }) + } + + async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode> { + // whatever + println!("dataid: {}", completeparam.dataid); + println!("succeeded?: {}", completeparam.success); + + Ok(()) + } + + async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode> { + // this returns nothing + Ok(()) + } } \ No newline at end of file diff --git a/rnex-core/src/nex/mod.rs b/rnex-core/src/nex/mod.rs index 2f628cd..91bb866 100644 --- a/rnex-core/src/nex/mod.rs +++ b/rnex-core/src/nex/mod.rs @@ -5,4 +5,5 @@ pub mod friends_handler; pub mod matchmake; pub mod remote_console; pub mod user; -pub mod datastore; \ No newline at end of file +pub mod datastore; +pub mod s3presigner; \ No newline at end of file diff --git a/rnex-core/src/nex/s3presigner.rs b/rnex-core/src/nex/s3presigner.rs new file mode 100644 index 0000000..c348c9d --- /dev/null +++ b/rnex-core/src/nex/s3presigner.rs @@ -0,0 +1,72 @@ +use aws_sdk_s3::presigning::PresigningConfig; +use base64::{engine::general_purpose, Engine as _}; +use hmac::{Hmac, Mac}; +use sha2::{Sha256, Digest}; +use chrono::{Utc, Duration}; +use serde_json::json; + +pub struct S3Presigner { + endpoint: String, + bucket: String, +} + +impl S3Presigner { + pub async fn new(endpoint: &str, bucket: String) -> Self { + Self { + endpoint: endpoint.trim_end_matches('/').to_string(), + bucket, + } + } + pub async fn generate_presigned_post(&self, key: &str) -> (String, Vec<(String, String)>) { + let access_key = std::env::var("AWS_ACCESS_KEY_ID").expect("Missing Access Key"); + let secret_key = std::env::var("AWS_SECRET_ACCESS_KEY").expect("Missing Secret Key"); + let region = "us-east-1"; + let date_short = Utc::now().format("%Y%m%d").to_string(); + let date_full = Utc::now().format("%Y%m%dT%H%M%SZ").to_string(); + let expiration = (Utc::now() + Duration::minutes(15)).format("%Y-%m-%dT%H:%M:%SZ").to_string(); + + let credential = format!("{}/{}/{}/s3/aws4_request", access_key, date_short, region); + + let policy_json = json!({ + "expiration": expiration, + "conditions": [ + {"bucket": self.bucket}, + ["starts-with", "$key", key], + {"x-amz-credential": credential}, + {"x-amz-algorithm": "AWS4-HMAC-SHA256"}, + {"x-amz-date": date_full} + ] + }); + + let policy_base64 = general_purpose::STANDARD.encode(policy_json.to_string()); + + let signature = self.calculate_signature(&secret_key, &date_short, region, &policy_base64); + + let mut fields = vec![ + ("key".to_string(), key.to_string()), + ("X-Amz-Algorithm".to_string(), "AWS4-HMAC-SHA256".to_string()), + ("X-Amz-Credential".to_string(), credential), + ("X-Amz-Date".to_string(), date_full), + ("Policy".to_string(), policy_base64), + ("X-Amz-Signature".to_string(), signature), + ]; + + let url = format!("https://s3.perditum.com/{}", self.bucket); + (url, fields) + } + + fn calculate_signature(&self, secret: &str, date: &str, region: &str, policy: &str) -> String { + let k_date = self.hmac_sha256(format!("AWS4{}", secret).as_bytes(), date); + let k_region = self.hmac_sha256(&k_date, region); + let k_service = self.hmac_sha256(&k_region, "s3"); + let k_signing = self.hmac_sha256(&k_service, "aws4_request"); + + hex::encode(self.hmac_sha256(&k_signing, policy)) + } + + fn hmac_sha256(&self, key: &[u8], data: &str) -> Vec { + let mut mac = Hmac::::new_from_slice(key).expect("HMAC can take key of any size"); + mac.update(data.as_bytes()); + mac.finalize().into_bytes().to_vec() + } +} \ No newline at end of file diff --git a/rnex-core/src/rmc/protocols/datastore.rs b/rnex-core/src/rmc/protocols/datastore.rs index d1eb4ff..9055355 100644 --- a/rnex-core/src/rmc/protocols/datastore.rs +++ b/rnex-core/src/rmc/protocols/datastore.rs @@ -1,6 +1,6 @@ use macros::{method_id, rmc_proto, RmcSerialize, rmc_struct}; -use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::qbuffer::QBuffer; +use rnex_core::rmc::response::ErrorCode; use rnex_core::kerberos::KerberosDateTime; use rnex_core::PID; @@ -12,7 +12,7 @@ pub struct PersistenceTarget { pub persistence_slot_id: u16, } -#[derive(RmcSerialize, Clone)] +#[derive(RmcSerialize, Clone, Debug)] #[rmc_struct(0)] pub struct Permission { pub permission: u8, @@ -49,7 +49,7 @@ pub struct GetMetaInfo { pub dataid: u64, pub owner: PID, pub size: u32, - pub name: &'static str, + pub name: String, pub data_type: u16, pub meta_binary: QBuffer, pub permission: Permission, @@ -58,17 +58,101 @@ pub struct GetMetaInfo { pub updated_time: KerberosDateTime, pub period: u16, pub status: u8, - pub reffered_count: u32, + pub referred_count: u32, pub refer_dat_id: u32, pub flag: u32, pub referred_time: KerberosDateTime, pub expire_time: KerberosDateTime, - pub tags: Vec<&'static str>, + pub tags: Vec, pub ratings: Vec, } +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct RatingInitParam { + pub flag: u8, + pub internal_flag: u8, + pub lock_type: u8, + pub intial_valie: i64, + pub range_min: i32, + pub range_max: i32, + pub period_hour: i8, + pub period_duration: i16 +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct RatingInitParamWithSlot { + pub slot: i8, + pub param: RatingInitParam, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct PersistenceInitParam { + pub persistence_slot_id: u16, + pub delete_last_object: bool, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct KeyValue { + pub key: String, + pub value: String, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct PreparePostParam { + pub size: u32, + pub name: String, + pub data_type: u16, + pub meta_binary: QBuffer, + pub permission: Permission, + pub del_permission: Permission, + pub flag: u32, + pub period: u16, + pub refer_data_id: u32, + pub tags: Vec, + pub rating_init_params: Vec, + pub persistence_init_param: PersistenceInitParam, + pub extra_data: Vec, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct ReqPostInfo { + pub dataid: u64, + pub url: String, + pub request_headers: Vec, + pub form_fields: Vec, + pub root_ca_cert: Vec, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct CompletePostParam { + pub dataid: u64, + pub success: bool, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct RateCustomRankingParam { + pub dataid: u64, + pub appid: u32, + pub score: u32, + pub period: u16, +} + #[rmc_proto(115)] pub trait DataStore{ #[method_id(8)] async fn get_meta(&self, metaparam: GetMetaParam) -> Result; + #[method_id(24)] + async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result; + #[method_id(26)] + async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode>; + #[method_id(48)] + async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode>; } \ No newline at end of file From 75c6e9df49e2ee6a8f3795ff00e2c6726c1505ec Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 14 Apr 2026 09:19:00 +0200 Subject: [PATCH 084/203] Dynamically load S3 details --- rnex-core/src/executables/common.rs | 12 +++++++++++- rnex-core/src/nex/datastore.rs | 6 +++++- rnex-core/src/nex/s3presigner.rs | 5 +++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index 416e450..08ba399 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -8,14 +8,24 @@ use std::io::Cursor; use std::net::{Ipv4Addr, SocketAddrV4}; use std::sync::Arc; use tokio::net::TcpListener; +use std::sync::LazyLock; use log::error; use std::error::Error; - +use std::string::ToString; use crate::reggie::UnitPacketRead; const IP_REQ_SERVICE_URL: &str = "https://ipinfo.io/ip"; +pub static RNEX_DATASTORE_S3_ENDPOINT: LazyLock = LazyLock::new(|| { + std::env::var("RNEX_DATASTORE_S3_ENDPOINT") + .expect("RNEX_DATASTORE_S3_ENDPOINT must be set") +}); +pub static RNEX_DATASTORE_S3_BUCKET: LazyLock = LazyLock::new(|| { + std::env::var("RNEX_DATASTORE_S3_BUCKET") + .expect("RNEX_DATASTORE_S3_BUCKET must be set") +}); + pub fn try_get_ip() -> Result> { let mut req = ureq::get(IP_REQ_SERVICE_URL).call()?; diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index 9299906..89e5a02 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -10,6 +10,7 @@ use rnex_core::rmc::protocols::secure::{Secure, RawSecure, RawSecureInfo, Remote use rnex_core::rmc::protocols::datastore::{CompletePostParam, GetMetaInfo, GetMetaParam, KeyValue, RateCustomRankingParam}; use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore, PreparePostParam, ReqPostInfo}; use crate::nex::user::User; +use rnex_core::executables::common::{RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT}; impl DataStore for User { async fn get_meta(&self, metaparam: GetMetaParam) -> Result { @@ -22,7 +23,10 @@ impl DataStore for User { async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result { let data_id: u64 = 9400001; - let presigner = S3Presigner::new("https://s3.perditum.com", "miku".into()).await; + let presigner = S3Presigner::new( + &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), + format!("{}", *RNEX_DATASTORE_S3_BUCKET) + ).await; let key = format!("data/{}.bin", data_id); diff --git a/rnex-core/src/nex/s3presigner.rs b/rnex-core/src/nex/s3presigner.rs index c348c9d..169293b 100644 --- a/rnex-core/src/nex/s3presigner.rs +++ b/rnex-core/src/nex/s3presigner.rs @@ -4,6 +4,7 @@ use hmac::{Hmac, Mac}; use sha2::{Sha256, Digest}; use chrono::{Utc, Duration}; use serde_json::json; +use rnex_core::executables::common::RNEX_DATASTORE_S3_ENDPOINT; pub struct S3Presigner { endpoint: String, @@ -20,7 +21,7 @@ impl S3Presigner { pub async fn generate_presigned_post(&self, key: &str) -> (String, Vec<(String, String)>) { let access_key = std::env::var("AWS_ACCESS_KEY_ID").expect("Missing Access Key"); let secret_key = std::env::var("AWS_SECRET_ACCESS_KEY").expect("Missing Secret Key"); - let region = "us-east-1"; + let region = "us-east-1"; // hardcoded because its the default region for most s3 clones let date_short = Utc::now().format("%Y%m%d").to_string(); let date_full = Utc::now().format("%Y%m%dT%H%M%SZ").to_string(); let expiration = (Utc::now() + Duration::minutes(15)).format("%Y-%m-%dT%H:%M:%SZ").to_string(); @@ -51,7 +52,7 @@ impl S3Presigner { ("X-Amz-Signature".to_string(), signature), ]; - let url = format!("https://s3.perditum.com/{}", self.bucket); + let url = format!("https://{}/{}", *RNEX_DATASTORE_S3_ENDPOINT, self.bucket); (url, fields) } From 3b103e12d4c58f5e1269505e30c7c4d9f085d6a2 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 14 Apr 2026 09:42:18 +0200 Subject: [PATCH 085/203] Implement GetApplicationConfig --- rnex-core/src/nex/datastore.rs | 36 ++++++++++++++++++++++++ rnex-core/src/rmc/protocols/datastore.rs | 9 ++++++ 2 files changed, 45 insertions(+) diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index 89e5a02..a2d8b8a 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -57,4 +57,40 @@ impl DataStore for User { // this returns nothing Ok(()) } + + async fn get_application_config(&self, appid: u32) -> Result, ErrorCode> { + const MAX_COURSE_UPLOADS: i32 = 100; + + let config = match appid { + 0 => vec![ + 0x00000001, 0x00000032, 0x00000096, 0x0000012c, 0x000001f4, + 0x00000320, 0x00000514, 0x000007d0, 0x00000bb8, 0x00001388, + MAX_COURSE_UPLOADS, 0x00000014, 0x0000001e, 0x00000028, 0x00000032, + 0x0000003c, 0x00000046, 0x00000050, 0x0000005a, 0x00000064, + 0x00000023, 0x0000004b, 0x00000023, 0x0000004b, 0x00000032, + 0x00000000, 0x00000003, 0x00000003, 0x00000064, 0x00000006, + 0x00000001, 0x00000060, 0x00000005, 0x00000060, 0x00000000, + 0x000007e4, 0x00000001, 0x00000001, 0x0000000c, 0x00000000, + ], + 1 => vec![ + 2, + 1770179696, + 1770179664, + 1770179640, + 1770180827, + 1770180777, + 1770180745, + 1770177625, + 1770177590, + ], + 2 => vec![0x000007df, 0x0000000c, 0x00000016, 0x00000005, 0x00000000], + 10 => vec![35, 75, 96, 40, 5, 6], + _ => { + log::error!("unknown SMM app id: {}", appid); + return Err(ErrorCode::DataStore_Unknown); + } + }; + + Ok(config) + } } \ No newline at end of file diff --git a/rnex-core/src/rmc/protocols/datastore.rs b/rnex-core/src/rmc/protocols/datastore.rs index 9055355..3899f93 100644 --- a/rnex-core/src/rmc/protocols/datastore.rs +++ b/rnex-core/src/rmc/protocols/datastore.rs @@ -145,6 +145,13 @@ pub struct RateCustomRankingParam { pub period: u16, } +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct BufferQueueParam { + pub dataid: u64, + pub slot: u32, +} + #[rmc_proto(115)] pub trait DataStore{ #[method_id(8)] @@ -155,4 +162,6 @@ pub trait DataStore{ async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode>; #[method_id(48)] async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode>; + #[method_id(61)] + async fn get_application_config(&self, appid: u32) -> Result, ErrorCode>; } \ No newline at end of file From ee798408f06fa393a38ca2523447e9f0d03b2431 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 14 Apr 2026 10:49:30 +0200 Subject: [PATCH 086/203] preliminary DB support --- Cargo.lock | 22 +++++++++ ...b44a630eb066846c777c462b8c9341e26b696.json | 38 ++++++++++++++ rnex-core/Cargo.toml | 2 +- .../src/executables/backend_server_secure.rs | 11 +++++ rnex-core/src/executables/common.rs | 12 +++++ rnex-core/src/nex/datastore.rs | 49 ++++++++++++++++++- 6 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 rnex-core/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json diff --git a/Cargo.lock b/Cargo.lock index 3e1d57d..8fd84b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2628,6 +2628,7 @@ checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ "base64", "bytes", + "chrono", "crc", "crossbeam-queue", "either", @@ -2648,6 +2649,9 @@ dependencies = [ "sha2", "smallvec", "thiserror", + "time", + "tokio", + "tokio-stream", "tracing", "url", ] @@ -2686,6 +2690,7 @@ dependencies = [ "sqlx-postgres", "sqlx-sqlite", "syn 2.0.104", + "tokio", "url", ] @@ -2700,6 +2705,7 @@ dependencies = [ "bitflags", "byteorder", "bytes", + "chrono", "crc", "digest", "dotenvy", @@ -2727,6 +2733,7 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror", + "time", "tracing", "whoami", ] @@ -2741,6 +2748,7 @@ dependencies = [ "base64", "bitflags", "byteorder", + "chrono", "crc", "dotenvy", "etcetera", @@ -2764,6 +2772,7 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror", + "time", "tracing", "whoami", ] @@ -2775,6 +2784,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" dependencies = [ "atoi", + "chrono", "flume", "futures-channel", "futures-core", @@ -2788,6 +2798,7 @@ dependencies = [ "serde_urlencoded", "sqlx-core", "thiserror", + "time", "tracing", "url", ] @@ -2983,6 +2994,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-tungstenite" version = "0.28.0" diff --git a/rnex-core/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json b/rnex-core/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json new file mode 100644 index 0000000..f91446a --- /dev/null +++ b/rnex-core/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO datastore.objects (\n owner, size, name, data_type, meta_binary,\n permission, permission_recipients,\n delete_permission, delete_permission_recipients,\n flag, period, refer_data_id, tags,\n persistence_slot_id, extra_data, creation_date, update_date\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17\n ) RETURNING data_id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int4", + "Int4", + "Text", + "Int4", + "Bytea", + "Int4", + "Int4Array", + "Int4", + "Int4Array", + "Int4", + "Int4", + "Int8", + "TextArray", + "Int4", + "TextArray", + "Timestamp", + "Timestamp" + ] + }, + "nullable": [ + false + ] + }, + "hash": "039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696" +} diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 07e5dd8..646b65e 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -28,7 +28,7 @@ anyhow = "1.0.100" ureq = { version = "3.1.4", features = [ "json" ] } serde = { version = "1.0.228", features = [ "derive" ] } serde_json = "1.0.149" -sqlx = { version = "0.8.6", optional = true } +sqlx = { version = "0.8.6", optional = true, features = ["postgres", "runtime-tokio", "chrono", "time"] } aws-sdk-s3 = { version = "1.129.0", optional = true } aws-config = { version = "1.8.15", optional = true } base64 = "0.22.1" diff --git a/rnex-core/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs index 91b83b3..a92ba9a 100644 --- a/rnex-core/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -1,5 +1,6 @@ use cfg_if::cfg_if; use rnex_core::common::setup; +use rnex_core::executables::common::DB_POOL; use rnex_core::executables::common::new_simple_backend; use rnex_core::executables::friends_backend::start_friends_backend; use rnex_core::nex::matchmake::MatchmakeManager; @@ -8,6 +9,7 @@ use rnex_core::nex::user::User; use rnex_core::rmc::protocols::{RemoteDisconnectable, RmcPureRemoteObject}; use std::sync::Arc; use std::sync::atomic::AtomicU32; +use sqlx::PgPool; #[tokio::main] async fn main() { @@ -16,6 +18,15 @@ async fn main() { cfg_if! { if #[cfg(feature = "friends")]{ start_friends_backend().await; + } else if #[cfg(feature = "datastore")] { + let database_url = std::env::var("RNEX_DATASTORE_DATABASE_URL") + .expect("RNEX_DATASTORE_DATABASE_URL must be set"); + + let pool = PgPool::connect(&database_url) + .await + .expect("Failed to create pool"); + + DB_POOL.set(pool).expect("failed to set global DB_POOL"); } else { use rnex_core::executables::regular_backend; regular_backend::start_regular_backend().await diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index 08ba399..ec27f43 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -9,6 +9,8 @@ use std::net::{Ipv4Addr, SocketAddrV4}; use std::sync::Arc; use tokio::net::TcpListener; use std::sync::LazyLock; +use std::sync::OnceLock; +use sqlx::postgres::PgPool; use log::error; use std::error::Error; @@ -17,6 +19,16 @@ use crate::reggie::UnitPacketRead; const IP_REQ_SERVICE_URL: &str = "https://ipinfo.io/ip"; +pub static RNEX_DATASTORE_DATABASE_URL: LazyLock = LazyLock::new(|| { + std::env::var("RNEX_DATASTORE_DATABASE_URL") + .expect("RNEX_DATASTORE_DATABASE_URL must be set") +}); + +pub static DB_POOL: OnceLock = OnceLock::new(); + +pub fn get_db() -> &'static PgPool { + DB_POOL.get().expect("db_pool not initialized") +} pub static RNEX_DATASTORE_S3_ENDPOINT: LazyLock = LazyLock::new(|| { std::env::var("RNEX_DATASTORE_S3_ENDPOINT") .expect("RNEX_DATASTORE_S3_ENDPOINT must be set") diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index a2d8b8a..57635a7 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -2,6 +2,9 @@ use crate::define_rmc_proto; use macros::rmc_struct; use rnex_core::prudp::socket_addr::PRUDPSockAddr; use std::sync::{Weak}; +use chrono::Utc; +use sqlx::types::time; +use sqlx::types::time::PrimitiveDateTime; use rnex_core::PID; use rnex_core::nex::remote_console::RemoteConsole; use rnex_core::nex::s3presigner::S3Presigner; @@ -10,7 +13,7 @@ use rnex_core::rmc::protocols::secure::{Secure, RawSecure, RawSecureInfo, Remote use rnex_core::rmc::protocols::datastore::{CompletePostParam, GetMetaInfo, GetMetaParam, KeyValue, RateCustomRankingParam}; use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore, PreparePostParam, ReqPostInfo}; use crate::nex::user::User; -use rnex_core::executables::common::{RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT}; +use rnex_core::executables::common::{RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db}; impl DataStore for User { async fn get_meta(&self, metaparam: GetMetaParam) -> Result { @@ -22,7 +25,49 @@ impl DataStore for User { } async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result { - let data_id: u64 = 9400001; + // Prepare your arrays first (Postgres needs i32, not u32) + let recipient_ids: Vec = postparam.permission.recipient_ids.iter().map(|&id| id as i32).collect(); + let del_recipient_ids: Vec = postparam.del_permission.recipient_ids.iter().map(|&id| id as i32).collect(); + let now = time::OffsetDateTime::now_utc(); + + let row = sqlx::query!( + r#" + INSERT INTO datastore.objects ( + owner, size, name, data_type, meta_binary, + permission, permission_recipients, + delete_permission, delete_permission_recipients, + flag, period, refer_data_id, tags, + persistence_slot_id, extra_data, creation_date, update_date + ) VALUES ( + $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17 + ) RETURNING data_id + "#, + self.pid as i32, + postparam.size as i32, + postparam.name, + postparam.data_type as i32, + &postparam.meta_binary.0, // unwrap QBuffer to &[u8] + postparam.permission.permission as i32, + &recipient_ids, + postparam.del_permission.permission as i32, + &del_recipient_ids, + postparam.flag as i32, + postparam.period as i32, + postparam.refer_data_id as i64, + &postparam.tags, + postparam.persistence_init_param.persistence_slot_id as i32, + &postparam.extra_data, + time::PrimitiveDateTime::new(now.date(), now.time()), + time::PrimitiveDateTime::new(now.date(), now.time()) + ) + .fetch_one(get_db()) + .await + .map_err(|e| { + log::error!("DB Error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + + let data_id = row.data_id as u64; let presigner = S3Presigner::new( &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), format!("{}", *RNEX_DATASTORE_S3_BUCKET) From b07c97f2bcd269f6c8db1559a5bfa757b3577258 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 14 Apr 2026 10:53:57 +0200 Subject: [PATCH 087/203] I've got to be like a professional dumbass or smth --- rnex-core/src/executables/backend_server_secure.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rnex-core/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs index a92ba9a..0beeafc 100644 --- a/rnex-core/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -27,6 +27,8 @@ async fn main() { .expect("Failed to create pool"); DB_POOL.set(pool).expect("failed to set global DB_POOL"); + use rnex_core::executables::regular_backend; + regular_backend::start_regular_backend().await } else { use rnex_core::executables::regular_backend; regular_backend::start_regular_backend().await From 2b8132452f5e7a8331e0c793de54e125e3a1ff72 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 14 Apr 2026 19:42:44 +0200 Subject: [PATCH 088/203] More work on datastore --- ...b44a630eb066846c777c462b8c9341e26b696.json | 38 ++ ...d3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json | 28 ++ ...077f9b06ffe11cab2693e4e365c265f8e2418.json | 125 +++++ ...88d2d26f7644e85bfd65423e6e32c469e3695.json | 16 + ...b8158ea907d36588e1e59f6cbe752d89361bb.json | 22 + ...f7803ee88233c53efaa2df9966a6c72c8c763.json | 23 + ...a4beaf37e879c28c81c22abeddb3d030535df.json | 28 ++ ...8be8946430d93821dbccb6dc9324ef0544c17.json | 29 ++ ...1d9f4ef96adbdab7ca7d008acf596af91fc2b.json | 112 +++++ ...e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json | 40 ++ ...fe18e500d243f1b55fd18e7d96d281605bcf9.json | 14 + build-edition.sh | 1 + ...d3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json | 28 ++ ...077f9b06ffe11cab2693e4e365c265f8e2418.json | 125 +++++ ...88d2d26f7644e85bfd65423e6e32c469e3695.json | 16 + ...b8158ea907d36588e1e59f6cbe752d89361bb.json | 22 + ...f7803ee88233c53efaa2df9966a6c72c8c763.json | 23 + ...a4beaf37e879c28c81c22abeddb3d030535df.json | 28 ++ ...8be8946430d93821dbccb6dc9324ef0544c17.json | 29 ++ ...1d9f4ef96adbdab7ca7d008acf596af91fc2b.json | 112 +++++ ...e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json | 40 ++ ...fe18e500d243f1b55fd18e7d96d281605bcf9.json | 14 + rnex-core/src/kerberos/mod.rs | 17 + rnex-core/src/nex/datastore.rs | 465 +++++++++++++++++- rnex-core/src/rmc/protocols/datastore.rs | 25 +- 25 files changed, 1406 insertions(+), 14 deletions(-) create mode 100644 .sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json create mode 100644 .sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json create mode 100644 .sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json create mode 100644 .sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json create mode 100644 .sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json create mode 100644 .sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json create mode 100644 .sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json create mode 100644 .sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json create mode 100644 .sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json create mode 100644 .sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json create mode 100644 .sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json create mode 100644 rnex-core/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json create mode 100644 rnex-core/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json create mode 100644 rnex-core/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json create mode 100644 rnex-core/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json create mode 100644 rnex-core/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json create mode 100644 rnex-core/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json create mode 100644 rnex-core/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json create mode 100644 rnex-core/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json create mode 100644 rnex-core/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json create mode 100644 rnex-core/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json diff --git a/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json b/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json new file mode 100644 index 0000000..f91446a --- /dev/null +++ b/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO datastore.objects (\n owner, size, name, data_type, meta_binary,\n permission, permission_recipients,\n delete_permission, delete_permission_recipients,\n flag, period, refer_data_id, tags,\n persistence_slot_id, extra_data, creation_date, update_date\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17\n ) RETURNING data_id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int4", + "Int4", + "Text", + "Int4", + "Bytea", + "Int4", + "Int4Array", + "Int4", + "Int4Array", + "Int4", + "Int4", + "Int8", + "TextArray", + "Int4", + "TextArray", + "Timestamp", + "Timestamp" + ] + }, + "nullable": [ + false + ] + }, + "hash": "039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696" +} diff --git a/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json b/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json new file mode 100644 index 0000000..abf5c03 --- /dev/null +++ b/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json @@ -0,0 +1,28 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT owner, under_review FROM datastore.objects WHERE data_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "owner", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "under_review", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + true, + false + ] + }, + "hash": "164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9" +} diff --git a/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json b/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json new file mode 100644 index 0000000..7471873 --- /dev/null +++ b/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json @@ -0,0 +1,125 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date,\n access_password, under_review\n FROM datastore.objects\n WHERE owner = $1 AND persistence_slot_id = $2\n AND upload_completed = TRUE AND deleted = FALSE", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "owner", + "type_info": "Int4" + }, + { + "ordinal": 2, + "name": "size", + "type_info": "Int4" + }, + { + "ordinal": 3, + "name": "name", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "data_type", + "type_info": "Int4" + }, + { + "ordinal": 5, + "name": "meta_binary", + "type_info": "Bytea" + }, + { + "ordinal": 6, + "name": "permission", + "type_info": "Int4" + }, + { + "ordinal": 7, + "name": "permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 8, + "name": "delete_permission", + "type_info": "Int4" + }, + { + "ordinal": 9, + "name": "delete_permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 10, + "name": "period", + "type_info": "Int4" + }, + { + "ordinal": 11, + "name": "refer_data_id", + "type_info": "Int8" + }, + { + "ordinal": 12, + "name": "flag", + "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "tags", + "type_info": "TextArray" + }, + { + "ordinal": 14, + "name": "creation_date", + "type_info": "Timestamp" + }, + { + "ordinal": 15, + "name": "update_date", + "type_info": "Timestamp" + }, + { + "ordinal": 16, + "name": "access_password", + "type_info": "Int8" + }, + { + "ordinal": 17, + "name": "under_review", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int4", + "Int4" + ] + }, + "nullable": [ + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false + ] + }, + "hash": "18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418" +} diff --git a/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json b/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json new file mode 100644 index 0000000..5411a38 --- /dev/null +++ b/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO datastore.object_custom_rankings (data_id, application_id, value)\n VALUES ($1, $2, $3)\n ON CONFLICT (data_id, application_id)\n DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Int8", + "Int8" + ] + }, + "nullable": [] + }, + "hash": "29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695" +} diff --git a/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json b/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json new file mode 100644 index 0000000..83246ca --- /dev/null +++ b/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + null + ] + }, + "hash": "2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb" +} diff --git a/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json b/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json new file mode 100644 index 0000000..7a1cc6f --- /dev/null +++ b/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT buffer\n FROM datastore.buffer_queues\n WHERE data_id = $1 AND slot = $2\n ORDER BY creation_date ASC\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "buffer", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [ + "Int8", + "Int4" + ] + }, + "nullable": [ + false + ] + }, + "hash": "48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763" +} diff --git a/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json b/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json new file mode 100644 index 0000000..4f07b49 --- /dev/null +++ b/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json @@ -0,0 +1,28 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT under_review, access_password\n FROM datastore.objects\n WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "under_review", + "type_info": "Bool" + }, + { + "ordinal": 1, + "name": "access_password", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + false + ] + }, + "hash": "60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df" +} diff --git a/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json b/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json new file mode 100644 index 0000000..867701f --- /dev/null +++ b/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json @@ -0,0 +1,29 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n rankings.data_id,\n rankings.value\n FROM datastore.object_custom_rankings rankings\n JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord)\n ON rankings.data_id = rows.data_id\n AND rankings.application_id = $2\n ORDER BY rows.ord\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "value", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8Array", + "Int8" + ] + }, + "nullable": [ + false, + true + ] + }, + "hash": "8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17" +} diff --git a/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json b/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json new file mode 100644 index 0000000..539fdeb --- /dev/null +++ b/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json @@ -0,0 +1,112 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date\n FROM datastore.objects WHERE data_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "owner", + "type_info": "Int4" + }, + { + "ordinal": 2, + "name": "size", + "type_info": "Int4" + }, + { + "ordinal": 3, + "name": "name", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "data_type", + "type_info": "Int4" + }, + { + "ordinal": 5, + "name": "meta_binary", + "type_info": "Bytea" + }, + { + "ordinal": 6, + "name": "permission", + "type_info": "Int4" + }, + { + "ordinal": 7, + "name": "permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 8, + "name": "delete_permission", + "type_info": "Int4" + }, + { + "ordinal": 9, + "name": "delete_permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 10, + "name": "period", + "type_info": "Int4" + }, + { + "ordinal": 11, + "name": "refer_data_id", + "type_info": "Int8" + }, + { + "ordinal": 12, + "name": "flag", + "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "tags", + "type_info": "TextArray" + }, + { + "ordinal": 14, + "name": "creation_date", + "type_info": "Timestamp" + }, + { + "ordinal": 15, + "name": "update_date", + "type_info": "Timestamp" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ] + }, + "hash": "a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b" +} diff --git a/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json b/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json new file mode 100644 index 0000000..095ca6f --- /dev/null +++ b/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json @@ -0,0 +1,40 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT slot, total_value, count, initial_value\n FROM datastore.object_ratings\n WHERE data_id = $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "slot", + "type_info": "Int2" + }, + { + "ordinal": 1, + "name": "total_value", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "count", + "type_info": "Int4" + }, + { + "ordinal": 3, + "name": "initial_value", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + true, + false, + true + ] + }, + "hash": "c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa" +} diff --git a/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json b/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json new file mode 100644 index 0000000..552f92a --- /dev/null +++ b/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [] + }, + "hash": "e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9" +} diff --git a/build-edition.sh b/build-edition.sh index ede64d3..d2c0750 100755 --- a/build-edition.sh +++ b/build-edition.sh @@ -11,4 +11,5 @@ echo ENV SETTINGS: env #OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl +OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 cargo sqlx prepare --workspace -- --features "$EDITION_FEATURES" OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 cargo build --release --features "$EDITION_FEATURES" diff --git a/rnex-core/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json b/rnex-core/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json new file mode 100644 index 0000000..abf5c03 --- /dev/null +++ b/rnex-core/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json @@ -0,0 +1,28 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT owner, under_review FROM datastore.objects WHERE data_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "owner", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "under_review", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + true, + false + ] + }, + "hash": "164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9" +} diff --git a/rnex-core/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json b/rnex-core/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json new file mode 100644 index 0000000..7471873 --- /dev/null +++ b/rnex-core/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json @@ -0,0 +1,125 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date,\n access_password, under_review\n FROM datastore.objects\n WHERE owner = $1 AND persistence_slot_id = $2\n AND upload_completed = TRUE AND deleted = FALSE", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "owner", + "type_info": "Int4" + }, + { + "ordinal": 2, + "name": "size", + "type_info": "Int4" + }, + { + "ordinal": 3, + "name": "name", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "data_type", + "type_info": "Int4" + }, + { + "ordinal": 5, + "name": "meta_binary", + "type_info": "Bytea" + }, + { + "ordinal": 6, + "name": "permission", + "type_info": "Int4" + }, + { + "ordinal": 7, + "name": "permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 8, + "name": "delete_permission", + "type_info": "Int4" + }, + { + "ordinal": 9, + "name": "delete_permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 10, + "name": "period", + "type_info": "Int4" + }, + { + "ordinal": 11, + "name": "refer_data_id", + "type_info": "Int8" + }, + { + "ordinal": 12, + "name": "flag", + "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "tags", + "type_info": "TextArray" + }, + { + "ordinal": 14, + "name": "creation_date", + "type_info": "Timestamp" + }, + { + "ordinal": 15, + "name": "update_date", + "type_info": "Timestamp" + }, + { + "ordinal": 16, + "name": "access_password", + "type_info": "Int8" + }, + { + "ordinal": 17, + "name": "under_review", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int4", + "Int4" + ] + }, + "nullable": [ + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false + ] + }, + "hash": "18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418" +} diff --git a/rnex-core/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json b/rnex-core/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json new file mode 100644 index 0000000..5411a38 --- /dev/null +++ b/rnex-core/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO datastore.object_custom_rankings (data_id, application_id, value)\n VALUES ($1, $2, $3)\n ON CONFLICT (data_id, application_id)\n DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Int8", + "Int8" + ] + }, + "nullable": [] + }, + "hash": "29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695" +} diff --git a/rnex-core/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json b/rnex-core/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json new file mode 100644 index 0000000..83246ca --- /dev/null +++ b/rnex-core/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + null + ] + }, + "hash": "2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb" +} diff --git a/rnex-core/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json b/rnex-core/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json new file mode 100644 index 0000000..7a1cc6f --- /dev/null +++ b/rnex-core/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT buffer\n FROM datastore.buffer_queues\n WHERE data_id = $1 AND slot = $2\n ORDER BY creation_date ASC\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "buffer", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [ + "Int8", + "Int4" + ] + }, + "nullable": [ + false + ] + }, + "hash": "48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763" +} diff --git a/rnex-core/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json b/rnex-core/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json new file mode 100644 index 0000000..4f07b49 --- /dev/null +++ b/rnex-core/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json @@ -0,0 +1,28 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT under_review, access_password\n FROM datastore.objects\n WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "under_review", + "type_info": "Bool" + }, + { + "ordinal": 1, + "name": "access_password", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + false + ] + }, + "hash": "60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df" +} diff --git a/rnex-core/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json b/rnex-core/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json new file mode 100644 index 0000000..867701f --- /dev/null +++ b/rnex-core/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json @@ -0,0 +1,29 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n rankings.data_id,\n rankings.value\n FROM datastore.object_custom_rankings rankings\n JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord)\n ON rankings.data_id = rows.data_id\n AND rankings.application_id = $2\n ORDER BY rows.ord\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "value", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8Array", + "Int8" + ] + }, + "nullable": [ + false, + true + ] + }, + "hash": "8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17" +} diff --git a/rnex-core/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json b/rnex-core/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json new file mode 100644 index 0000000..539fdeb --- /dev/null +++ b/rnex-core/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json @@ -0,0 +1,112 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date\n FROM datastore.objects WHERE data_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "owner", + "type_info": "Int4" + }, + { + "ordinal": 2, + "name": "size", + "type_info": "Int4" + }, + { + "ordinal": 3, + "name": "name", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "data_type", + "type_info": "Int4" + }, + { + "ordinal": 5, + "name": "meta_binary", + "type_info": "Bytea" + }, + { + "ordinal": 6, + "name": "permission", + "type_info": "Int4" + }, + { + "ordinal": 7, + "name": "permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 8, + "name": "delete_permission", + "type_info": "Int4" + }, + { + "ordinal": 9, + "name": "delete_permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 10, + "name": "period", + "type_info": "Int4" + }, + { + "ordinal": 11, + "name": "refer_data_id", + "type_info": "Int8" + }, + { + "ordinal": 12, + "name": "flag", + "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "tags", + "type_info": "TextArray" + }, + { + "ordinal": 14, + "name": "creation_date", + "type_info": "Timestamp" + }, + { + "ordinal": 15, + "name": "update_date", + "type_info": "Timestamp" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ] + }, + "hash": "a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b" +} diff --git a/rnex-core/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json b/rnex-core/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json new file mode 100644 index 0000000..095ca6f --- /dev/null +++ b/rnex-core/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json @@ -0,0 +1,40 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT slot, total_value, count, initial_value\n FROM datastore.object_ratings\n WHERE data_id = $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "slot", + "type_info": "Int2" + }, + { + "ordinal": 1, + "name": "total_value", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "count", + "type_info": "Int4" + }, + { + "ordinal": 3, + "name": "initial_value", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + true, + false, + true + ] + }, + "hash": "c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa" +} diff --git a/rnex-core/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json b/rnex-core/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json new file mode 100644 index 0000000..552f92a --- /dev/null +++ b/rnex-core/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [] + }, + "hash": "e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9" +} diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index 205c62a..00f775d 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -51,6 +51,23 @@ pub fn derive_key(pid: PID, password: &[u8]) -> [u8; 16] { pub struct KerberosDateTime(pub u64); impl KerberosDateTime { + pub fn from_u64(val: u64) -> Self { + Self(val) + } + + pub fn from_naive(dt: chrono::NaiveDateTime) -> Self { + use chrono::Datelike; + use chrono::Timelike; + Self::new( + dt.second() as u64, + dt.minute() as u64, + dt.hour() as u64, + dt.day() as u64, + dt.month() as u64, + dt.year() as u64, + ) + } + pub fn new(second: u64, minute: u64, hour: u64, day: u64, month: u64, year: u64) -> Self { Self(second | (minute << 6) | (hour << 12) | (day << 17) | (month << 22) | (year << 26)) } diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index 57635a7..19db2b4 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -10,22 +10,360 @@ use rnex_core::nex::remote_console::RemoteConsole; use rnex_core::nex::s3presigner::S3Presigner; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::protocols::secure::{Secure, RawSecure, RawSecureInfo, RemoteSecure}; -use rnex_core::rmc::protocols::datastore::{CompletePostParam, GetMetaInfo, GetMetaParam, KeyValue, RateCustomRankingParam}; +use rnex_core::rmc::protocols::datastore::{BufferQueueParam, CompletePostParam, DataStoreCustomRankingResult, DataStoreGetCustomRankingByDataIDParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, RateCustomRankingParam, RatingInfo, RatingInfoWithSlot}; use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore, PreparePostParam, ReqPostInfo}; use crate::nex::user::User; use rnex_core::executables::common::{RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db}; +use rnex_core::rmc::structures::qbuffer::QBuffer; +use sqlx::types::chrono::DateTime; +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::rmc::structures::qresult::QResult; + +fn map_row_to_meta_info( + row_data_id: i64, + row_owner: i32, + row_size: i32, + row_name: String, + row_data_type: i16, + row_meta_binary: Vec, + row_permission: i16, + row_permission_recipients: Vec, + row_delete_permission: i16, + row_delete_permission_recipients: Vec, + row_period: i16, + row_refer_data_id: i64, + row_flag: i32, + row_tags: Vec, + row_creation_date: chrono::NaiveDateTime, + row_update_date: chrono::NaiveDateTime, + ratings: Vec +) -> GetMetaInfo { + GetMetaInfo { + dataid: row_data_id as u64, + owner: row_owner as u32, + size: row_size as u32, + name: row_name, + data_type: row_data_type as u16, + meta_binary: QBuffer(row_meta_binary), + permission: Permission { + permission: row_permission as u8, + recipient_ids: row_permission_recipients.into_iter().map(|id| id as u32).collect(), + }, + del_permission: Permission { + permission: row_delete_permission as u8, + recipient_ids: row_delete_permission_recipients.into_iter().map(|id| id as u32).collect(), + }, + period: row_period as u16, + status: 0, + referred_count: 0, + refer_dat_id: row_refer_data_id as u32, + flag: row_flag as u32, + tags: row_tags, + expire_time: KerberosDateTime::from_u64(0x9C3F3E0000), + created_time: KerberosDateTime::from_naive(row_creation_date), + updated_time: KerberosDateTime::from_naive(row_update_date), + referred_time: KerberosDateTime::from_naive(row_creation_date), + ratings, + } +} + +async fn check_object_availability(data_id: u64, password: u64) -> Result<(), ErrorCode> { + let row = sqlx::query!( + r#" + SELECT under_review, access_password + FROM datastore.objects + WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE + "#, + data_id as i64 + ) + .fetch_optional(get_db()) + .await + .map_err(|e| { + eprintln!("Availability check DB error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })? + .ok_or(ErrorCode::DataStore_NotFound)?; + + let access_password = row.access_password as u64; + if access_password != 0 && access_password != password { + return Err(ErrorCode::DataStore_InvalidPassword); + } + + if row.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } + + Ok(()) +} + +async fn get_object_ratings(data_id: u64, password: u64) -> Result, ErrorCode> { + check_object_availability(data_id, password).await?; + + let rows = sqlx::query!( + r#" + SELECT slot, total_value, count, initial_value + FROM datastore.object_ratings + WHERE data_id = $1 + "#, + data_id as i64 + ) + .fetch_all(get_db()) + .await + .map_err(|e| { + eprintln!("Ratings fetch error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + + let ratings = rows.into_iter().map(|row| { + RatingInfoWithSlot { + slot: row.slot as i8, + rating: RatingInfo { + total_value: row.total_value.unwrap_or(0), + count: row.count as u32, + initial_value: row.initial_value.unwrap_or(0), + }, + } + }).collect(); + + Ok(ratings) +} + +async fn get_object_info_by_data_id(data_id: u64, password: u64) -> Result { + check_object_availability(data_id, password).await?; + + let row = sqlx::query!( + r#"SELECT data_id, owner, size, name, data_type, meta_binary, + permission, permission_recipients, delete_permission, delete_permission_recipients, + period, refer_data_id, flag, tags, creation_date, update_date + FROM datastore.objects WHERE data_id = $1"#, + data_id as i64 + ) + .fetch_optional(get_db()) + .await + .map_err(|_| ErrorCode::DataStore_SystemFileError)? + .ok_or(ErrorCode::DataStore_NotFound)?; + + let ratings = get_object_ratings(data_id, password).await?; + + Ok(map_row_to_meta_info( + row.data_id, + row.owner.unwrap_or(0), + row.size.unwrap_or(0), + row.name.unwrap_or_default(), + row.data_type.unwrap_or(0) as i16, + row.meta_binary.unwrap_or_default(), + row.permission.unwrap_or(0) as i16, + row.permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), + row.delete_permission.unwrap_or(0) as i16, + row.delete_permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), + row.period.unwrap_or(0) as i16, + row.refer_data_id.unwrap_or(0), + row.flag.unwrap_or(0), + row.tags.unwrap_or_default(), + row.creation_date.map(|dt| chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), + chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() + )).unwrap_or_default(), + row.update_date.map(|dt| chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), + chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() + )).unwrap_or_default(), + ratings + )) +} + +async fn get_object_info_by_persistence_target(target: PersistenceTarget, password: u64) -> Result { + let row = sqlx::query!( + r#"SELECT data_id, owner, size, name, data_type, meta_binary, + permission, permission_recipients, delete_permission, delete_permission_recipients, + period, refer_data_id, flag, tags, creation_date, update_date, + access_password, under_review + FROM datastore.objects + WHERE owner = $1 AND persistence_slot_id = $2 + AND upload_completed = TRUE AND deleted = FALSE"#, + target.owner as i32, + target.persistence_slot_id as i16 + ) + .fetch_optional(get_db()) + .await + .map_err(|_| ErrorCode::DataStore_SystemFileError)? + .ok_or(ErrorCode::DataStore_NotFound)?; + + let db_password = row.access_password as u64; + if db_password != 0 && db_password != password { + return Err(ErrorCode::DataStore_InvalidPassword); + } + + if row.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } + + let ratings = get_object_ratings(row.data_id as u64, password).await?; + + Ok(map_row_to_meta_info( + row.data_id, + row.owner.unwrap_or(0), + row.size.unwrap_or(0), + row.name.unwrap_or_default(), + row.data_type.unwrap_or(0) as i16, + row.meta_binary.unwrap_or_default(), + row.permission.unwrap_or(0) as i16, + row.permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), + row.delete_permission.unwrap_or(0) as i16, + row.delete_permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), + row.period.unwrap_or(0) as i16, + row.refer_data_id.unwrap_or(0), + row.flag.unwrap_or(0), + row.tags.unwrap_or_default(), + row.creation_date.map(|dt| chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), + chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() + )).unwrap_or_default(), + row.update_date.map(|dt| chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), + chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() + )).unwrap_or_default(), + ratings + )) +} + +async fn get_buffer_queues_by_data_id_and_slot( + data_id: u64, + slot: u32 +) -> Result, ErrorCode> { + check_object_availability(data_id, 0).await?; + + let rows = sqlx::query!( + r#" + SELECT buffer + FROM datastore.buffer_queues + WHERE data_id = $1 AND slot = $2 + ORDER BY creation_date ASC + "#, + data_id as i64, + slot as i32 + ) + .fetch_all(get_db()) + .await + .map_err(|e| { + log::error!("Buffer queue fetch error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + + let buffer_queues = rows + .into_iter() + .map(|row| QBuffer(row.buffer)) + .collect(); + + Ok(buffer_queues) +} + +fn verify_object_permission( + owner_id: u32, + viewer_id: u32, + permission: &Permission, +) -> Result<(), ErrorCode> { + if owner_id == viewer_id { + return Ok(()); + } + + match permission.permission { + 0 => Ok(()), // All can read + 1 => Err(ErrorCode::DataStore_PermissionDenied), // Friends only, unimplemented + 2 => { + // Recipient IDs can read + if permission.recipient_ids.contains(&viewer_id) { + Ok(()) + } else { + Err(ErrorCode::DataStore_PermissionDenied) + } + } + 3 => Err(ErrorCode::DataStore_PermissionDenied), // Owner only, redundant + _ => Err(ErrorCode::DataStore_InvalidArgument), // ??? haxx0r + } +} + +fn filter_properties_by_result_option( + meta_info: &mut GetMetaInfo, + result_option: u8, +) { + if (result_option & 0x01) == 0 { + meta_info.meta_binary = QBuffer(Vec::new()); + } + + if (result_option & 0x04) == 0 { + meta_info.ratings = Vec::new(); + } + + // No idea what the other things do. :shrug: +} + +// Dawg... +async fn get_custom_rankings_by_data_ids( + application_id: u32, + data_ids: Vec +) -> Vec { + let mut results = Vec::with_capacity(data_ids.len()); + + let rows = sqlx::query!( + r#" + SELECT + rankings.data_id, + rankings.value + FROM datastore.object_custom_rankings rankings + JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord) + ON rankings.data_id = rows.data_id + AND rankings.application_id = $2 + ORDER BY rows.ord + "#, + &data_ids.iter().map(|&id| id as i64).collect::>(), + application_id as i32 + ) + .fetch_all(get_db()) + .await; + + let rows = match rows { + Ok(r) => r, + Err(e) => { + log::error!("Custom ranking query error: {:?}", e); + return results; + } + }; + + for row in rows { + let data_id = row.data_id as u64; + let score = row.value.unwrap_or(0) as u32; + + if let Ok(meta) = get_object_info_by_data_id(data_id, 0).await { + results.push(DataStoreCustomRankingResult { + score, + meta_info: meta, + }); + } else { + log::warn!("Could not find metadata for ranked object {}", data_id); + } + } + + results +} impl DataStore for User { - async fn get_meta(&self, metaparam: GetMetaParam) -> Result { - println!("dataid: {}", metaparam.dataid); - println!("access password: {}", metaparam.access_password); + async fn get_meta(&self, mut metaparam: GetMetaParam) -> Result { + let mut meta_info = if metaparam.dataid != 0 { + get_object_info_by_data_id(metaparam.dataid, metaparam.access_password).await? + } else { + get_object_info_by_persistence_target(metaparam.persistence_target, metaparam.access_password).await? + }; - // just trying to see what methods it tries to use - Err(ErrorCode::DataStore_NotFound) + let current_pid = self.pid; + verify_object_permission(meta_info.owner, current_pid, &meta_info.permission)?; + + filter_properties_by_result_option(&mut meta_info, metaparam.result_option); + + Ok(meta_info) } async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result { - // Prepare your arrays first (Postgres needs i32, not u32) let recipient_ids: Vec = postparam.permission.recipient_ids.iter().map(|&id| id as i32).collect(); let del_recipient_ids: Vec = postparam.del_permission.recipient_ids.iter().map(|&id| id as i32).collect(); let now = time::OffsetDateTime::now_utc(); @@ -46,7 +384,7 @@ impl DataStore for User { postparam.size as i32, postparam.name, postparam.data_type as i32, - &postparam.meta_binary.0, // unwrap QBuffer to &[u8] + &postparam.meta_binary.0, postparam.permission.permission as i32, &recipient_ids, postparam.del_permission.permission as i32, @@ -91,15 +429,78 @@ impl DataStore for User { } async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode> { - // whatever - println!("dataid: {}", completeparam.dataid); - println!("succeeded?: {}", completeparam.success); + let record = sqlx::query!( + r#"SELECT owner, under_review FROM datastore.objects WHERE data_id = $1"#, + completeparam.dataid as i64 + ) + .fetch_optional(get_db()) + .await + .map_err(|e| { + eprintln!("select error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + + let record = record.ok_or(ErrorCode::DataStore_NotFound)?; + + if record.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } + + if record.owner.unwrap_or(0) as u32 != self.pid { + return Err(ErrorCode::DataStore_PermissionDenied); + } + + if completeparam.success { + sqlx::query!( + r#"UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1"#, + completeparam.dataid as i64 + ) + .execute(get_db()) + .await + .map_err(|e| { + eprintln!("update error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + } else { + return Err(ErrorCode::Transport_TemporaryServerError); + } Ok(()) } async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode> { - // this returns nothing + for param in rankingparam { + let exists = sqlx::query_scalar!( + r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#, + param.dataid as i64 + ) + .fetch_one(get_db()) + .await + .map_err(|_| ErrorCode::DataStore_SystemFileError)?; + + if !exists.unwrap_or(false) { + return Err(ErrorCode::DataStore_NotFound); + } + + sqlx::query!( + r#" + INSERT INTO datastore.object_custom_rankings (data_id, application_id, value) + VALUES ($1, $2, $3) + ON CONFLICT (data_id, application_id) + DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value + "#, + param.dataid as i64, + param.appid as i32, + param.score as i32 + ) + .execute(get_db()) + .await + .map_err(|e| { + log::error!("update/insert error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + } + Ok(()) } @@ -138,4 +539,44 @@ impl DataStore for User { Ok(config) } + + async fn get_custom_ranking_by_data_id( + &self, + param: DataStoreGetCustomRankingByDataIDParam + ) -> Result<(Vec, Vec), ErrorCode> { + + let mut ranking_results = get_custom_rankings_by_data_ids(param.application_id, param.data_id_list).await; + + let mut q_results = Vec::with_capacity(ranking_results.len()); + + for result in &mut ranking_results { + if (param.result_option & 0x01) == 0 { + result.meta_info.tags = Vec::new(); + } + + if (param.result_option & 0x02) == 0 { + result.meta_info.ratings = Vec::new(); + } + + if (param.result_option & 0x04) == 0 { + result.meta_info.meta_binary = QBuffer(Vec::new()); + } + + if (param.result_option & 0x20) == 0 { + result.score = 0; + } + + q_results.push(QResult::success(ErrorCode::Core_Unknown)); + } + + Ok((ranking_results, q_results)) + } + + async fn get_buffer_queue(&self, param: BufferQueueParam) -> Result, ErrorCode> { + // log::info!("GetBufferQueue: dataid={}, slot={}", param.dataid, param.slot); + + let buffers = get_buffer_queues_by_data_id_and_slot(param.dataid, param.slot).await?; + + Ok(buffers) + } } \ No newline at end of file diff --git a/rnex-core/src/rmc/protocols/datastore.rs b/rnex-core/src/rmc/protocols/datastore.rs index 3899f93..00e522f 100644 --- a/rnex-core/src/rmc/protocols/datastore.rs +++ b/rnex-core/src/rmc/protocols/datastore.rs @@ -1,11 +1,11 @@ use macros::{method_id, rmc_proto, RmcSerialize, rmc_struct}; use rnex_core::rmc::structures::qbuffer::QBuffer; use rnex_core::rmc::response::ErrorCode; - +use rnex_core::rmc::structures::qresult::QResult; use rnex_core::kerberos::KerberosDateTime; use rnex_core::PID; -#[derive(RmcSerialize, Clone)] +#[derive(RmcSerialize, Clone, Debug)] #[rmc_struct(0)] pub struct PersistenceTarget { pub owner: PID, @@ -152,6 +152,23 @@ pub struct BufferQueueParam { pub slot: u32, } +// I just realized I forgot to add "DataStore" in front of the structs. I can't be assed to change it, sucks to be you lol. + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct DataStoreGetCustomRankingByDataIDParam { + pub application_id: u32, + pub data_id_list: Vec, + pub result_option: u8, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct DataStoreCustomRankingResult { + pub score: u32, + pub meta_info: GetMetaInfo, +} + #[rmc_proto(115)] pub trait DataStore{ #[method_id(8)] @@ -164,4 +181,8 @@ pub trait DataStore{ async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode>; #[method_id(61)] async fn get_application_config(&self, appid: u32) -> Result, ErrorCode>; + #[method_id(50)] + async fn get_custom_ranking_by_data_id(&self, param: DataStoreGetCustomRankingByDataIDParam) -> Result<(Vec, Vec), ErrorCode>; + #[method_id(54)] + async fn get_buffer_queue(&self, param: BufferQueueParam) -> Result, ErrorCode>; } \ No newline at end of file From 08fac7af039d8b9850b649fcfff228320b75a3d8 Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 20 Apr 2026 14:06:04 +0200 Subject: [PATCH 089/203] Even more work on datastore --- ...b44a630eb066846c777c462b8c9341e26b696.json | 38 --- ...d3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json | 28 --- ...077f9b06ffe11cab2693e4e365c265f8e2418.json | 125 ---------- ...88d2d26f7644e85bfd65423e6e32c469e3695.json | 16 -- ...b8158ea907d36588e1e59f6cbe752d89361bb.json | 22 -- ...f7803ee88233c53efaa2df9966a6c72c8c763.json | 23 -- ...a4beaf37e879c28c81c22abeddb3d030535df.json | 28 --- ...8be8946430d93821dbccb6dc9324ef0544c17.json | 29 --- ...1d9f4ef96adbdab7ca7d008acf596af91fc2b.json | 112 --------- ...e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json | 40 ---- ...fe18e500d243f1b55fd18e7d96d281605bcf9.json | 14 -- Cargo.lock | 1 + rnex-core/Cargo.toml | 1 + rnex-core/src/nex/datastore.rs | 226 ++++++++++++++++-- rnex-core/src/nex/s3presigner.rs | 44 ++++ rnex-core/src/rmc/protocols/datastore.rs | 64 ++++- rnex-core/src/rmc/protocols/ranking.rs | 9 +- rnex-core/src/rmc/structures/mod.rs | 1 + rnex-core/src/rmc/structures/qbuffer.rs | 2 +- rnex-core/src/rmc/structures/resultsrange.rs | 8 + 20 files changed, 327 insertions(+), 504 deletions(-) delete mode 100644 .sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json delete mode 100644 .sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json delete mode 100644 .sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json delete mode 100644 .sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json delete mode 100644 .sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json delete mode 100644 .sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json delete mode 100644 .sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json delete mode 100644 .sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json delete mode 100644 .sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json delete mode 100644 .sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json delete mode 100644 .sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json create mode 100644 rnex-core/src/rmc/structures/resultsrange.rs diff --git a/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json b/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json deleted file mode 100644 index f91446a..0000000 --- a/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n INSERT INTO datastore.objects (\n owner, size, name, data_type, meta_binary,\n permission, permission_recipients,\n delete_permission, delete_permission_recipients,\n flag, period, refer_data_id, tags,\n persistence_slot_id, extra_data, creation_date, update_date\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17\n ) RETURNING data_id\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "data_id", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Text", - "Int4", - "Bytea", - "Int4", - "Int4Array", - "Int4", - "Int4Array", - "Int4", - "Int4", - "Int8", - "TextArray", - "Int4", - "TextArray", - "Timestamp", - "Timestamp" - ] - }, - "nullable": [ - false - ] - }, - "hash": "039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696" -} diff --git a/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json b/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json deleted file mode 100644 index abf5c03..0000000 --- a/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT owner, under_review FROM datastore.objects WHERE data_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "owner", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "under_review", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - true, - false - ] - }, - "hash": "164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9" -} diff --git a/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json b/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json deleted file mode 100644 index 7471873..0000000 --- a/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date,\n access_password, under_review\n FROM datastore.objects\n WHERE owner = $1 AND persistence_slot_id = $2\n AND upload_completed = TRUE AND deleted = FALSE", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "data_id", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "owner", - "type_info": "Int4" - }, - { - "ordinal": 2, - "name": "size", - "type_info": "Int4" - }, - { - "ordinal": 3, - "name": "name", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "data_type", - "type_info": "Int4" - }, - { - "ordinal": 5, - "name": "meta_binary", - "type_info": "Bytea" - }, - { - "ordinal": 6, - "name": "permission", - "type_info": "Int4" - }, - { - "ordinal": 7, - "name": "permission_recipients", - "type_info": "Int4Array" - }, - { - "ordinal": 8, - "name": "delete_permission", - "type_info": "Int4" - }, - { - "ordinal": 9, - "name": "delete_permission_recipients", - "type_info": "Int4Array" - }, - { - "ordinal": 10, - "name": "period", - "type_info": "Int4" - }, - { - "ordinal": 11, - "name": "refer_data_id", - "type_info": "Int8" - }, - { - "ordinal": 12, - "name": "flag", - "type_info": "Int4" - }, - { - "ordinal": 13, - "name": "tags", - "type_info": "TextArray" - }, - { - "ordinal": 14, - "name": "creation_date", - "type_info": "Timestamp" - }, - { - "ordinal": 15, - "name": "update_date", - "type_info": "Timestamp" - }, - { - "ordinal": 16, - "name": "access_password", - "type_info": "Int8" - }, - { - "ordinal": 17, - "name": "under_review", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Int4", - "Int4" - ] - }, - "nullable": [ - false, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - false, - false - ] - }, - "hash": "18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418" -} diff --git a/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json b/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json deleted file mode 100644 index 5411a38..0000000 --- a/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n INSERT INTO datastore.object_custom_rankings (data_id, application_id, value)\n VALUES ($1, $2, $3)\n ON CONFLICT (data_id, application_id)\n DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value\n ", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Int8" - ] - }, - "nullable": [] - }, - "hash": "29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695" -} diff --git a/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json b/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json deleted file mode 100644 index 83246ca..0000000 --- a/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "exists", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - null - ] - }, - "hash": "2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb" -} diff --git a/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json b/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json deleted file mode 100644 index 7a1cc6f..0000000 --- a/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT buffer\n FROM datastore.buffer_queues\n WHERE data_id = $1 AND slot = $2\n ORDER BY creation_date ASC\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "buffer", - "type_info": "Bytea" - } - ], - "parameters": { - "Left": [ - "Int8", - "Int4" - ] - }, - "nullable": [ - false - ] - }, - "hash": "48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763" -} diff --git a/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json b/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json deleted file mode 100644 index 4f07b49..0000000 --- a/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT under_review, access_password\n FROM datastore.objects\n WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "under_review", - "type_info": "Bool" - }, - { - "ordinal": 1, - "name": "access_password", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false, - false - ] - }, - "hash": "60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df" -} diff --git a/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json b/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json deleted file mode 100644 index 867701f..0000000 --- a/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n rankings.data_id,\n rankings.value\n FROM datastore.object_custom_rankings rankings\n JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord)\n ON rankings.data_id = rows.data_id\n AND rankings.application_id = $2\n ORDER BY rows.ord\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "data_id", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "value", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int8Array", - "Int8" - ] - }, - "nullable": [ - false, - true - ] - }, - "hash": "8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17" -} diff --git a/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json b/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json deleted file mode 100644 index 539fdeb..0000000 --- a/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date\n FROM datastore.objects WHERE data_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "data_id", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "owner", - "type_info": "Int4" - }, - { - "ordinal": 2, - "name": "size", - "type_info": "Int4" - }, - { - "ordinal": 3, - "name": "name", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "data_type", - "type_info": "Int4" - }, - { - "ordinal": 5, - "name": "meta_binary", - "type_info": "Bytea" - }, - { - "ordinal": 6, - "name": "permission", - "type_info": "Int4" - }, - { - "ordinal": 7, - "name": "permission_recipients", - "type_info": "Int4Array" - }, - { - "ordinal": 8, - "name": "delete_permission", - "type_info": "Int4" - }, - { - "ordinal": 9, - "name": "delete_permission_recipients", - "type_info": "Int4Array" - }, - { - "ordinal": 10, - "name": "period", - "type_info": "Int4" - }, - { - "ordinal": 11, - "name": "refer_data_id", - "type_info": "Int8" - }, - { - "ordinal": 12, - "name": "flag", - "type_info": "Int4" - }, - { - "ordinal": 13, - "name": "tags", - "type_info": "TextArray" - }, - { - "ordinal": 14, - "name": "creation_date", - "type_info": "Timestamp" - }, - { - "ordinal": 15, - "name": "update_date", - "type_info": "Timestamp" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "hash": "a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b" -} diff --git a/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json b/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json deleted file mode 100644 index 095ca6f..0000000 --- a/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT slot, total_value, count, initial_value\n FROM datastore.object_ratings\n WHERE data_id = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "slot", - "type_info": "Int2" - }, - { - "ordinal": 1, - "name": "total_value", - "type_info": "Int8" - }, - { - "ordinal": 2, - "name": "count", - "type_info": "Int4" - }, - { - "ordinal": 3, - "name": "initial_value", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false, - true, - false, - true - ] - }, - "hash": "c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa" -} diff --git a/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json b/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json deleted file mode 100644 index 552f92a..0000000 --- a/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [] - }, - "hash": "e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9" -} diff --git a/Cargo.lock b/Cargo.lock index 8fd84b8..bf83871 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2225,6 +2225,7 @@ dependencies = [ "tokio", "typenum", "ureq", + "urlencoding", "v-byte-helpers", ] diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 646b65e..620357b 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -33,6 +33,7 @@ aws-sdk-s3 = { version = "1.129.0", optional = true } aws-config = { version = "1.8.15", optional = true } base64 = "0.22.1" sha2 = "0.10.9" +urlencoding = "2.1.3" [dev-dependencies] # criterion = "0.7.0" diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index 19db2b4..498a75d 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -10,7 +10,7 @@ use rnex_core::nex::remote_console::RemoteConsole; use rnex_core::nex::s3presigner::S3Presigner; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::protocols::secure::{Secure, RawSecure, RawSecureInfo, RemoteSecure}; -use rnex_core::rmc::protocols::datastore::{BufferQueueParam, CompletePostParam, DataStoreCustomRankingResult, DataStoreGetCustomRankingByDataIDParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, RateCustomRankingParam, RatingInfo, RatingInfoWithSlot}; +use rnex_core::rmc::protocols::datastore::{BufferQueueParam, CompletePostParam, DataStoreCustomRankingResult, DataStoreGetCustomRankingByDataIDParam, DataStorePrepareGetParam, DataStoreReqGetInfo, DataStoreSearchParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, RateCustomRankingParam, RatingInfo, RatingInfoWithSlot}; use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore, PreparePostParam, ReqPostInfo}; use crate::nex::user::User; use rnex_core::executables::common::{RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db}; @@ -336,6 +336,7 @@ async fn get_custom_rankings_by_data_ids( if let Ok(meta) = get_object_info_by_data_id(data_id, 0).await { results.push(DataStoreCustomRankingResult { + order: 0, score, meta_info: meta, }); @@ -347,6 +348,70 @@ async fn get_custom_rankings_by_data_ids( results } +async fn get_user_course_object_ids(owner_pid: u32) -> Result, ErrorCode> { + let rows = sqlx::query!( + r#" + SELECT data_id + FROM datastore.objects + WHERE owner = $1 AND data_type > 2 AND data_type < 50 + "#, + owner_pid as i64 + ) + .fetch_all(get_db()) + .await + .map_err(|e| { + log::error!("error fetching course IDs for PID {}: {:?}", owner_pid, e); + ErrorCode::DataStore_SystemFileError + })?; + + let mut valid_ids = Vec::new(); + for row in rows { + let data_id = row.data_id as u64; + // always check avail + if check_object_availability(data_id, 0).await.is_ok() { + valid_ids.push(data_id); + } + } + + Ok(valid_ids) +} + +fn get_blacklist_1() -> Vec { + vec![ + "けされ", "消され", "削除され", "リセットされ", "BANされ", "BANされ", + "キミのコース", "君のコース", "きみのコース", "い い ね", "遊びます", "地震", + "震災", "被災", "津波", "バンされ", "い~ね", "震度", "じしん", "banされ", + "くわしくは", "詳しくは", "ちんちん", "ち0こ", "bicth", "い.い.ね", + "ナイ~ス", "い&い", "い-いね", "いぃね", "nigger", "ngger", "star if u", + "Star if u", "Star if you", "star if you", "PENlS", "マンコ", "butthole", + "LILI", "vagina", "vagyna", "うんち", "うんこ", "ウンコ", "Iine", + "EENE", "まんこ", "ウンチ", "niglet", "nigglet", "please like", "きんたま", + "Butthole", "llね", "iいね", "give a star", "ちんぽ", "亀頭", "penis", + "ウンコ", "plz more stars", "star plz", "い()ね", "PLEASE star", "Bitte Sterne", + ].into_iter().map(String::from).collect() +} + +fn get_blacklist_2() -> Vec { + vec![ + "ゼロから", "0から", "0から", "い  い  ね", "いい", "東日本", "大震", + ].into_iter().map(String::from).collect() +} + +fn get_blacklist_3() -> Vec { + vec![ + "いいね", "下さい", "ください", "押して", "おして", "返す", "かえす", + "星", "してくれ", "するよ", "☆くれたら", "☆あげます", "★くれたら", + "★あげます", "しね", "ころす", "ころされた", "アナル", "ファック", + "キンタマ", "○ね", "キチガイ", "うんこ", "KITIGAI", "金玉", "おっぱい", + "☆おす", "☆押す", "★おす", "★押す", "いいする", "いいよ", "イイネ", + "ケツ", "うんち", "かくせいざい", "覚せい剤", "シャブ", "きんたま", + "ちんちん", "おしっこ", "ちんぽこ", "ころして", "グッド", "グット", + "レ●プ", "バーカ", "きちがい", "ちんげ", "マンコ", "まんこ", "チンポ", + "クズ", "ウンコ", "ナイスおねがいします", "penis", "イイね", "☆よろ", + "ナイス!して", "ま/んこ", "まん/こ", + ].into_iter().map(String::from).collect() +} + impl DataStore for User { async fn get_meta(&self, mut metaparam: GetMetaParam) -> Result { let mut meta_info = if metaparam.dataid != 0 { @@ -429,6 +494,9 @@ impl DataStore for User { } async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode> { + log::info!("Data ID: {:?}", completeparam.dataid); + log::info!("Success: {:?}", completeparam.success); + let record = sqlx::query!( r#"SELECT owner, under_review FROM datastore.objects WHERE data_id = $1"#, completeparam.dataid as i64 @@ -469,10 +537,10 @@ impl DataStore for User { } async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode> { - for param in rankingparam { + for abcparam in rankingparam { let exists = sqlx::query_scalar!( r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#, - param.dataid as i64 + abcparam.dataid as i64 ) .fetch_one(get_db()) .await @@ -489,9 +557,9 @@ impl DataStore for User { ON CONFLICT (data_id, application_id) DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value "#, - param.dataid as i64, - param.appid as i32, - param.score as i32 + abcparam.dataid as i64, + abcparam.appid as i32, + abcparam.score as i32 ) .execute(get_db()) .await @@ -542,27 +610,30 @@ impl DataStore for User { async fn get_custom_ranking_by_data_id( &self, - param: DataStoreGetCustomRankingByDataIDParam + custom_ranking_param: DataStoreGetCustomRankingByDataIDParam ) -> Result<(Vec, Vec), ErrorCode> { + println!("appid: {:?}", custom_ranking_param.application_id); + println!("dataid list: {:?}", custom_ranking_param.data_id_list); + println!("result option: {:?}", custom_ranking_param.result_option); - let mut ranking_results = get_custom_rankings_by_data_ids(param.application_id, param.data_id_list).await; + let mut ranking_results = get_custom_rankings_by_data_ids(custom_ranking_param.application_id, custom_ranking_param.data_id_list).await; let mut q_results = Vec::with_capacity(ranking_results.len()); for result in &mut ranking_results { - if (param.result_option & 0x01) == 0 { + if (custom_ranking_param.result_option & 0x01) == 0 { result.meta_info.tags = Vec::new(); } - if (param.result_option & 0x02) == 0 { + if (custom_ranking_param.result_option & 0x02) == 0 { result.meta_info.ratings = Vec::new(); } - if (param.result_option & 0x04) == 0 { + if (custom_ranking_param.result_option & 0x04) == 0 { result.meta_info.meta_binary = QBuffer(Vec::new()); } - if (param.result_option & 0x20) == 0 { + if (custom_ranking_param.result_option & 0x20) == 0 { result.score = 0; } @@ -572,11 +643,138 @@ impl DataStore for User { Ok((ranking_results, q_results)) } - async fn get_buffer_queue(&self, param: BufferQueueParam) -> Result, ErrorCode> { + async fn get_buffer_queue(&self, bufferparam: BufferQueueParam) -> Result, ErrorCode> { // log::info!("GetBufferQueue: dataid={}, slot={}", param.dataid, param.slot); - let buffers = get_buffer_queues_by_data_id_and_slot(param.dataid, param.slot).await?; + let buffers = get_buffer_queues_by_data_id_and_slot(bufferparam.dataid, bufferparam.slot).await?; Ok(buffers) } + + async fn prepare_get_object(&self, prepare_get_param: DataStorePrepareGetParam) -> Result { + let meta_info = if prepare_get_param.dataid != 0 { + get_object_info_by_data_id(prepare_get_param.dataid, prepare_get_param.access_password).await? + } else { + get_object_info_by_persistence_target(prepare_get_param.persistence_target, prepare_get_param.access_password).await? + }; + + verify_object_permission(meta_info.owner, self.pid, &meta_info.permission)?; + + let presigner = S3Presigner::new( + &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), + format!("{}", *RNEX_DATASTORE_S3_BUCKET) + ).await; + + let key = format!("data/{}.bin", meta_info.dataid); + let download_url = presigner.generate_presigned_get(&key); + + Ok(DataStoreReqGetInfo { + url: download_url, + request_headers: vec![], + size: meta_info.size, + root_ca_cert: vec![], + dataid: meta_info.dataid, + }) + } + + async fn followings_latest_course_search_object( + &self, + course_search_param: DataStoreSearchParam, + _extra_data: Vec + ) -> Result, ErrorCode> { + let mut all_results = Vec::new(); + + for &owner_pid in &course_search_param.owner_ids { + let course_ids = get_user_course_object_ids(owner_pid).await?; + + if course_ids.is_empty() { + continue; + } + + let mut results = get_custom_rankings_by_data_ids(0, course_ids).await; + + // Flag 0x1: Return Tags + // Flag 0x2: Return Ratings + // Flag 0x4: Return MetaBinary + // Flag 0x20: Return Score + for res in &mut results { + if course_search_param.result_option & 0x1 == 0 { + res.meta_info.tags = Vec::new(); + } + if course_search_param.result_option & 0x2 == 0 { + res.meta_info.ratings = Vec::new(); + } + if course_search_param.result_option & 0x4 == 0 { + res.meta_info.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); + } + if course_search_param.result_option & 0x20 == 0 { + res.score = 0; + } + } + + all_results.extend(results); + } + + // note: we assume the client sorts the data lol + + Ok(all_results) + } + + async fn get_application_config_string(&self, application_id: u32) -> Result, ErrorCode> { + let config = match application_id { + 128 => get_blacklist_1(), + 129 => get_blacklist_2(), + 130 => get_blacklist_3(), + _ => { + log::warn!("unsupported application_id in GetApplicationConfigString: {}", application_id); + Vec::new() + } + }; + + Ok(config) + } + + async fn get_metas_multiple_param( + &self, + params: Vec + ) -> Result<(Vec, Vec), ErrorCode> { + let mut metas = Vec::with_capacity(params.len()); + let mut results = Vec::with_capacity(params.len()); + + for param in params { + let info_result = if param.dataid != 0 { + get_object_info_by_data_id(param.dataid, param.access_password).await + } else { + get_object_info_by_persistence_target(param.persistence_target, param.access_password).await + }; + + match info_result { + Ok(mut meta) => { + if let Err(e) = verify_object_permission(meta.owner, self.pid, &meta.permission) { + metas.push(GetMetaInfo::default()); + results.push(QResult::error(e)); + } else { + if param.result_option & 0x1 == 0 { + meta.tags = Vec::new(); + } + if param.result_option & 0x2 == 0 { + meta.ratings = Vec::new(); + } + if param.result_option & 0x4 == 0 { + meta.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); + } + + metas.push(meta); + results.push(QResult::success(ErrorCode::Core_Unknown)); + } + } + Err(e) => { + metas.push(GetMetaInfo::default()); + results.push(QResult::error(e)); + } + } + } + + Ok((metas, results)) + } } \ No newline at end of file diff --git a/rnex-core/src/nex/s3presigner.rs b/rnex-core/src/nex/s3presigner.rs index 169293b..afe61d4 100644 --- a/rnex-core/src/nex/s3presigner.rs +++ b/rnex-core/src/nex/s3presigner.rs @@ -56,6 +56,50 @@ impl S3Presigner { (url, fields) } + pub fn generate_presigned_get(&self, key: &str) -> String { + let access_key = std::env::var("AWS_ACCESS_KEY_ID").expect("Missing Access Key"); + let secret_key = std::env::var("AWS_SECRET_ACCESS_KEY").expect("Missing Secret Key"); + let region = "us-east-1"; + let date_short = Utc::now().format("%Y%m%d").to_string(); + let date_full = Utc::now().format("%Y%m%dT%H%M%SZ").to_string(); + + let credential_scope = format!("{}/{}/s3/aws4_request", date_short, region); + + let query_string = format!( + "X-Amz-Algorithm=AWS4-HMAC-SHA256&\ + X-Amz-Credential={}%2F{}&\ + X-Amz-Date={}&\ + X-Amz-Expires=900&\ + X-Amz-SignedHeaders=host", + access_key, + urlencoding::encode(&credential_scope), + date_full + ); + + let canonical_request = format!( + "GET\n/{}/{}\n{}\nhost:{}\n\nhost\nUNSIGNED-PAYLOAD", + self.bucket, key, query_string, *RNEX_DATASTORE_S3_ENDPOINT + ); + + let hashed_request = hex::encode(Sha256::digest(canonical_request.as_bytes())); + + let string_to_sign = format!( + "AWS4-HMAC-SHA256\n{}\n{}\n{}", + date_full, credential_scope, hashed_request + ); + + let k_date = self.hmac_sha256(format!("AWS4{}", secret_key).as_bytes(), &date_short); + let k_region = self.hmac_sha256(&k_date, region); + let k_service = self.hmac_sha256(&k_region, "s3"); + let k_signing = self.hmac_sha256(&k_service, "aws4_request"); + let signature = hex::encode(self.hmac_sha256(&k_signing, &string_to_sign)); + + format!( + "https://{}/{}/{}?{}&X-Amz-Signature={}", + *RNEX_DATASTORE_S3_ENDPOINT, self.bucket, key, query_string, signature + ) + } + fn calculate_signature(&self, secret: &str, date: &str, region: &str, policy: &str) -> String { let k_date = self.hmac_sha256(format!("AWS4{}", secret).as_bytes(), date); let k_region = self.hmac_sha256(&k_date, region); diff --git a/rnex-core/src/rmc/protocols/datastore.rs b/rnex-core/src/rmc/protocols/datastore.rs index 00e522f..0c68fc5 100644 --- a/rnex-core/src/rmc/protocols/datastore.rs +++ b/rnex-core/src/rmc/protocols/datastore.rs @@ -4,15 +4,16 @@ use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::qresult::QResult; use rnex_core::kerberos::KerberosDateTime; use rnex_core::PID; +use rnex_core::rmc::structures::resultsrange::ResultsRange; -#[derive(RmcSerialize, Clone, Debug)] +#[derive(RmcSerialize, Clone, Debug, Default)] #[rmc_struct(0)] pub struct PersistenceTarget { pub owner: PID, pub persistence_slot_id: u16, } -#[derive(RmcSerialize, Clone, Debug)] +#[derive(RmcSerialize, Clone, Debug, Default)] #[rmc_struct(0)] pub struct Permission { pub permission: u8, @@ -34,7 +35,7 @@ pub struct RatingInfo { pub initial_value: i64, } -#[derive(RmcSerialize, Clone)] +#[derive(RmcSerialize, Clone, Default)] #[rmc_struct(0)] pub struct GetMetaParam { pub dataid: u64, @@ -43,7 +44,7 @@ pub struct GetMetaParam { pub access_password: u64, } -#[derive(RmcSerialize, Clone)] +#[derive(RmcSerialize, Clone, Default)] #[rmc_struct(0)] pub struct GetMetaInfo { pub dataid: u64, @@ -165,14 +166,59 @@ pub struct DataStoreGetCustomRankingByDataIDParam { #[derive(RmcSerialize, Clone)] #[rmc_struct(0)] pub struct DataStoreCustomRankingResult { + pub order: u32, pub score: u32, pub meta_info: GetMetaInfo, } +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct DataStorePrepareGetParam { + pub dataid: u64, + pub lockid: u32, + pub persistence_target: PersistenceTarget, + pub access_password: u64, + pub extra_data: Vec, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(0)] +pub struct DataStoreReqGetInfo { + pub url: String, + pub request_headers: Vec, + pub size: u32, + pub root_ca_cert: Vec, + pub dataid: u64, +} + +#[derive(RmcSerialize, Clone)] +#[rmc_struct(1)] +pub struct DataStoreSearchParam { + pub search_target: u8, + pub owner_ids: Vec, + pub owner_type: u8, + pub destination_ids: Vec, + pub data_type: u16, + pub created_after: KerberosDateTime, + pub created_before: KerberosDateTime, + pub updated_after: KerberosDateTime, + pub updated_before: KerberosDateTime, + pub refer_dat_id: u32, + pub tags: Vec, + pub result_order_column: u8, + pub result_order: u8, + pub result_range: ResultsRange, + pub result_option: u8, + pub minimal_rating_frequency: u32, + pub use_cache: bool, +} + #[rmc_proto(115)] pub trait DataStore{ #[method_id(8)] async fn get_meta(&self, metaparam: GetMetaParam) -> Result; + #[method_id(36)] + async fn get_metas_multiple_param(&self, params: Vec) -> Result<(Vec, Vec), ErrorCode>; #[method_id(24)] async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result; #[method_id(26)] @@ -182,7 +228,13 @@ pub trait DataStore{ #[method_id(61)] async fn get_application_config(&self, appid: u32) -> Result, ErrorCode>; #[method_id(50)] - async fn get_custom_ranking_by_data_id(&self, param: DataStoreGetCustomRankingByDataIDParam) -> Result<(Vec, Vec), ErrorCode>; + async fn get_custom_ranking_by_data_id(&self, custom_ranking_param: DataStoreGetCustomRankingByDataIDParam) -> Result<(Vec, Vec), ErrorCode>; #[method_id(54)] - async fn get_buffer_queue(&self, param: BufferQueueParam) -> Result, ErrorCode>; + async fn get_buffer_queue(&self, bufferparam: BufferQueueParam) -> Result, ErrorCode>; + #[method_id(25)] + async fn prepare_get_object(&self, prepare_get_param: DataStorePrepareGetParam) -> Result; + #[method_id(65)] + async fn followings_latest_course_search_object(&self, course_search_param: DataStoreSearchParam, extra_data: Vec) -> Result, ErrorCode>; + #[method_id(74)] + async fn get_application_config_string(&self, application_id: u32) -> Result, ErrorCode>; } \ No newline at end of file diff --git a/rnex-core/src/rmc/protocols/ranking.rs b/rnex-core/src/rmc/protocols/ranking.rs index b9dba06..53ec9af 100644 --- a/rnex-core/src/rmc/protocols/ranking.rs +++ b/rnex-core/src/rmc/protocols/ranking.rs @@ -2,17 +2,10 @@ use macros::{rmc_struct, rmc_proto, RmcSerialize, method_id}; use rnex_core::kerberos::KerberosDateTime; use rnex_core::rmc::structures::qbuffer::QBuffer; - +use rnex_core::rmc::structures::resultsrange::ResultsRange; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::ranking::UploadCompetitionData; -#[derive(RmcSerialize, Debug, Default, Clone)] -#[rmc_struct(0)] -pub struct ResultsRange{ - pub offset: u32, - pub size: u32 -} - #[derive(RmcSerialize, Debug, Default, Clone)] #[rmc_struct(1)] pub struct CompetitionRankingGetParam { diff --git a/rnex-core/src/rmc/structures/mod.rs b/rnex-core/src/rmc/structures/mod.rs index 996cc4b..459aeac 100644 --- a/rnex-core/src/rmc/structures/mod.rs +++ b/rnex-core/src/rmc/structures/mod.rs @@ -37,6 +37,7 @@ pub mod ranking; pub mod rmc_struct; pub mod string; pub mod variant; +pub mod resultsrange; pub trait RmcSerialize { fn serialize(&self, writer: &mut impl Write) -> Result<()>; diff --git a/rnex-core/src/rmc/structures/qbuffer.rs b/rnex-core/src/rmc/structures/qbuffer.rs index 2f7b23a..7f2aa7b 100644 --- a/rnex-core/src/rmc/structures/qbuffer.rs +++ b/rnex-core/src/rmc/structures/qbuffer.rs @@ -3,7 +3,7 @@ use bytemuck::bytes_of; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::rmc::structures::{Result, RmcSerialize}; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct QBuffer(pub Vec); impl RmcSerialize for QBuffer{ diff --git a/rnex-core/src/rmc/structures/resultsrange.rs b/rnex-core/src/rmc/structures/resultsrange.rs new file mode 100644 index 0000000..ba62e49 --- /dev/null +++ b/rnex-core/src/rmc/structures/resultsrange.rs @@ -0,0 +1,8 @@ +use macros::RmcSerialize; + +#[derive(RmcSerialize, Debug, Default, Clone)] +#[rmc_struct(0)] +pub struct ResultsRange{ + pub offset: u32, + pub size: u32 +} \ No newline at end of file From 20ee0e20dc3ed9def60865aac0353fda2d20d946 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 21 Apr 2026 20:36:51 +0200 Subject: [PATCH 090/203] add super mario maker to CI --- .gitlab-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 900885c..7b9a013 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,3 +24,7 @@ splatoon: friends: stage: build_and_test script: ./.ci-scripts/make-edition.sh friends + +super-mario-maker: + stage: build_and_test + script: ./.ci-scripts/make-edition.sh super-mario-maker From e5a0b374922887c8c99f888bd354050a95539280 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 21 Apr 2026 20:46:38 +0200 Subject: [PATCH 091/203] sqlx prepare --- ...0f608f018cb20125bf0ed30fdfb4319a14cf0.json | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 rnex-core/.sqlx/query-74408b6923370db5de1589b62360f608f018cb20125bf0ed30fdfb4319a14cf0.json diff --git a/rnex-core/.sqlx/query-74408b6923370db5de1589b62360f608f018cb20125bf0ed30fdfb4319a14cf0.json b/rnex-core/.sqlx/query-74408b6923370db5de1589b62360f608f018cb20125bf0ed30fdfb4319a14cf0.json new file mode 100644 index 0000000..775d98d --- /dev/null +++ b/rnex-core/.sqlx/query-74408b6923370db5de1589b62360f608f018cb20125bf0ed30fdfb4319a14cf0.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT data_id\n FROM datastore.objects\n WHERE owner = $1 AND data_type > 2 AND data_type < 50\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int4" + ] + }, + "nullable": [ + false + ] + }, + "hash": "74408b6923370db5de1589b62360f608f018cb20125bf0ed30fdfb4319a14cf0" +} From 49dab174cc3aa2c2dbbf4adf5f352f91505f04fe Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 21 Apr 2026 21:00:13 +0200 Subject: [PATCH 092/203] revert build-edition to normal, and try to allow normal builds to succeed --- build-edition.sh | 4 +- ...b44a630eb066846c777c462b8c9341e26b696.json | 38 - ...f67d1812b99e1ec952a044fc03e1a5c63703.json} | 4 +- ...a1675439bb44c91158f8b8a696e326c45447c.json | 38 + ...57f27247530878b7f82feeb65802d995a38c4.json | 16 + ...88d2d26f7644e85bfd65423e6e32c469e3695.json | 16 - ...1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json} | 4 +- ...02e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json} | 4 +- ...8a7a9bf551126712c1d1089a4263453090e79.json | 29 + ...1340561031d8e5c91f46c041f83e54c31a7d.json} | 4 +- ...8be8946430d93821dbccb6dc9324ef0544c17.json | 29 - ...8f5eb4a3761dd71129ba6939cdd0d62569fb.json} | 4 +- ...cecccf8f0f8dd20d890a76acf85265b2192c.json} | 4 +- rnex-core/src/nex/datastore.rs | 1479 +++++++++-------- 14 files changed, 838 insertions(+), 835 deletions(-) delete mode 100644 rnex-core/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json rename rnex-core/.sqlx/{query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json => query-1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703.json} (85%) create mode 100644 rnex-core/.sqlx/query-219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c.json create mode 100644 rnex-core/.sqlx/query-29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4.json delete mode 100644 rnex-core/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json rename rnex-core/.sqlx/{query-74408b6923370db5de1589b62360f608f018cb20125bf0ed30fdfb4319a14cf0.json => query-37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json} (51%) rename rnex-core/.sqlx/{query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json => query-3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json} (50%) create mode 100644 rnex-core/.sqlx/query-8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79.json rename rnex-core/.sqlx/{query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json => query-8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d.json} (69%) delete mode 100644 rnex-core/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json rename rnex-core/.sqlx/{query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json => query-93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb.json} (57%) rename rnex-core/.sqlx/{query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json => query-efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c.json} (81%) diff --git a/build-edition.sh b/build-edition.sh index d2c0750..5d65fc3 100755 --- a/build-edition.sh +++ b/build-edition.sh @@ -10,6 +10,4 @@ echo $EDITION_FEATURES echo ENV SETTINGS: env -#OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl -OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 cargo sqlx prepare --workspace -- --features "$EDITION_FEATURES" -OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 cargo build --release --features "$EDITION_FEATURES" +OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl diff --git a/rnex-core/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json b/rnex-core/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json deleted file mode 100644 index f91446a..0000000 --- a/rnex-core/.sqlx/query-039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n INSERT INTO datastore.objects (\n owner, size, name, data_type, meta_binary,\n permission, permission_recipients,\n delete_permission, delete_permission_recipients,\n flag, period, refer_data_id, tags,\n persistence_slot_id, extra_data, creation_date, update_date\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17\n ) RETURNING data_id\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "data_id", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Text", - "Int4", - "Bytea", - "Int4", - "Int4Array", - "Int4", - "Int4Array", - "Int4", - "Int4", - "Int8", - "TextArray", - "Int4", - "TextArray", - "Timestamp", - "Timestamp" - ] - }, - "nullable": [ - false - ] - }, - "hash": "039d134f0d1b681b55b1394a710b44a630eb066846c777c462b8c9341e26b696" -} diff --git a/rnex-core/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json b/rnex-core/.sqlx/query-1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703.json similarity index 85% rename from rnex-core/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json rename to rnex-core/.sqlx/query-1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703.json index 539fdeb..befa7e1 100644 --- a/rnex-core/.sqlx/query-a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b.json +++ b/rnex-core/.sqlx/query-1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date\n FROM datastore.objects WHERE data_id = $1", + "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date\n FROM datastore.objects WHERE data_id = $1", "describe": { "columns": [ { @@ -108,5 +108,5 @@ true ] }, - "hash": "a5e86d7e66d0e16e5f35df883e11d9f4ef96adbdab7ca7d008acf596af91fc2b" + "hash": "1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703" } diff --git a/rnex-core/.sqlx/query-219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c.json b/rnex-core/.sqlx/query-219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c.json new file mode 100644 index 0000000..cf80412 --- /dev/null +++ b/rnex-core/.sqlx/query-219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO datastore.objects (\n owner, size, name, data_type, meta_binary,\n permission, permission_recipients,\n delete_permission, delete_permission_recipients,\n flag, period, refer_data_id, tags,\n persistence_slot_id, extra_data, creation_date, update_date\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17\n ) RETURNING data_id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int4", + "Int4", + "Text", + "Int4", + "Bytea", + "Int4", + "Int4Array", + "Int4", + "Int4Array", + "Int4", + "Int4", + "Int8", + "TextArray", + "Int4", + "TextArray", + "Timestamp", + "Timestamp" + ] + }, + "nullable": [ + false + ] + }, + "hash": "219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c" +} diff --git a/rnex-core/.sqlx/query-29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4.json b/rnex-core/.sqlx/query-29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4.json new file mode 100644 index 0000000..0c3393d --- /dev/null +++ b/rnex-core/.sqlx/query-29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO datastore.object_custom_rankings (data_id, application_id, value)\n VALUES ($1, $2, $3)\n ON CONFLICT (data_id, application_id)\n DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Int8", + "Int8" + ] + }, + "nullable": [] + }, + "hash": "29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4" +} diff --git a/rnex-core/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json b/rnex-core/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json deleted file mode 100644 index 5411a38..0000000 --- a/rnex-core/.sqlx/query-29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n INSERT INTO datastore.object_custom_rankings (data_id, application_id, value)\n VALUES ($1, $2, $3)\n ON CONFLICT (data_id, application_id)\n DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value\n ", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Int8" - ] - }, - "nullable": [] - }, - "hash": "29e18f241dc860dca12c03cabb788d2d26f7644e85bfd65423e6e32c469e3695" -} diff --git a/rnex-core/.sqlx/query-74408b6923370db5de1589b62360f608f018cb20125bf0ed30fdfb4319a14cf0.json b/rnex-core/.sqlx/query-37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json similarity index 51% rename from rnex-core/.sqlx/query-74408b6923370db5de1589b62360f608f018cb20125bf0ed30fdfb4319a14cf0.json rename to rnex-core/.sqlx/query-37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json index 775d98d..35c78ee 100644 --- a/rnex-core/.sqlx/query-74408b6923370db5de1589b62360f608f018cb20125bf0ed30fdfb4319a14cf0.json +++ b/rnex-core/.sqlx/query-37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT data_id\n FROM datastore.objects\n WHERE owner = $1 AND data_type > 2 AND data_type < 50\n ", + "query": "\n SELECT data_id\n FROM datastore.objects\n WHERE owner = $1 AND data_type > 2 AND data_type < 50\n ", "describe": { "columns": [ { @@ -18,5 +18,5 @@ false ] }, - "hash": "74408b6923370db5de1589b62360f608f018cb20125bf0ed30fdfb4319a14cf0" + "hash": "37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92" } diff --git a/rnex-core/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json b/rnex-core/.sqlx/query-3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json similarity index 50% rename from rnex-core/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json rename to rnex-core/.sqlx/query-3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json index 7a1cc6f..166c25d 100644 --- a/rnex-core/.sqlx/query-48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763.json +++ b/rnex-core/.sqlx/query-3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT buffer\n FROM datastore.buffer_queues\n WHERE data_id = $1 AND slot = $2\n ORDER BY creation_date ASC\n ", + "query": "\n SELECT buffer\n FROM datastore.buffer_queues\n WHERE data_id = $1 AND slot = $2\n ORDER BY creation_date ASC\n ", "describe": { "columns": [ { @@ -19,5 +19,5 @@ false ] }, - "hash": "48d94383f1a261f19060f5c75d9f7803ee88233c53efaa2df9966a6c72c8c763" + "hash": "3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f" } diff --git a/rnex-core/.sqlx/query-8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79.json b/rnex-core/.sqlx/query-8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79.json new file mode 100644 index 0000000..dd1c783 --- /dev/null +++ b/rnex-core/.sqlx/query-8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79.json @@ -0,0 +1,29 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n rankings.data_id,\n rankings.value\n FROM datastore.object_custom_rankings rankings\n JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord)\n ON rankings.data_id = rows.data_id\n AND rankings.application_id = $2\n ORDER BY rows.ord\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "value", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8Array", + "Int8" + ] + }, + "nullable": [ + false, + true + ] + }, + "hash": "8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79" +} diff --git a/rnex-core/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json b/rnex-core/.sqlx/query-8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d.json similarity index 69% rename from rnex-core/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json rename to rnex-core/.sqlx/query-8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d.json index 095ca6f..dbab55e 100644 --- a/rnex-core/.sqlx/query-c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa.json +++ b/rnex-core/.sqlx/query-8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT slot, total_value, count, initial_value\n FROM datastore.object_ratings\n WHERE data_id = $1\n ", + "query": "\n SELECT slot, total_value, count, initial_value\n FROM datastore.object_ratings\n WHERE data_id = $1\n ", "describe": { "columns": [ { @@ -36,5 +36,5 @@ true ] }, - "hash": "c2a0ca72fdcb060a7fb1c670b25e1efdbf3cef31e4b6cea4adbd51ee0218f5aa" + "hash": "8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d" } diff --git a/rnex-core/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json b/rnex-core/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json deleted file mode 100644 index 867701f..0000000 --- a/rnex-core/.sqlx/query-8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n rankings.data_id,\n rankings.value\n FROM datastore.object_custom_rankings rankings\n JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord)\n ON rankings.data_id = rows.data_id\n AND rankings.application_id = $2\n ORDER BY rows.ord\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "data_id", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "value", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int8Array", - "Int8" - ] - }, - "nullable": [ - false, - true - ] - }, - "hash": "8909f81fbf26a9b559d26e138568be8946430d93821dbccb6dc9324ef0544c17" -} diff --git a/rnex-core/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json b/rnex-core/.sqlx/query-93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb.json similarity index 57% rename from rnex-core/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json rename to rnex-core/.sqlx/query-93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb.json index 4f07b49..0a8127b 100644 --- a/rnex-core/.sqlx/query-60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df.json +++ b/rnex-core/.sqlx/query-93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n SELECT under_review, access_password\n FROM datastore.objects\n WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE\n ", + "query": "\n SELECT under_review, access_password\n FROM datastore.objects\n WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE\n ", "describe": { "columns": [ { @@ -24,5 +24,5 @@ false ] }, - "hash": "60d8ebcf914d887439096df400fa4beaf37e879c28c81c22abeddb3d030535df" + "hash": "93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb" } diff --git a/rnex-core/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json b/rnex-core/.sqlx/query-efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c.json similarity index 81% rename from rnex-core/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json rename to rnex-core/.sqlx/query-efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c.json index 7471873..60714c0 100644 --- a/rnex-core/.sqlx/query-18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418.json +++ b/rnex-core/.sqlx/query-efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date,\n access_password, under_review\n FROM datastore.objects\n WHERE owner = $1 AND persistence_slot_id = $2\n AND upload_completed = TRUE AND deleted = FALSE", + "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date,\n access_password, under_review\n FROM datastore.objects\n WHERE owner = $1 AND persistence_slot_id = $2\n AND upload_completed = TRUE AND deleted = FALSE", "describe": { "columns": [ { @@ -121,5 +121,5 @@ false ] }, - "hash": "18fb671d9d97353420446413b74077f9b06ffe11cab2693e4e365c265f8e2418" + "hash": "efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c" } diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index 498a75d..763bc3e 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -1,780 +1,785 @@ -use crate::define_rmc_proto; -use macros::rmc_struct; -use rnex_core::prudp::socket_addr::PRUDPSockAddr; -use std::sync::{Weak}; -use chrono::Utc; -use sqlx::types::time; -use sqlx::types::time::PrimitiveDateTime; -use rnex_core::PID; -use rnex_core::nex::remote_console::RemoteConsole; -use rnex_core::nex::s3presigner::S3Presigner; -use rnex_core::rmc::response::ErrorCode; -use rnex_core::rmc::protocols::secure::{Secure, RawSecure, RawSecureInfo, RemoteSecure}; -use rnex_core::rmc::protocols::datastore::{BufferQueueParam, CompletePostParam, DataStoreCustomRankingResult, DataStoreGetCustomRankingByDataIDParam, DataStorePrepareGetParam, DataStoreReqGetInfo, DataStoreSearchParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, RateCustomRankingParam, RatingInfo, RatingInfoWithSlot}; -use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore, PreparePostParam, ReqPostInfo}; -use crate::nex::user::User; -use rnex_core::executables::common::{RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db}; -use rnex_core::rmc::structures::qbuffer::QBuffer; -use sqlx::types::chrono::DateTime; -use rnex_core::kerberos::KerberosDateTime; -use rnex_core::rmc::structures::qresult::QResult; +use cfg_if::cfg_if; +cfg_if! { + if #[cfg(feature = "datastore")] { + use crate::define_rmc_proto; + use macros::rmc_struct; + use rnex_core::prudp::socket_addr::PRUDPSockAddr; + use std::sync::{Weak}; + use chrono::Utc; + use sqlx::types::time; + use sqlx::types::time::PrimitiveDateTime; + use rnex_core::PID; + use rnex_core::nex::remote_console::RemoteConsole; + use rnex_core::nex::s3presigner::S3Presigner; + use rnex_core::rmc::response::ErrorCode; + use rnex_core::rmc::protocols::secure::{Secure, RawSecure, RawSecureInfo, RemoteSecure}; + use rnex_core::rmc::protocols::datastore::{BufferQueueParam, CompletePostParam, DataStoreCustomRankingResult, DataStoreGetCustomRankingByDataIDParam, DataStorePrepareGetParam, DataStoreReqGetInfo, DataStoreSearchParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, RateCustomRankingParam, RatingInfo, RatingInfoWithSlot}; + use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore, PreparePostParam, ReqPostInfo}; + use crate::nex::user::User; + use rnex_core::executables::common::{RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db}; + use rnex_core::rmc::structures::qbuffer::QBuffer; + use sqlx::types::chrono::DateTime; + use rnex_core::kerberos::KerberosDateTime; + use rnex_core::rmc::structures::qresult::QResult; -fn map_row_to_meta_info( - row_data_id: i64, - row_owner: i32, - row_size: i32, - row_name: String, - row_data_type: i16, - row_meta_binary: Vec, - row_permission: i16, - row_permission_recipients: Vec, - row_delete_permission: i16, - row_delete_permission_recipients: Vec, - row_period: i16, - row_refer_data_id: i64, - row_flag: i32, - row_tags: Vec, - row_creation_date: chrono::NaiveDateTime, - row_update_date: chrono::NaiveDateTime, - ratings: Vec -) -> GetMetaInfo { - GetMetaInfo { - dataid: row_data_id as u64, - owner: row_owner as u32, - size: row_size as u32, - name: row_name, - data_type: row_data_type as u16, - meta_binary: QBuffer(row_meta_binary), - permission: Permission { - permission: row_permission as u8, - recipient_ids: row_permission_recipients.into_iter().map(|id| id as u32).collect(), - }, - del_permission: Permission { - permission: row_delete_permission as u8, - recipient_ids: row_delete_permission_recipients.into_iter().map(|id| id as u32).collect(), - }, - period: row_period as u16, - status: 0, - referred_count: 0, - refer_dat_id: row_refer_data_id as u32, - flag: row_flag as u32, - tags: row_tags, - expire_time: KerberosDateTime::from_u64(0x9C3F3E0000), - created_time: KerberosDateTime::from_naive(row_creation_date), - updated_time: KerberosDateTime::from_naive(row_update_date), - referred_time: KerberosDateTime::from_naive(row_creation_date), - ratings, - } -} - -async fn check_object_availability(data_id: u64, password: u64) -> Result<(), ErrorCode> { - let row = sqlx::query!( - r#" - SELECT under_review, access_password - FROM datastore.objects - WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE - "#, - data_id as i64 - ) - .fetch_optional(get_db()) - .await - .map_err(|e| { - eprintln!("Availability check DB error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })? - .ok_or(ErrorCode::DataStore_NotFound)?; - - let access_password = row.access_password as u64; - if access_password != 0 && access_password != password { - return Err(ErrorCode::DataStore_InvalidPassword); - } - - if row.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } - - Ok(()) -} - -async fn get_object_ratings(data_id: u64, password: u64) -> Result, ErrorCode> { - check_object_availability(data_id, password).await?; - - let rows = sqlx::query!( - r#" - SELECT slot, total_value, count, initial_value - FROM datastore.object_ratings - WHERE data_id = $1 - "#, - data_id as i64 - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - eprintln!("Ratings fetch error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; - - let ratings = rows.into_iter().map(|row| { - RatingInfoWithSlot { - slot: row.slot as i8, - rating: RatingInfo { - total_value: row.total_value.unwrap_or(0), - count: row.count as u32, - initial_value: row.initial_value.unwrap_or(0), - }, - } - }).collect(); - - Ok(ratings) -} - -async fn get_object_info_by_data_id(data_id: u64, password: u64) -> Result { - check_object_availability(data_id, password).await?; - - let row = sqlx::query!( - r#"SELECT data_id, owner, size, name, data_type, meta_binary, - permission, permission_recipients, delete_permission, delete_permission_recipients, - period, refer_data_id, flag, tags, creation_date, update_date - FROM datastore.objects WHERE data_id = $1"#, - data_id as i64 - ) - .fetch_optional(get_db()) - .await - .map_err(|_| ErrorCode::DataStore_SystemFileError)? - .ok_or(ErrorCode::DataStore_NotFound)?; - - let ratings = get_object_ratings(data_id, password).await?; - - Ok(map_row_to_meta_info( - row.data_id, - row.owner.unwrap_or(0), - row.size.unwrap_or(0), - row.name.unwrap_or_default(), - row.data_type.unwrap_or(0) as i16, - row.meta_binary.unwrap_or_default(), - row.permission.unwrap_or(0) as i16, - row.permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), - row.delete_permission.unwrap_or(0) as i16, - row.delete_permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), - row.period.unwrap_or(0) as i16, - row.refer_data_id.unwrap_or(0), - row.flag.unwrap_or(0), - row.tags.unwrap_or_default(), - row.creation_date.map(|dt| chrono::NaiveDateTime::new( - chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), - chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() - )).unwrap_or_default(), - row.update_date.map(|dt| chrono::NaiveDateTime::new( - chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), - chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() - )).unwrap_or_default(), - ratings - )) -} - -async fn get_object_info_by_persistence_target(target: PersistenceTarget, password: u64) -> Result { - let row = sqlx::query!( - r#"SELECT data_id, owner, size, name, data_type, meta_binary, - permission, permission_recipients, delete_permission, delete_permission_recipients, - period, refer_data_id, flag, tags, creation_date, update_date, - access_password, under_review - FROM datastore.objects - WHERE owner = $1 AND persistence_slot_id = $2 - AND upload_completed = TRUE AND deleted = FALSE"#, - target.owner as i32, - target.persistence_slot_id as i16 - ) - .fetch_optional(get_db()) - .await - .map_err(|_| ErrorCode::DataStore_SystemFileError)? - .ok_or(ErrorCode::DataStore_NotFound)?; - - let db_password = row.access_password as u64; - if db_password != 0 && db_password != password { - return Err(ErrorCode::DataStore_InvalidPassword); - } - - if row.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } - - let ratings = get_object_ratings(row.data_id as u64, password).await?; - - Ok(map_row_to_meta_info( - row.data_id, - row.owner.unwrap_or(0), - row.size.unwrap_or(0), - row.name.unwrap_or_default(), - row.data_type.unwrap_or(0) as i16, - row.meta_binary.unwrap_or_default(), - row.permission.unwrap_or(0) as i16, - row.permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), - row.delete_permission.unwrap_or(0) as i16, - row.delete_permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), - row.period.unwrap_or(0) as i16, - row.refer_data_id.unwrap_or(0), - row.flag.unwrap_or(0), - row.tags.unwrap_or_default(), - row.creation_date.map(|dt| chrono::NaiveDateTime::new( - chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), - chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() - )).unwrap_or_default(), - row.update_date.map(|dt| chrono::NaiveDateTime::new( - chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), - chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() - )).unwrap_or_default(), - ratings - )) -} - -async fn get_buffer_queues_by_data_id_and_slot( - data_id: u64, - slot: u32 -) -> Result, ErrorCode> { - check_object_availability(data_id, 0).await?; - - let rows = sqlx::query!( - r#" - SELECT buffer - FROM datastore.buffer_queues - WHERE data_id = $1 AND slot = $2 - ORDER BY creation_date ASC - "#, - data_id as i64, - slot as i32 - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - log::error!("Buffer queue fetch error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; - - let buffer_queues = rows - .into_iter() - .map(|row| QBuffer(row.buffer)) - .collect(); - - Ok(buffer_queues) -} - -fn verify_object_permission( - owner_id: u32, - viewer_id: u32, - permission: &Permission, -) -> Result<(), ErrorCode> { - if owner_id == viewer_id { - return Ok(()); - } - - match permission.permission { - 0 => Ok(()), // All can read - 1 => Err(ErrorCode::DataStore_PermissionDenied), // Friends only, unimplemented - 2 => { - // Recipient IDs can read - if permission.recipient_ids.contains(&viewer_id) { - Ok(()) - } else { - Err(ErrorCode::DataStore_PermissionDenied) + fn map_row_to_meta_info( + row_data_id: i64, + row_owner: i32, + row_size: i32, + row_name: String, + row_data_type: i16, + row_meta_binary: Vec, + row_permission: i16, + row_permission_recipients: Vec, + row_delete_permission: i16, + row_delete_permission_recipients: Vec, + row_period: i16, + row_refer_data_id: i64, + row_flag: i32, + row_tags: Vec, + row_creation_date: chrono::NaiveDateTime, + row_update_date: chrono::NaiveDateTime, + ratings: Vec + ) -> GetMetaInfo { + GetMetaInfo { + dataid: row_data_id as u64, + owner: row_owner as u32, + size: row_size as u32, + name: row_name, + data_type: row_data_type as u16, + meta_binary: QBuffer(row_meta_binary), + permission: Permission { + permission: row_permission as u8, + recipient_ids: row_permission_recipients.into_iter().map(|id| id as u32).collect(), + }, + del_permission: Permission { + permission: row_delete_permission as u8, + recipient_ids: row_delete_permission_recipients.into_iter().map(|id| id as u32).collect(), + }, + period: row_period as u16, + status: 0, + referred_count: 0, + refer_dat_id: row_refer_data_id as u32, + flag: row_flag as u32, + tags: row_tags, + expire_time: KerberosDateTime::from_u64(0x9C3F3E0000), + created_time: KerberosDateTime::from_naive(row_creation_date), + updated_time: KerberosDateTime::from_naive(row_update_date), + referred_time: KerberosDateTime::from_naive(row_creation_date), + ratings, } } - 3 => Err(ErrorCode::DataStore_PermissionDenied), // Owner only, redundant - _ => Err(ErrorCode::DataStore_InvalidArgument), // ??? haxx0r - } -} -fn filter_properties_by_result_option( - meta_info: &mut GetMetaInfo, - result_option: u8, -) { - if (result_option & 0x01) == 0 { - meta_info.meta_binary = QBuffer(Vec::new()); - } - - if (result_option & 0x04) == 0 { - meta_info.ratings = Vec::new(); - } - - // No idea what the other things do. :shrug: -} - -// Dawg... -async fn get_custom_rankings_by_data_ids( - application_id: u32, - data_ids: Vec -) -> Vec { - let mut results = Vec::with_capacity(data_ids.len()); - - let rows = sqlx::query!( - r#" - SELECT - rankings.data_id, - rankings.value - FROM datastore.object_custom_rankings rankings - JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord) - ON rankings.data_id = rows.data_id - AND rankings.application_id = $2 - ORDER BY rows.ord - "#, - &data_ids.iter().map(|&id| id as i64).collect::>(), - application_id as i32 - ) - .fetch_all(get_db()) - .await; - - let rows = match rows { - Ok(r) => r, - Err(e) => { - log::error!("Custom ranking query error: {:?}", e); - return results; - } - }; - - for row in rows { - let data_id = row.data_id as u64; - let score = row.value.unwrap_or(0) as u32; - - if let Ok(meta) = get_object_info_by_data_id(data_id, 0).await { - results.push(DataStoreCustomRankingResult { - order: 0, - score, - meta_info: meta, - }); - } else { - log::warn!("Could not find metadata for ranked object {}", data_id); - } - } - - results -} - -async fn get_user_course_object_ids(owner_pid: u32) -> Result, ErrorCode> { - let rows = sqlx::query!( - r#" - SELECT data_id - FROM datastore.objects - WHERE owner = $1 AND data_type > 2 AND data_type < 50 - "#, - owner_pid as i64 - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - log::error!("error fetching course IDs for PID {}: {:?}", owner_pid, e); - ErrorCode::DataStore_SystemFileError - })?; - - let mut valid_ids = Vec::new(); - for row in rows { - let data_id = row.data_id as u64; - // always check avail - if check_object_availability(data_id, 0).await.is_ok() { - valid_ids.push(data_id); - } - } - - Ok(valid_ids) -} - -fn get_blacklist_1() -> Vec { - vec![ - "けされ", "消され", "削除され", "リセットされ", "BANされ", "BANされ", - "キミのコース", "君のコース", "きみのコース", "い い ね", "遊びます", "地震", - "震災", "被災", "津波", "バンされ", "い~ね", "震度", "じしん", "banされ", - "くわしくは", "詳しくは", "ちんちん", "ち0こ", "bicth", "い.い.ね", - "ナイ~ス", "い&い", "い-いね", "いぃね", "nigger", "ngger", "star if u", - "Star if u", "Star if you", "star if you", "PENlS", "マンコ", "butthole", - "LILI", "vagina", "vagyna", "うんち", "うんこ", "ウンコ", "Iine", - "EENE", "まんこ", "ウンチ", "niglet", "nigglet", "please like", "きんたま", - "Butthole", "llね", "iいね", "give a star", "ちんぽ", "亀頭", "penis", - "ウンコ", "plz more stars", "star plz", "い()ね", "PLEASE star", "Bitte Sterne", - ].into_iter().map(String::from).collect() -} - -fn get_blacklist_2() -> Vec { - vec![ - "ゼロから", "0から", "0から", "い  い  ね", "いい", "東日本", "大震", - ].into_iter().map(String::from).collect() -} - -fn get_blacklist_3() -> Vec { - vec![ - "いいね", "下さい", "ください", "押して", "おして", "返す", "かえす", - "星", "してくれ", "するよ", "☆くれたら", "☆あげます", "★くれたら", - "★あげます", "しね", "ころす", "ころされた", "アナル", "ファック", - "キンタマ", "○ね", "キチガイ", "うんこ", "KITIGAI", "金玉", "おっぱい", - "☆おす", "☆押す", "★おす", "★押す", "いいする", "いいよ", "イイネ", - "ケツ", "うんち", "かくせいざい", "覚せい剤", "シャブ", "きんたま", - "ちんちん", "おしっこ", "ちんぽこ", "ころして", "グッド", "グット", - "レ●プ", "バーカ", "きちがい", "ちんげ", "マンコ", "まんこ", "チンポ", - "クズ", "ウンコ", "ナイスおねがいします", "penis", "イイね", "☆よろ", - "ナイス!して", "ま/んこ", "まん/こ", - ].into_iter().map(String::from).collect() -} - -impl DataStore for User { - async fn get_meta(&self, mut metaparam: GetMetaParam) -> Result { - let mut meta_info = if metaparam.dataid != 0 { - get_object_info_by_data_id(metaparam.dataid, metaparam.access_password).await? - } else { - get_object_info_by_persistence_target(metaparam.persistence_target, metaparam.access_password).await? - }; - - let current_pid = self.pid; - verify_object_permission(meta_info.owner, current_pid, &meta_info.permission)?; - - filter_properties_by_result_option(&mut meta_info, metaparam.result_option); - - Ok(meta_info) - } - - async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result { - let recipient_ids: Vec = postparam.permission.recipient_ids.iter().map(|&id| id as i32).collect(); - let del_recipient_ids: Vec = postparam.del_permission.recipient_ids.iter().map(|&id| id as i32).collect(); - let now = time::OffsetDateTime::now_utc(); - - let row = sqlx::query!( + async fn check_object_availability(data_id: u64, password: u64) -> Result<(), ErrorCode> { + let row = sqlx::query!( r#" - INSERT INTO datastore.objects ( - owner, size, name, data_type, meta_binary, - permission, permission_recipients, - delete_permission, delete_permission_recipients, - flag, period, refer_data_id, tags, - persistence_slot_id, extra_data, creation_date, update_date - ) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17 - ) RETURNING data_id + SELECT under_review, access_password + FROM datastore.objects + WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE "#, - self.pid as i32, - postparam.size as i32, - postparam.name, - postparam.data_type as i32, - &postparam.meta_binary.0, - postparam.permission.permission as i32, - &recipient_ids, - postparam.del_permission.permission as i32, - &del_recipient_ids, - postparam.flag as i32, - postparam.period as i32, - postparam.refer_data_id as i64, - &postparam.tags, - postparam.persistence_init_param.persistence_slot_id as i32, - &postparam.extra_data, - time::PrimitiveDateTime::new(now.date(), now.time()), - time::PrimitiveDateTime::new(now.date(), now.time()) + data_id as i64 ) - .fetch_one(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; - - let data_id = row.data_id as u64; - let presigner = S3Presigner::new( - &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), - format!("{}", *RNEX_DATASTORE_S3_BUCKET) - ).await; - - let key = format!("data/{}.bin", data_id); - - let (upload_url, fields) = presigner.generate_presigned_post(&key).await; - - let form_fields = fields.into_iter().map(|(k, v)| { - KeyValue { key: k, value: v } - }).collect(); - - Ok(ReqPostInfo { - dataid: data_id, - url: upload_url, - request_headers: vec![], - form_fields, - root_ca_cert: vec![], - }) - } - - async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode> { - log::info!("Data ID: {:?}", completeparam.dataid); - log::info!("Success: {:?}", completeparam.success); - - let record = sqlx::query!( - r#"SELECT owner, under_review FROM datastore.objects WHERE data_id = $1"#, - completeparam.dataid as i64 - ) - .fetch_optional(get_db()) - .await - .map_err(|e| { - eprintln!("select error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; - - let record = record.ok_or(ErrorCode::DataStore_NotFound)?; - - if record.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } - - if record.owner.unwrap_or(0) as u32 != self.pid { - return Err(ErrorCode::DataStore_PermissionDenied); - } - - if completeparam.success { - sqlx::query!( - r#"UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1"#, - completeparam.dataid as i64 - ) - .execute(get_db()) + .fetch_optional(get_db()) .await .map_err(|e| { - eprintln!("update error: {:?}", e); + eprintln!("Availability check DB error: {:?}", e); ErrorCode::DataStore_SystemFileError - })?; - } else { - return Err(ErrorCode::Transport_TemporaryServerError); - } + })? + .ok_or(ErrorCode::DataStore_NotFound)?; - Ok(()) - } - - async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode> { - for abcparam in rankingparam { - let exists = sqlx::query_scalar!( - r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#, - abcparam.dataid as i64 - ) - .fetch_one(get_db()) - .await - .map_err(|_| ErrorCode::DataStore_SystemFileError)?; - - if !exists.unwrap_or(false) { - return Err(ErrorCode::DataStore_NotFound); + let access_password = row.access_password as u64; + if access_password != 0 && access_password != password { + return Err(ErrorCode::DataStore_InvalidPassword); } - sqlx::query!( - r#" - INSERT INTO datastore.object_custom_rankings (data_id, application_id, value) - VALUES ($1, $2, $3) - ON CONFLICT (data_id, application_id) - DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value - "#, - abcparam.dataid as i64, - abcparam.appid as i32, - abcparam.score as i32 - ) - .execute(get_db()) + if row.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } + + Ok(()) + } + + async fn get_object_ratings(data_id: u64, password: u64) -> Result, ErrorCode> { + check_object_availability(data_id, password).await?; + + let rows = sqlx::query!( + r#" + SELECT slot, total_value, count, initial_value + FROM datastore.object_ratings + WHERE data_id = $1 + "#, + data_id as i64 + ) + .fetch_all(get_db()) .await .map_err(|e| { - log::error!("update/insert error: {:?}", e); + eprintln!("Ratings fetch error: {:?}", e); ErrorCode::DataStore_SystemFileError })?; + + let ratings = rows.into_iter().map(|row| { + RatingInfoWithSlot { + slot: row.slot as i8, + rating: RatingInfo { + total_value: row.total_value.unwrap_or(0), + count: row.count as u32, + initial_value: row.initial_value.unwrap_or(0), + }, + } + }).collect(); + + Ok(ratings) } - Ok(()) - } + async fn get_object_info_by_data_id(data_id: u64, password: u64) -> Result { + check_object_availability(data_id, password).await?; - async fn get_application_config(&self, appid: u32) -> Result, ErrorCode> { - const MAX_COURSE_UPLOADS: i32 = 100; + let row = sqlx::query!( + r#"SELECT data_id, owner, size, name, data_type, meta_binary, + permission, permission_recipients, delete_permission, delete_permission_recipients, + period, refer_data_id, flag, tags, creation_date, update_date + FROM datastore.objects WHERE data_id = $1"#, + data_id as i64 + ) + .fetch_optional(get_db()) + .await + .map_err(|_| ErrorCode::DataStore_SystemFileError)? + .ok_or(ErrorCode::DataStore_NotFound)?; - let config = match appid { - 0 => vec![ - 0x00000001, 0x00000032, 0x00000096, 0x0000012c, 0x000001f4, - 0x00000320, 0x00000514, 0x000007d0, 0x00000bb8, 0x00001388, - MAX_COURSE_UPLOADS, 0x00000014, 0x0000001e, 0x00000028, 0x00000032, - 0x0000003c, 0x00000046, 0x00000050, 0x0000005a, 0x00000064, - 0x00000023, 0x0000004b, 0x00000023, 0x0000004b, 0x00000032, - 0x00000000, 0x00000003, 0x00000003, 0x00000064, 0x00000006, - 0x00000001, 0x00000060, 0x00000005, 0x00000060, 0x00000000, - 0x000007e4, 0x00000001, 0x00000001, 0x0000000c, 0x00000000, - ], - 1 => vec![ - 2, - 1770179696, - 1770179664, - 1770179640, - 1770180827, - 1770180777, - 1770180745, - 1770177625, - 1770177590, - ], - 2 => vec![0x000007df, 0x0000000c, 0x00000016, 0x00000005, 0x00000000], - 10 => vec![35, 75, 96, 40, 5, 6], - _ => { - log::error!("unknown SMM app id: {}", appid); - return Err(ErrorCode::DataStore_Unknown); - } - }; + let ratings = get_object_ratings(data_id, password).await?; - Ok(config) - } - - async fn get_custom_ranking_by_data_id( - &self, - custom_ranking_param: DataStoreGetCustomRankingByDataIDParam - ) -> Result<(Vec, Vec), ErrorCode> { - println!("appid: {:?}", custom_ranking_param.application_id); - println!("dataid list: {:?}", custom_ranking_param.data_id_list); - println!("result option: {:?}", custom_ranking_param.result_option); - - let mut ranking_results = get_custom_rankings_by_data_ids(custom_ranking_param.application_id, custom_ranking_param.data_id_list).await; - - let mut q_results = Vec::with_capacity(ranking_results.len()); - - for result in &mut ranking_results { - if (custom_ranking_param.result_option & 0x01) == 0 { - result.meta_info.tags = Vec::new(); - } - - if (custom_ranking_param.result_option & 0x02) == 0 { - result.meta_info.ratings = Vec::new(); - } - - if (custom_ranking_param.result_option & 0x04) == 0 { - result.meta_info.meta_binary = QBuffer(Vec::new()); - } - - if (custom_ranking_param.result_option & 0x20) == 0 { - result.score = 0; - } - - q_results.push(QResult::success(ErrorCode::Core_Unknown)); + Ok(map_row_to_meta_info( + row.data_id, + row.owner.unwrap_or(0), + row.size.unwrap_or(0), + row.name.unwrap_or_default(), + row.data_type.unwrap_or(0) as i16, + row.meta_binary.unwrap_or_default(), + row.permission.unwrap_or(0) as i16, + row.permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), + row.delete_permission.unwrap_or(0) as i16, + row.delete_permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), + row.period.unwrap_or(0) as i16, + row.refer_data_id.unwrap_or(0), + row.flag.unwrap_or(0), + row.tags.unwrap_or_default(), + row.creation_date.map(|dt| chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), + chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() + )).unwrap_or_default(), + row.update_date.map(|dt| chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), + chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() + )).unwrap_or_default(), + ratings + )) } - Ok((ranking_results, q_results)) - } + async fn get_object_info_by_persistence_target(target: PersistenceTarget, password: u64) -> Result { + let row = sqlx::query!( + r#"SELECT data_id, owner, size, name, data_type, meta_binary, + permission, permission_recipients, delete_permission, delete_permission_recipients, + period, refer_data_id, flag, tags, creation_date, update_date, + access_password, under_review + FROM datastore.objects + WHERE owner = $1 AND persistence_slot_id = $2 + AND upload_completed = TRUE AND deleted = FALSE"#, + target.owner as i32, + target.persistence_slot_id as i16 + ) + .fetch_optional(get_db()) + .await + .map_err(|_| ErrorCode::DataStore_SystemFileError)? + .ok_or(ErrorCode::DataStore_NotFound)?; - async fn get_buffer_queue(&self, bufferparam: BufferQueueParam) -> Result, ErrorCode> { - // log::info!("GetBufferQueue: dataid={}, slot={}", param.dataid, param.slot); - - let buffers = get_buffer_queues_by_data_id_and_slot(bufferparam.dataid, bufferparam.slot).await?; - - Ok(buffers) - } - - async fn prepare_get_object(&self, prepare_get_param: DataStorePrepareGetParam) -> Result { - let meta_info = if prepare_get_param.dataid != 0 { - get_object_info_by_data_id(prepare_get_param.dataid, prepare_get_param.access_password).await? - } else { - get_object_info_by_persistence_target(prepare_get_param.persistence_target, prepare_get_param.access_password).await? - }; - - verify_object_permission(meta_info.owner, self.pid, &meta_info.permission)?; - - let presigner = S3Presigner::new( - &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), - format!("{}", *RNEX_DATASTORE_S3_BUCKET) - ).await; - - let key = format!("data/{}.bin", meta_info.dataid); - let download_url = presigner.generate_presigned_get(&key); - - Ok(DataStoreReqGetInfo { - url: download_url, - request_headers: vec![], - size: meta_info.size, - root_ca_cert: vec![], - dataid: meta_info.dataid, - }) - } - - async fn followings_latest_course_search_object( - &self, - course_search_param: DataStoreSearchParam, - _extra_data: Vec - ) -> Result, ErrorCode> { - let mut all_results = Vec::new(); - - for &owner_pid in &course_search_param.owner_ids { - let course_ids = get_user_course_object_ids(owner_pid).await?; - - if course_ids.is_empty() { - continue; + let db_password = row.access_password as u64; + if db_password != 0 && db_password != password { + return Err(ErrorCode::DataStore_InvalidPassword); } - let mut results = get_custom_rankings_by_data_ids(0, course_ids).await; - - // Flag 0x1: Return Tags - // Flag 0x2: Return Ratings - // Flag 0x4: Return MetaBinary - // Flag 0x20: Return Score - for res in &mut results { - if course_search_param.result_option & 0x1 == 0 { - res.meta_info.tags = Vec::new(); - } - if course_search_param.result_option & 0x2 == 0 { - res.meta_info.ratings = Vec::new(); - } - if course_search_param.result_option & 0x4 == 0 { - res.meta_info.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); - } - if course_search_param.result_option & 0x20 == 0 { - res.score = 0; - } + if row.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); } - all_results.extend(results); + let ratings = get_object_ratings(row.data_id as u64, password).await?; + + Ok(map_row_to_meta_info( + row.data_id, + row.owner.unwrap_or(0), + row.size.unwrap_or(0), + row.name.unwrap_or_default(), + row.data_type.unwrap_or(0) as i16, + row.meta_binary.unwrap_or_default(), + row.permission.unwrap_or(0) as i16, + row.permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), + row.delete_permission.unwrap_or(0) as i16, + row.delete_permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), + row.period.unwrap_or(0) as i16, + row.refer_data_id.unwrap_or(0), + row.flag.unwrap_or(0), + row.tags.unwrap_or_default(), + row.creation_date.map(|dt| chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), + chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() + )).unwrap_or_default(), + row.update_date.map(|dt| chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), + chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() + )).unwrap_or_default(), + ratings + )) } - // note: we assume the client sorts the data lol + async fn get_buffer_queues_by_data_id_and_slot( + data_id: u64, + slot: u32 + ) -> Result, ErrorCode> { + check_object_availability(data_id, 0).await?; - Ok(all_results) - } + let rows = sqlx::query!( + r#" + SELECT buffer + FROM datastore.buffer_queues + WHERE data_id = $1 AND slot = $2 + ORDER BY creation_date ASC + "#, + data_id as i64, + slot as i32 + ) + .fetch_all(get_db()) + .await + .map_err(|e| { + log::error!("Buffer queue fetch error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; - async fn get_application_config_string(&self, application_id: u32) -> Result, ErrorCode> { - let config = match application_id { - 128 => get_blacklist_1(), - 129 => get_blacklist_2(), - 130 => get_blacklist_3(), - _ => { - log::warn!("unsupported application_id in GetApplicationConfigString: {}", application_id); - Vec::new() + let buffer_queues = rows + .into_iter() + .map(|row| QBuffer(row.buffer)) + .collect(); + + Ok(buffer_queues) + } + + fn verify_object_permission( + owner_id: u32, + viewer_id: u32, + permission: &Permission, + ) -> Result<(), ErrorCode> { + if owner_id == viewer_id { + return Ok(()); } - }; - Ok(config) - } - - async fn get_metas_multiple_param( - &self, - params: Vec - ) -> Result<(Vec, Vec), ErrorCode> { - let mut metas = Vec::with_capacity(params.len()); - let mut results = Vec::with_capacity(params.len()); - - for param in params { - let info_result = if param.dataid != 0 { - get_object_info_by_data_id(param.dataid, param.access_password).await - } else { - get_object_info_by_persistence_target(param.persistence_target, param.access_password).await - }; - - match info_result { - Ok(mut meta) => { - if let Err(e) = verify_object_permission(meta.owner, self.pid, &meta.permission) { - metas.push(GetMetaInfo::default()); - results.push(QResult::error(e)); + match permission.permission { + 0 => Ok(()), // All can read + 1 => Err(ErrorCode::DataStore_PermissionDenied), // Friends only, unimplemented + 2 => { + // Recipient IDs can read + if permission.recipient_ids.contains(&viewer_id) { + Ok(()) } else { - if param.result_option & 0x1 == 0 { - meta.tags = Vec::new(); - } - if param.result_option & 0x2 == 0 { - meta.ratings = Vec::new(); - } - if param.result_option & 0x4 == 0 { - meta.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); - } - - metas.push(meta); - results.push(QResult::success(ErrorCode::Core_Unknown)); + Err(ErrorCode::DataStore_PermissionDenied) } } - Err(e) => { - metas.push(GetMetaInfo::default()); - results.push(QResult::error(e)); - } + 3 => Err(ErrorCode::DataStore_PermissionDenied), // Owner only, redundant + _ => Err(ErrorCode::DataStore_InvalidArgument), // ??? haxx0r } } - Ok((metas, results)) + fn filter_properties_by_result_option( + meta_info: &mut GetMetaInfo, + result_option: u8, + ) { + if (result_option & 0x01) == 0 { + meta_info.meta_binary = QBuffer(Vec::new()); + } + + if (result_option & 0x04) == 0 { + meta_info.ratings = Vec::new(); + } + + // No idea what the other things do. :shrug: + } + + // Dawg... + async fn get_custom_rankings_by_data_ids( + application_id: u32, + data_ids: Vec + ) -> Vec { + let mut results = Vec::with_capacity(data_ids.len()); + + let rows = sqlx::query!( + r#" + SELECT + rankings.data_id, + rankings.value + FROM datastore.object_custom_rankings rankings + JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord) + ON rankings.data_id = rows.data_id + AND rankings.application_id = $2 + ORDER BY rows.ord + "#, + &data_ids.iter().map(|&id| id as i64).collect::>(), + application_id as i32 + ) + .fetch_all(get_db()) + .await; + + let rows = match rows { + Ok(r) => r, + Err(e) => { + log::error!("Custom ranking query error: {:?}", e); + return results; + } + }; + + for row in rows { + let data_id = row.data_id as u64; + let score = row.value.unwrap_or(0) as u32; + + if let Ok(meta) = get_object_info_by_data_id(data_id, 0).await { + results.push(DataStoreCustomRankingResult { + order: 0, + score, + meta_info: meta, + }); + } else { + log::warn!("Could not find metadata for ranked object {}", data_id); + } + } + + results + } + + async fn get_user_course_object_ids(owner_pid: u32) -> Result, ErrorCode> { + let rows = sqlx::query!( + r#" + SELECT data_id + FROM datastore.objects + WHERE owner = $1 AND data_type > 2 AND data_type < 50 + "#, + owner_pid as i64 + ) + .fetch_all(get_db()) + .await + .map_err(|e| { + log::error!("error fetching course IDs for PID {}: {:?}", owner_pid, e); + ErrorCode::DataStore_SystemFileError + })?; + + let mut valid_ids = Vec::new(); + for row in rows { + let data_id = row.data_id as u64; + // always check avail + if check_object_availability(data_id, 0).await.is_ok() { + valid_ids.push(data_id); + } + } + + Ok(valid_ids) + } + + fn get_blacklist_1() -> Vec { + vec![ + "けされ", "消され", "削除され", "リセットされ", "BANされ", "BANされ", + "キミのコース", "君のコース", "きみのコース", "い い ね", "遊びます", "地震", + "震災", "被災", "津波", "バンされ", "い~ね", "震度", "じしん", "banされ", + "くわしくは", "詳しくは", "ちんちん", "ち0こ", "bicth", "い.い.ね", + "ナイ~ス", "い&い", "い-いね", "いぃね", "nigger", "ngger", "star if u", + "Star if u", "Star if you", "star if you", "PENlS", "マンコ", "butthole", + "LILI", "vagina", "vagyna", "うんち", "うんこ", "ウンコ", "Iine", + "EENE", "まんこ", "ウンチ", "niglet", "nigglet", "please like", "きんたま", + "Butthole", "llね", "iいね", "give a star", "ちんぽ", "亀頭", "penis", + "ウンコ", "plz more stars", "star plz", "い()ね", "PLEASE star", "Bitte Sterne", + ].into_iter().map(String::from).collect() + } + + fn get_blacklist_2() -> Vec { + vec![ + "ゼロから", "0から", "0から", "い  い  ね", "いい", "東日本", "大震", + ].into_iter().map(String::from).collect() + } + + fn get_blacklist_3() -> Vec { + vec![ + "いいね", "下さい", "ください", "押して", "おして", "返す", "かえす", + "星", "してくれ", "するよ", "☆くれたら", "☆あげます", "★くれたら", + "★あげます", "しね", "ころす", "ころされた", "アナル", "ファック", + "キンタマ", "○ね", "キチガイ", "うんこ", "KITIGAI", "金玉", "おっぱい", + "☆おす", "☆押す", "★おす", "★押す", "いいする", "いいよ", "イイネ", + "ケツ", "うんち", "かくせいざい", "覚せい剤", "シャブ", "きんたま", + "ちんちん", "おしっこ", "ちんぽこ", "ころして", "グッド", "グット", + "レ●プ", "バーカ", "きちがい", "ちんげ", "マンコ", "まんこ", "チンポ", + "クズ", "ウンコ", "ナイスおねがいします", "penis", "イイね", "☆よろ", + "ナイス!して", "ま/んこ", "まん/こ", + ].into_iter().map(String::from).collect() + } + + impl DataStore for User { + async fn get_meta(&self, mut metaparam: GetMetaParam) -> Result { + let mut meta_info = if metaparam.dataid != 0 { + get_object_info_by_data_id(metaparam.dataid, metaparam.access_password).await? + } else { + get_object_info_by_persistence_target(metaparam.persistence_target, metaparam.access_password).await? + }; + + let current_pid = self.pid; + verify_object_permission(meta_info.owner, current_pid, &meta_info.permission)?; + + filter_properties_by_result_option(&mut meta_info, metaparam.result_option); + + Ok(meta_info) + } + + async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result { + let recipient_ids: Vec = postparam.permission.recipient_ids.iter().map(|&id| id as i32).collect(); + let del_recipient_ids: Vec = postparam.del_permission.recipient_ids.iter().map(|&id| id as i32).collect(); + let now = time::OffsetDateTime::now_utc(); + + let row = sqlx::query!( + r#" + INSERT INTO datastore.objects ( + owner, size, name, data_type, meta_binary, + permission, permission_recipients, + delete_permission, delete_permission_recipients, + flag, period, refer_data_id, tags, + persistence_slot_id, extra_data, creation_date, update_date + ) VALUES ( + $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17 + ) RETURNING data_id + "#, + self.pid as i32, + postparam.size as i32, + postparam.name, + postparam.data_type as i32, + &postparam.meta_binary.0, + postparam.permission.permission as i32, + &recipient_ids, + postparam.del_permission.permission as i32, + &del_recipient_ids, + postparam.flag as i32, + postparam.period as i32, + postparam.refer_data_id as i64, + &postparam.tags, + postparam.persistence_init_param.persistence_slot_id as i32, + &postparam.extra_data, + time::PrimitiveDateTime::new(now.date(), now.time()), + time::PrimitiveDateTime::new(now.date(), now.time()) + ) + .fetch_one(get_db()) + .await + .map_err(|e| { + log::error!("DB Error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + + let data_id = row.data_id as u64; + let presigner = S3Presigner::new( + &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), + format!("{}", *RNEX_DATASTORE_S3_BUCKET) + ).await; + + let key = format!("data/{}.bin", data_id); + + let (upload_url, fields) = presigner.generate_presigned_post(&key).await; + + let form_fields = fields.into_iter().map(|(k, v)| { + KeyValue { key: k, value: v } + }).collect(); + + Ok(ReqPostInfo { + dataid: data_id, + url: upload_url, + request_headers: vec![], + form_fields, + root_ca_cert: vec![], + }) + } + + async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode> { + log::info!("Data ID: {:?}", completeparam.dataid); + log::info!("Success: {:?}", completeparam.success); + + let record = sqlx::query!( + r#"SELECT owner, under_review FROM datastore.objects WHERE data_id = $1"#, + completeparam.dataid as i64 + ) + .fetch_optional(get_db()) + .await + .map_err(|e| { + eprintln!("select error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + + let record = record.ok_or(ErrorCode::DataStore_NotFound)?; + + if record.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } + + if record.owner.unwrap_or(0) as u32 != self.pid { + return Err(ErrorCode::DataStore_PermissionDenied); + } + + if completeparam.success { + sqlx::query!( + r#"UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1"#, + completeparam.dataid as i64 + ) + .execute(get_db()) + .await + .map_err(|e| { + eprintln!("update error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + } else { + return Err(ErrorCode::Transport_TemporaryServerError); + } + + Ok(()) + } + + async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode> { + for abcparam in rankingparam { + let exists = sqlx::query_scalar!( + r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#, + abcparam.dataid as i64 + ) + .fetch_one(get_db()) + .await + .map_err(|_| ErrorCode::DataStore_SystemFileError)?; + + if !exists.unwrap_or(false) { + return Err(ErrorCode::DataStore_NotFound); + } + + sqlx::query!( + r#" + INSERT INTO datastore.object_custom_rankings (data_id, application_id, value) + VALUES ($1, $2, $3) + ON CONFLICT (data_id, application_id) + DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value + "#, + abcparam.dataid as i64, + abcparam.appid as i32, + abcparam.score as i32 + ) + .execute(get_db()) + .await + .map_err(|e| { + log::error!("update/insert error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + } + + Ok(()) + } + + async fn get_application_config(&self, appid: u32) -> Result, ErrorCode> { + const MAX_COURSE_UPLOADS: i32 = 100; + + let config = match appid { + 0 => vec![ + 0x00000001, 0x00000032, 0x00000096, 0x0000012c, 0x000001f4, + 0x00000320, 0x00000514, 0x000007d0, 0x00000bb8, 0x00001388, + MAX_COURSE_UPLOADS, 0x00000014, 0x0000001e, 0x00000028, 0x00000032, + 0x0000003c, 0x00000046, 0x00000050, 0x0000005a, 0x00000064, + 0x00000023, 0x0000004b, 0x00000023, 0x0000004b, 0x00000032, + 0x00000000, 0x00000003, 0x00000003, 0x00000064, 0x00000006, + 0x00000001, 0x00000060, 0x00000005, 0x00000060, 0x00000000, + 0x000007e4, 0x00000001, 0x00000001, 0x0000000c, 0x00000000, + ], + 1 => vec![ + 2, + 1770179696, + 1770179664, + 1770179640, + 1770180827, + 1770180777, + 1770180745, + 1770177625, + 1770177590, + ], + 2 => vec![0x000007df, 0x0000000c, 0x00000016, 0x00000005, 0x00000000], + 10 => vec![35, 75, 96, 40, 5, 6], + _ => { + log::error!("unknown SMM app id: {}", appid); + return Err(ErrorCode::DataStore_Unknown); + } + }; + + Ok(config) + } + + async fn get_custom_ranking_by_data_id( + &self, + custom_ranking_param: DataStoreGetCustomRankingByDataIDParam + ) -> Result<(Vec, Vec), ErrorCode> { + println!("appid: {:?}", custom_ranking_param.application_id); + println!("dataid list: {:?}", custom_ranking_param.data_id_list); + println!("result option: {:?}", custom_ranking_param.result_option); + + let mut ranking_results = get_custom_rankings_by_data_ids(custom_ranking_param.application_id, custom_ranking_param.data_id_list).await; + + let mut q_results = Vec::with_capacity(ranking_results.len()); + + for result in &mut ranking_results { + if (custom_ranking_param.result_option & 0x01) == 0 { + result.meta_info.tags = Vec::new(); + } + + if (custom_ranking_param.result_option & 0x02) == 0 { + result.meta_info.ratings = Vec::new(); + } + + if (custom_ranking_param.result_option & 0x04) == 0 { + result.meta_info.meta_binary = QBuffer(Vec::new()); + } + + if (custom_ranking_param.result_option & 0x20) == 0 { + result.score = 0; + } + + q_results.push(QResult::success(ErrorCode::Core_Unknown)); + } + + Ok((ranking_results, q_results)) + } + + async fn get_buffer_queue(&self, bufferparam: BufferQueueParam) -> Result, ErrorCode> { + // log::info!("GetBufferQueue: dataid={}, slot={}", param.dataid, param.slot); + + let buffers = get_buffer_queues_by_data_id_and_slot(bufferparam.dataid, bufferparam.slot).await?; + + Ok(buffers) + } + + async fn prepare_get_object(&self, prepare_get_param: DataStorePrepareGetParam) -> Result { + let meta_info = if prepare_get_param.dataid != 0 { + get_object_info_by_data_id(prepare_get_param.dataid, prepare_get_param.access_password).await? + } else { + get_object_info_by_persistence_target(prepare_get_param.persistence_target, prepare_get_param.access_password).await? + }; + + verify_object_permission(meta_info.owner, self.pid, &meta_info.permission)?; + + let presigner = S3Presigner::new( + &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), + format!("{}", *RNEX_DATASTORE_S3_BUCKET) + ).await; + + let key = format!("data/{}.bin", meta_info.dataid); + let download_url = presigner.generate_presigned_get(&key); + + Ok(DataStoreReqGetInfo { + url: download_url, + request_headers: vec![], + size: meta_info.size, + root_ca_cert: vec![], + dataid: meta_info.dataid, + }) + } + + async fn followings_latest_course_search_object( + &self, + course_search_param: DataStoreSearchParam, + _extra_data: Vec + ) -> Result, ErrorCode> { + let mut all_results = Vec::new(); + + for &owner_pid in &course_search_param.owner_ids { + let course_ids = get_user_course_object_ids(owner_pid).await?; + + if course_ids.is_empty() { + continue; + } + + let mut results = get_custom_rankings_by_data_ids(0, course_ids).await; + + // Flag 0x1: Return Tags + // Flag 0x2: Return Ratings + // Flag 0x4: Return MetaBinary + // Flag 0x20: Return Score + for res in &mut results { + if course_search_param.result_option & 0x1 == 0 { + res.meta_info.tags = Vec::new(); + } + if course_search_param.result_option & 0x2 == 0 { + res.meta_info.ratings = Vec::new(); + } + if course_search_param.result_option & 0x4 == 0 { + res.meta_info.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); + } + if course_search_param.result_option & 0x20 == 0 { + res.score = 0; + } + } + + all_results.extend(results); + } + + // note: we assume the client sorts the data lol + + Ok(all_results) + } + + async fn get_application_config_string(&self, application_id: u32) -> Result, ErrorCode> { + let config = match application_id { + 128 => get_blacklist_1(), + 129 => get_blacklist_2(), + 130 => get_blacklist_3(), + _ => { + log::warn!("unsupported application_id in GetApplicationConfigString: {}", application_id); + Vec::new() + } + }; + + Ok(config) + } + + async fn get_metas_multiple_param( + &self, + params: Vec + ) -> Result<(Vec, Vec), ErrorCode> { + let mut metas = Vec::with_capacity(params.len()); + let mut results = Vec::with_capacity(params.len()); + + for param in params { + let info_result = if param.dataid != 0 { + get_object_info_by_data_id(param.dataid, param.access_password).await + } else { + get_object_info_by_persistence_target(param.persistence_target, param.access_password).await + }; + + match info_result { + Ok(mut meta) => { + if let Err(e) = verify_object_permission(meta.owner, self.pid, &meta.permission) { + metas.push(GetMetaInfo::default()); + results.push(QResult::error(e)); + } else { + if param.result_option & 0x1 == 0 { + meta.tags = Vec::new(); + } + if param.result_option & 0x2 == 0 { + meta.ratings = Vec::new(); + } + if param.result_option & 0x4 == 0 { + meta.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); + } + + metas.push(meta); + results.push(QResult::success(ErrorCode::Core_Unknown)); + } + } + Err(e) => { + metas.push(GetMetaInfo::default()); + results.push(QResult::error(e)); + } + } + } + + Ok((metas, results)) + } + } } } \ No newline at end of file From 458c651cd4e0f0d40ca22bfa5cc036e8695ab9e3 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 21 Apr 2026 21:41:44 +0200 Subject: [PATCH 093/203] Fix conditional compilaton --- rnex-core/src/executables/common.rs | 42 +++++++++++++++++------------ rnex-core/src/nex/mod.rs | 8 +++++- rnex-core/src/nex/user.rs | 36 ++++++++++++++++++------- 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index ec27f43..280ab7f 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -10,33 +10,41 @@ use std::sync::Arc; use tokio::net::TcpListener; use std::sync::LazyLock; use std::sync::OnceLock; -use sqlx::postgres::PgPool; - +cfg_if! { + if #[cfg(feature = "datastore")] { + use sqlx::postgres::PgPool; + } +} use log::error; use std::error::Error; use std::string::ToString; +use cfg_if::cfg_if; use crate::reggie::UnitPacketRead; const IP_REQ_SERVICE_URL: &str = "https://ipinfo.io/ip"; -pub static RNEX_DATASTORE_DATABASE_URL: LazyLock = LazyLock::new(|| { - std::env::var("RNEX_DATASTORE_DATABASE_URL") - .expect("RNEX_DATASTORE_DATABASE_URL must be set") -}); +cfg_if! { + if #[cfg(feature = "datastore")] { + pub static RNEX_DATASTORE_DATABASE_URL: LazyLock = LazyLock::new(|| { + std::env::var("RNEX_DATASTORE_DATABASE_URL") + .expect("RNEX_DATASTORE_DATABASE_URL must be set") + }); -pub static DB_POOL: OnceLock = OnceLock::new(); + pub static DB_POOL: OnceLock = OnceLock::new(); -pub fn get_db() -> &'static PgPool { - DB_POOL.get().expect("db_pool not initialized") + pub fn get_db() -> &'static PgPool { + DB_POOL.get().expect("db_pool not initialized") + } + pub static RNEX_DATASTORE_S3_ENDPOINT: LazyLock = LazyLock::new(|| { + std::env::var("RNEX_DATASTORE_S3_ENDPOINT") + .expect("RNEX_DATASTORE_S3_ENDPOINT must be set") + }); + pub static RNEX_DATASTORE_S3_BUCKET: LazyLock = LazyLock::new(|| { + std::env::var("RNEX_DATASTORE_S3_BUCKET") + .expect("RNEX_DATASTORE_S3_BUCKET must be set") + }); + } } -pub static RNEX_DATASTORE_S3_ENDPOINT: LazyLock = LazyLock::new(|| { - std::env::var("RNEX_DATASTORE_S3_ENDPOINT") - .expect("RNEX_DATASTORE_S3_ENDPOINT must be set") -}); -pub static RNEX_DATASTORE_S3_BUCKET: LazyLock = LazyLock::new(|| { - std::env::var("RNEX_DATASTORE_S3_BUCKET") - .expect("RNEX_DATASTORE_S3_BUCKET must be set") -}); pub fn try_get_ip() -> Result> { let mut req = ureq::get(IP_REQ_SERVICE_URL).call()?; diff --git a/rnex-core/src/nex/mod.rs b/rnex-core/src/nex/mod.rs index 91bb866..f54e939 100644 --- a/rnex-core/src/nex/mod.rs +++ b/rnex-core/src/nex/mod.rs @@ -1,3 +1,5 @@ +use cfg_if::cfg_if; + pub mod account; pub mod auth_handler; pub mod common; @@ -6,4 +8,8 @@ pub mod matchmake; pub mod remote_console; pub mod user; pub mod datastore; -pub mod s3presigner; \ No newline at end of file +cfg_if! { + if #[cfg(feature = "datastore")] { + pub mod s3presigner; + } +} \ No newline at end of file diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index f271355..a812d7c 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -41,21 +41,37 @@ use rnex_core::prudp::socket_addr::PRUDPSockAddr; use rnex_core::rmc::response::ErrorCode::{Core_InvalidArgument, RendezVous_AccountExpired}; use rnex_core::rmc::structures::qresult::QResult; use std::sync::{Arc, Weak}; +use cfg_if::cfg_if; use rnex_core::rmc::protocols::ranking::{CompetitionRankingScoreData, CompetitionRankingGetParam, CompetitionRankingScoreInfo}; use rnex_core::rmc::structures::ranking::{UploadCompetitionData}; use tokio::sync::{Mutex, RwLock}; -define_rmc_proto!( - proto UserProtocol{ - Secure, - MatchmakeExtension, - MatchmakeExt, - Matchmake, - NatTraversal, - Ranking, - DataStore +cfg_if! { + if #[cfg(feature = "datastore")] { + define_rmc_proto!( + proto UserProtocol{ + Secure, + MatchmakeExtension, + MatchmakeExt, + Matchmake, + NatTraversal, + Ranking, + DataStore + } + ); + } else { + define_rmc_proto!( + proto UserProtocol{ + Secure, + MatchmakeExtension, + MatchmakeExt, + Matchmake, + NatTraversal, + Ranking + } + ); } -); +} #[rmc_struct(UserProtocol)] pub struct User { From 52af146c555d4354af9c6d8eb27456a65b8e81a4 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 21 Apr 2026 21:48:28 +0200 Subject: [PATCH 094/203] i should really start waiting maybe a minute longer before commiting --- rnex-core/src/executables/backend_server_secure.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rnex-core/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs index 0beeafc..cbb64d8 100644 --- a/rnex-core/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -1,6 +1,5 @@ use cfg_if::cfg_if; use rnex_core::common::setup; -use rnex_core::executables::common::DB_POOL; use rnex_core::executables::common::new_simple_backend; use rnex_core::executables::friends_backend::start_friends_backend; use rnex_core::nex::matchmake::MatchmakeManager; @@ -9,7 +8,6 @@ use rnex_core::nex::user::User; use rnex_core::rmc::protocols::{RemoteDisconnectable, RmcPureRemoteObject}; use std::sync::Arc; use std::sync::atomic::AtomicU32; -use sqlx::PgPool; #[tokio::main] async fn main() { @@ -19,6 +17,8 @@ async fn main() { if #[cfg(feature = "friends")]{ start_friends_backend().await; } else if #[cfg(feature = "datastore")] { + use rnex_core::executables::common::DB_POOL; + use sqlx::PgPool; let database_url = std::env::var("RNEX_DATASTORE_DATABASE_URL") .expect("RNEX_DATASTORE_DATABASE_URL must be set"); From e874bf142dcdb96bf010ec0585023ea53fda81db Mon Sep 17 00:00:00 2001 From: Maple Date: Fri, 24 Apr 2026 21:38:31 +0200 Subject: [PATCH 095/203] fix self holepunch --- rnex-core/src/nex/matchmake.rs | 36 ++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 032fbad..085c8a1 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -236,6 +236,9 @@ impl ExtendedMatchmakeSession { }*/ for pid in &list_of_connected_pids { + if other_conn.pid == *pid { + continue; + } other_conn .remote .process_notification_event(NotificationEvent { @@ -247,28 +250,31 @@ impl ExtendedMatchmakeSession { param_3: self.connected_players.len() as _, }) .await; - } + } } for old_conns in &old_particip { let Some(old_conns) = old_conns.upgrade() else { continue; }; - if old_conns.pid != self.session.gathering.host_pid{ - continue; + if old_conns.pid != self.session.gathering.host_pid { + continue; } - for new_conn_pid in conns.iter().filter_map(Weak::upgrade).map(|c| c.pid){ - old_conns - .remote - .process_notification_event(NotificationEvent { - pid_source: initiating_pid, - notif_type: 3001, - param_1: self.session.gathering.self_gid as PID, - param_2: new_conn_pid, - str_param: join_msg.clone(), - param_3: self.connected_players.len() as _, - }) - .await; + for new_conn_pid in conns.iter().filter_map(Weak::upgrade).map(|c| c.pid) { + if old_conns.pid == new_conn_pid { + continue; + } + old_conns + .remote + .process_notification_event(NotificationEvent { + pid_source: initiating_pid, + notif_type: 3001, + param_1: self.session.gathering.self_gid as PID, + param_2: new_conn_pid, + str_param: join_msg.clone(), + param_3: self.connected_players.len() as _, + }) + .await; } } } From 81824b1540120533c93b18bd29dc5a290a2fa91d Mon Sep 17 00:00:00 2001 From: Maple Date: Fri, 24 Apr 2026 22:09:02 +0200 Subject: [PATCH 096/203] try fixing matchmaking again --- rnex-core/src/nex/matchmake.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 085c8a1..e1afa21 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -235,10 +235,11 @@ impl ExtendedMatchmakeSession { continue; }*/ + if other_conn.pid != self.session.gathering.host_pid { + continue; + } + for pid in &list_of_connected_pids { - if other_conn.pid == *pid { - continue; - } other_conn .remote .process_notification_event(NotificationEvent { @@ -261,9 +262,6 @@ impl ExtendedMatchmakeSession { continue; } for new_conn_pid in conns.iter().filter_map(Weak::upgrade).map(|c| c.pid) { - if old_conns.pid == new_conn_pid { - continue; - } old_conns .remote .process_notification_event(NotificationEvent { From 09e5b1f92a1738e3a969bb82bed2d883659a88d3 Mon Sep 17 00:00:00 2001 From: Maple Date: Fri, 24 Apr 2026 22:38:25 +0200 Subject: [PATCH 097/203] try fixing matchmaking again really hopefully --- rnex-core/src/nex/matchmake.rs | 7 ++-- rnex-core/src/nex/user.rs | 58 ++++++++++++++++------------------ 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index e1afa21..dbaf9c0 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -234,10 +234,10 @@ impl ExtendedMatchmakeSession { joining_pid == self.session.gathering.owner_pid{ continue; }*/ - + /* if other_conn.pid != self.session.gathering.host_pid { continue; - } + } */ for pid in &list_of_connected_pids { other_conn @@ -258,9 +258,10 @@ impl ExtendedMatchmakeSession { let Some(old_conns) = old_conns.upgrade() else { continue; }; + /* if old_conns.pid != self.session.gathering.host_pid { continue; - } + } */ for new_conn_pid in conns.iter().filter_map(Weak::upgrade).map(|c| c.pid) { old_conns .remote diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index c86ae73..29d5332 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -5,15 +5,12 @@ use crate::nex::remote_console::RemoteConsole; use crate::rmc::protocols::matchmake::{ Matchmake, RawMatchmake, RawMatchmakeInfo, RemoteMatchmake, }; -use serde::{Serialize, Deserialize}; -use std::env; -use std::str::FromStr; use crate::rmc::protocols::nat_traversal::{ NatTraversal, RawNatTraversal, RawNatTraversalInfo, RemoteNatTraversal, RemoteNatTraversalConsole, }; -use rnex_core::kerberos::KerberosDateTime; use rnex_core::PID; +use rnex_core::kerberos::KerberosDateTime; use rnex_core::prudp::station_url::StationUrl; use rnex_core::prudp::station_url::UrlOptions::{ Address, NatFiltering, NatMapping, Port, RVConnectionID, @@ -31,17 +28,22 @@ use rnex_core::rmc::structures::any::Any; use rnex_core::rmc::structures::matchmake::{ AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession, }; +use serde::{Deserialize, Serialize}; +use std::env; +use std::str::FromStr; use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; -use log::{info, error}; +use log::{error, info}; use macros::rmc_struct; -use rnex_core::rmc::structures::qbuffer::QBuffer; use rnex_core::prudp::socket_addr::PRUDPSockAddr; +use rnex_core::rmc::protocols::ranking::{ + CompetitionRankingGetParam, CompetitionRankingScoreData, CompetitionRankingScoreInfo, +}; use rnex_core::rmc::response::ErrorCode::{Core_InvalidArgument, RendezVous_AccountExpired}; +use rnex_core::rmc::structures::qbuffer::QBuffer; use rnex_core::rmc::structures::qresult::QResult; +use rnex_core::rmc::structures::ranking::UploadCompetitionData; use std::sync::{Arc, Weak}; -use rnex_core::rmc::protocols::ranking::{CompetitionRankingScoreData, CompetitionRankingGetParam, CompetitionRankingScoreInfo}; -use rnex_core::rmc::structures::ranking::{UploadCompetitionData}; use tokio::sync::{Mutex, RwLock}; define_rmc_proto!( @@ -617,10 +619,7 @@ fn fetch_team_votes(fest_id: u32) -> Result, ErrorCode> { })?; let body = body.trim().trim_start_matches('[').trim_end_matches(']'); - let votes: Result, _> = body - .split(',') - .map(|s| u32::from_str(s.trim())) - .collect(); + let votes: Result, _> = body.split(',').map(|s| u32::from_str(s.trim())).collect(); votes.map_err(|e| { error!("failed to parse votes: {:?}", e); @@ -635,23 +634,19 @@ impl Ranking for User { ) -> Result, ErrorCode> { let fest_id = param.festival_ids.get(0).copied().unwrap_or(0); - let endpoint_results = env::var("RNEX_SPLATOON_RESULTS_GET") - .map_err(|_| { - error!("RNEX_SPLATOON_RESULTS_GET not set"); - ErrorCode::RendezVous_InvalidConfiguration - })?; + let endpoint_results = env::var("RNEX_SPLATOON_RESULTS_GET").map_err(|_| { + error!("RNEX_SPLATOON_RESULTS_GET not set"); + ErrorCode::RendezVous_InvalidConfiguration + })?; let url_results = format!("{}?splatfest_id={}", endpoint_results, fest_id); let response_results = ureq::get(&url_results).call(); let results: Vec = match response_results { - Ok(mut res) => res - .body_mut() - .read_json() - .map_err(|e| { - error!("failed to parse JSON: {:?}", e); - ErrorCode::RendezVous_InvalidConfiguration - })?, + Ok(mut res) => res.body_mut().read_json().map_err(|e| { + error!("failed to parse JSON: {:?}", e); + ErrorCode::RendezVous_InvalidConfiguration + })?, Err(e) => { error!("GET failed: {:?}", e); return Err(ErrorCode::RendezVous_InvalidConfiguration); @@ -661,9 +656,8 @@ impl Ranking for User { let team_votes = fetch_team_votes(fest_id)?; let mut wins = vec![0u32, 0u32]; for r in &results { - if r.team_win == 1 && (r.team_id == 0 || r.team_id == 1) { - wins[r.team_id as usize] += 1; - } + let won_team = r.team_id ^ (!r.team_win); + wins[won_team as usize] += 1; } let score_data: Vec = results @@ -677,7 +671,7 @@ impl Ranking for User { appdata: QBuffer(vec![]), }) .collect(); - + let info = CompetitionRankingScoreInfo { fest_id, score_data, @@ -689,7 +683,10 @@ impl Ranking for User { Ok(vec![info]) } - async fn upload_competition_ranking_score(&self, param: UploadCompetitionData) -> Result { + async fn upload_competition_ranking_score( + &self, + param: UploadCompetitionData, + ) -> Result { info!("fest results for user {:?}:", self.pid); info!("fest id: {:?}", param.splatfest_id); info!("score: {:?}", param.score); @@ -732,8 +729,7 @@ impl Ranking for User { error!("POST borked: {:?}", e); } } - + Ok(true) } } - From 7ff0950617777779b983c6a02fc32427ae35be39 Mon Sep 17 00:00:00 2001 From: Maple Date: Fri, 24 Apr 2026 22:53:12 +0200 Subject: [PATCH 098/203] only let hosts see their own joins and let all other players not see their own joins --- rnex-core/src/nex/matchmake.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index dbaf9c0..1129c76 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -240,6 +240,9 @@ impl ExtendedMatchmakeSession { } */ for pid in &list_of_connected_pids { + if other_conn.pid != self.session.gathering.host_pid && other_conn.pid == *pid { + continue; + } other_conn .remote .process_notification_event(NotificationEvent { @@ -258,11 +261,11 @@ impl ExtendedMatchmakeSession { let Some(old_conns) = old_conns.upgrade() else { continue; }; - /* - if old_conns.pid != self.session.gathering.host_pid { - continue; - } */ for new_conn_pid in conns.iter().filter_map(Weak::upgrade).map(|c| c.pid) { + if old_conns.pid != self.session.gathering.host_pid && old_conns.pid == new_conn_pid + { + continue; + } old_conns .remote .process_notification_event(NotificationEvent { From 757ca292b9bea687991496bae49f9c22fc8f5d39 Mon Sep 17 00:00:00 2001 From: Maple Date: Fri, 24 Apr 2026 23:05:53 +0200 Subject: [PATCH 099/203] yet another attempt --- rnex-core/src/nex/matchmake.rs | 36 +++++++++++++++------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 1129c76..f449ddc 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -239,33 +239,29 @@ impl ExtendedMatchmakeSession { continue; } */ - for pid in &list_of_connected_pids { - if other_conn.pid != self.session.gathering.host_pid && other_conn.pid == *pid { - continue; - } - other_conn - .remote - .process_notification_event(NotificationEvent { - pid_source: initiating_pid, - notif_type: 3001, - param_1: self.session.gathering.self_gid as PID, - param_2: *pid, - str_param: join_msg.clone(), - param_3: self.connected_players.len() as _, - }) - .await; - } + // for pid in &list_of_connected_pids { + other_conn + .remote + .process_notification_event(NotificationEvent { + pid_source: initiating_pid, + notif_type: 3001, + param_1: self.session.gathering.self_gid as PID, + param_2: other_conn.pid, + str_param: join_msg.clone(), + param_3: self.connected_players.len() as _, + }) + .await; + // } } for old_conns in &old_particip { let Some(old_conns) = old_conns.upgrade() else { continue; }; + if old_conns.pid != self.session.gathering.host_pid { + continue; + } for new_conn_pid in conns.iter().filter_map(Weak::upgrade).map(|c| c.pid) { - if old_conns.pid != self.session.gathering.host_pid && old_conns.pid == new_conn_pid - { - continue; - } old_conns .remote .process_notification_event(NotificationEvent { From 9fdca492c407faf0fac28a45d90ac8d7505135ab Mon Sep 17 00:00:00 2001 From: Maple Date: Fri, 24 Apr 2026 23:32:47 +0200 Subject: [PATCH 100/203] yet another another attempt --- rnex-core/src/nex/matchmake.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index f449ddc..d5bdab4 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -246,13 +246,36 @@ impl ExtendedMatchmakeSession { pid_source: initiating_pid, notif_type: 3001, param_1: self.session.gathering.self_gid as PID, - param_2: other_conn.pid, + param_2: *pid, str_param: join_msg.clone(), param_3: self.connected_players.len() as _, }) .await; // } } + for other_connection in conns { + let Some(other_conn) = other_connection.upgrade() else { + continue; + }; + + for old_participant in &old_particip { + let Some(old_particip) = old_participant.upgrade() else { + continue; + }; + + other_conn + .remote + .process_notification_event(NotificationEvent { + pid_source: initiating_pid, + notif_type: 3001, + param_1: self.session.gathering.self_gid as PID, + param_2: old_particip.pid, + str_param: join_msg.clone(), + param_3: self.connected_players.len() as _, + }) + .await; + } + } for old_conns in &old_particip { let Some(old_conns) = old_conns.upgrade() else { From 9352687a4a4671fb1377173b2d141f920a080d7f Mon Sep 17 00:00:00 2001 From: Maple Date: Fri, 24 Apr 2026 23:43:57 +0200 Subject: [PATCH 101/203] fix building --- rnex-core/src/nex/matchmake.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index d5bdab4..a1a1f4c 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -246,7 +246,7 @@ impl ExtendedMatchmakeSession { pid_source: initiating_pid, notif_type: 3001, param_1: self.session.gathering.self_gid as PID, - param_2: *pid, + param_2: other_conn.pid, str_param: join_msg.clone(), param_3: self.connected_players.len() as _, }) From 40793af5c3fc7742ed0851a8c022426c7529f715 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 00:06:04 +0200 Subject: [PATCH 102/203] revert mostly back and try less big changes --- rnex-core/src/nex/matchmake.rs | 36 +++++----------------------------- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index a1a1f4c..0a18f74 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -234,42 +234,15 @@ impl ExtendedMatchmakeSession { joining_pid == self.session.gathering.owner_pid{ continue; }*/ - /* - if other_conn.pid != self.session.gathering.host_pid { - continue; - } */ - - // for pid in &list_of_connected_pids { - other_conn - .remote - .process_notification_event(NotificationEvent { - pid_source: initiating_pid, - notif_type: 3001, - param_1: self.session.gathering.self_gid as PID, - param_2: other_conn.pid, - str_param: join_msg.clone(), - param_3: self.connected_players.len() as _, - }) - .await; - // } - } - for other_connection in conns { - let Some(other_conn) = other_connection.upgrade() else { - continue; - }; - - for old_participant in &old_particip { - let Some(old_particip) = old_participant.upgrade() else { - continue; - }; + for pid in &list_of_connected_pids { other_conn .remote .process_notification_event(NotificationEvent { pid_source: initiating_pid, notif_type: 3001, param_1: self.session.gathering.self_gid as PID, - param_2: old_particip.pid, + param_2: *pid, str_param: join_msg.clone(), param_3: self.connected_players.len() as _, }) @@ -281,9 +254,9 @@ impl ExtendedMatchmakeSession { let Some(old_conns) = old_conns.upgrade() else { continue; }; - if old_conns.pid != self.session.gathering.host_pid { + /*if old_conns.pid != self.session.gathering.host_pid { continue; - } + }*/ for new_conn_pid in conns.iter().filter_map(Weak::upgrade).map(|c| c.pid) { old_conns .remote @@ -299,6 +272,7 @@ impl ExtendedMatchmakeSession { } } } + pub fn has_active_players(&self) -> bool { self.connected_players .iter() From 731fa91b72d5316266bc4513020685e854bdf4af Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 10:52:40 +0200 Subject: [PATCH 103/203] fix potential crash bug --- rnex-core/src/nex/user.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 29d5332..57c36d8 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -657,7 +657,9 @@ impl Ranking for User { let mut wins = vec![0u32, 0u32]; for r in &results { let won_team = r.team_id ^ (!r.team_win); - wins[won_team as usize] += 1; + if let Some(team) = wins.get_mut(won_team as usize) { + *team += 1 + }; } let score_data: Vec = results From 58c9e43fa3e2352822e2d470b979526ddd673e3f Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 12:59:49 +0200 Subject: [PATCH 104/203] add fragments to v0 outgoing packets --- prudpv0/src/server.rs | 85 +++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 34c7647..a336abb 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -106,50 +106,55 @@ impl Server { .expect("packet malformed in creation"), );*/ let mut inner = conn.inner.lock().await; - let seq = inner.server_packet_counter; - let packet = new_data_packet( - NEED_ACK | RELIABLE, - self.param.virtual_port, - conn.addr.virtual_port, - data, - inner.server_packet_counter, - conn.session_id, - 0, - &mut inner.crypto_instance, - &self.crypto, - ); - inner.server_packet_counter += 1; + let pieces = data.chunks(1000); + let max_piece = pieces.len() - 1; + let mut frag_num = 1; + for (i, piece) in pieces.enumerate() { + let seq = inner.server_packet_counter; + let packet = new_data_packet( + NEED_ACK | RELIABLE, + (&self).param.virtual_port, + conn.addr.virtual_port, + piece, + inner.server_packet_counter, + conn.session_id, + if i == max_piece { 0 } else { frag_num }, + &mut inner.crypto_instance, + &(&self).crypto, + ); + inner.server_packet_counter += 1; - let packet = Arc::new(packet); - let packet_ref = Arc::downgrade(&packet); + let packet = Arc::new(packet); + let packet_ref = Arc::downgrade(&packet); - inner.unacknowledged_packets.insert(seq, packet); + inner.unacknowledged_packets.insert(seq, packet); + let conn = Arc::downgrade(&conn); + let this = Arc::downgrade(&self); + + spawn(async move { + for n in 0..5 { + let Some(data) = packet_ref.upgrade() else { + return; + }; + let Some(conn) = conn.upgrade() else { + return; + }; + let Some(this) = this.upgrade() else { + return; + }; + info!("send attempt {}", n); + + self.socket + .send_to(&data, conn.addr.regular_socket_addr) + .await; + + break; + } + }); + frag_num += 1; + } drop(inner); - - let conn = Arc::downgrade(&conn); - let this = Arc::downgrade(&self); - - spawn(async move { - for n in 0..5 { - let Some(data) = packet_ref.upgrade() else { - return; - }; - let Some(conn) = conn.upgrade() else { - return; - }; - let Some(this) = this.upgrade() else { - return; - }; - info!("send attempt {}", n); - - self.socket - .send_to(&data, conn.addr.regular_socket_addr) - .await; - - break; - } - }); } async fn connection_thread( self: Arc, From 20fc294a36a0f276c4a0b466412a89c2116bf37e Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 14:15:42 +0200 Subject: [PATCH 105/203] implement friendships --- rnex-core/src/executables/friends_backend.rs | 11 +- rnex-core/src/nex/friends_handler.rs | 136 ++++++++++++++++-- rnex-core/src/rmc/protocols/friends.rs | 6 +- rnex-core/src/rmc/protocols/mod.rs | 1 + .../rmc/protocols/nintendo_notification.rs | 39 +++++ rnex-core/src/rmc/structures/any.rs | 21 ++- rnex-core/src/rmc/structures/mod.rs | 3 + 7 files changed, 196 insertions(+), 21 deletions(-) create mode 100644 rnex-core/src/rmc/protocols/nintendo_notification.rs diff --git a/rnex-core/src/executables/friends_backend.rs b/rnex-core/src/executables/friends_backend.rs index 74983f7..6dceda1 100644 --- a/rnex-core/src/executables/friends_backend.rs +++ b/rnex-core/src/executables/friends_backend.rs @@ -9,10 +9,12 @@ use tokio::net::TcpListener; use crate::{ executables::common::{OWN_IP_PRIVATE, SERVER_PORT, new_simple_backend}, - nex::friends_handler::{FriendsGuest, FriendsManager, FriendsUser}, + nex::friends_handler::{FriendsGuest, FriendsManager, FriendsUser, RemoteFriendsUser}, reggie::UnitPacketRead, rmc::{ - protocols::{RmcCallable, new_rmc_gateway_connection}, + protocols::{ + RmcCallable, RmcPureRemoteObject, friends::RemoteFriends, new_rmc_gateway_connection, + }, structures::RmcSerialize, }, rnex_proxy_common::ConnectionInitData, @@ -21,6 +23,7 @@ use crate::{ pub async fn start_friends_backend() { let fm = Arc::new(FriendsManager { cid_counter: AtomicU32::new(1), + users: Default::default(), }); let listen = TcpListener::bind(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) .await @@ -53,6 +56,10 @@ pub async fn start_friends_backend() { fm, addr: c.prudpsock_addr, pid: c.pid, + data: Default::default(), + current_friends: Default::default(), + this: this.clone(), + remote: RemoteFriendsUser::new(r), }) }); } else { diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 42e5c71..2d9c2a8 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -1,4 +1,6 @@ use std::io::{Cursor, Write}; +use std::ops::Deref; +use std::sync::Weak; use std::sync::{Arc, atomic::AtomicU32}; use bytemuck::bytes_of; @@ -9,6 +11,10 @@ use rnex_core::rmc::protocols::account_management::{ AccountManagement, RawAccountManagement, RawAccountManagementInfo, RemoteAccountManagement, }; use rnex_core::rmc::protocols::friends::{Friends, RawFriends, RawFriendsInfo, RemoteFriends}; +use rnex_core::rmc::protocols::nintendo_notification::{ + NintendoNotification, RawNintendoNotification, RawNintendoNotificationInfo, + RemoteNintendoNotification, +}; use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; use rnex_core::{ define_rmc_proto, @@ -25,12 +31,15 @@ use rnex_core::{ }, }; use std::sync::atomic::Ordering::Relaxed; +use tokio::sync::RwLock; use rnex_core::rmc::protocols::friends::{GameKey, MiiV2, PrincipalBasicInfo}; use rnex_core::PID; +use crate::nex::user; use crate::rmc::protocols::account_management::NintendoCreateAccountData; +use crate::rmc::protocols::nintendo_notification::NintendoNotificationEvent; use rnex_core::rmc::structures::RmcSerialize; define_rmc_proto!( @@ -39,17 +48,32 @@ define_rmc_proto!( Friends } ); +define_rmc_proto!( + proto FriendRemote{ + NintendoNotification + } +); define_rmc_proto!( proto FriendsGuest{ Secure, AccountManagement } ); + +pub struct UserData { + info: NNAInfo, + presence: NintendoPresenceV2, +} + #[rmc_struct(FriendsUser)] pub struct FriendsUser { pub fm: Arc, pub addr: PRUDPSockAddr, pub pid: PID, + pub data: RwLock>, + pub current_friends: RwLock>, + pub this: Weak, + pub remote: RemoteFriendRemote, } #[rmc_struct(FriendsGuest)] @@ -60,6 +84,7 @@ pub struct FriendsGuest { pub struct FriendsManager { pub cid_counter: AtomicU32, + pub users: RwLock>>, } impl FriendsManager { @@ -68,11 +93,26 @@ impl FriendsManager { } } +pub fn friend_info_from_user(data: &UserData) -> FriendInfo { + FriendInfo { + nna_info: data.info.clone(), + presence: data.presence.clone(), + comment: Comment { + unk: 0, + message: "litterally everyone is friends here =w=".to_string(), + last_changed: KerberosDateTime::now(), + }, + became_friends: KerberosDateTime::now(), + last_online: KerberosDateTime::now(), + unk: 0, + } +} + impl Friends for FriendsUser { async fn update_and_get_all_information( &self, - _info: NNAInfo, - _presence: NintendoPresenceV2, + info: NNAInfo, + presence: NintendoPresenceV2, _date_time: KerberosDateTime, ) -> Result< ( @@ -88,17 +128,15 @@ impl Friends for FriendsUser { ), ErrorCode, > { - Ok(( - PrincipalPreference { - block_friend_request: false, - show_online: false, - show_playing_title: false, - }, - Comment { - last_changed: KerberosDateTime::now(), - message: "".to_string(), - unk: 0, - }, + let mut data = self.data.write().await; + *data = Some(UserData { info, presence }); + let self_fr_info = friend_info_from_user(data.as_ref().unwrap()); + let Ok(any_self_fr_info) = Any::new(&self_fr_info) else { + return Err(ErrorCode::RendezVous_ControlScriptFailure); + }; + drop(data); + + let mut fr_list = vec![FriendInfo { became_friends: KerberosDateTime::now(), comment: Comment { @@ -144,7 +182,51 @@ impl Friends for FriendsUser { unk7: 0 }, unk: 0 - }], + }]; + + let users = self.fm.users.read().await; + let mut curr_friends = self.current_friends.write().await; + for u in users.deref().iter().filter_map(|u| u.upgrade()) { + let data = u.data.read().await; + let Some(data) = data.as_ref() else { + continue; + }; + + let mut fr = u.current_friends.write().await; + if !fr.contains(&self.pid) { + fr.push(self.pid); + u.remote + .process_nintendo_notification_event_1(NintendoNotificationEvent { + event_type: 30, + sender: self.pid, + data: any_self_fr_info.clone(), + }) + .await; + } + drop(fr); + + fr_list.push(friend_info_from_user(&data)); + curr_friends.push(u.pid); + } + drop(curr_friends); + drop(users); + + let mut users = self.fm.users.write().await; + users.push(self.this.clone()); + drop(users); + + Ok(( + PrincipalPreference { + block_friend_request: false, + show_online: false, + show_playing_title: false, + }, + Comment { + last_changed: KerberosDateTime::now(), + message: "".to_string(), + unk: 0, + }, + fr_list, vec![], vec![], vec![], @@ -154,6 +236,32 @@ impl Friends for FriendsUser { )) } + async fn update_presence(&self, presence: NintendoPresenceV2) -> Result<(), ErrorCode> { + let mut data = self.data.write().await; + let Some(data) = data.as_mut() else { + return Err(ErrorCode::RendezVous_PermissionDenied); + }; + data.presence = presence; + let Ok(any_self_fr_info) = Any::new(&data.presence) else { + return Err(ErrorCode::RendezVous_ControlScriptFailure); + }; + drop(data); + + let users = self.fm.users.read().await; + for u in users.deref().iter().filter_map(|u| u.upgrade()) { + u.remote + .process_nintendo_notification_event_2(NintendoNotificationEvent { + event_type: 24, + sender: self.pid, + data: any_self_fr_info.clone(), + }) + .await; + } + drop(users); + + Ok(()) + } + async fn check_setting_status(&self) -> Result { Ok(0xFF) } diff --git a/rnex-core/src/rmc/protocols/friends.rs b/rnex-core/src/rmc/protocols/friends.rs index 3f6138f..fb179ce 100644 --- a/rnex-core/src/rmc/protocols/friends.rs +++ b/rnex-core/src/rmc/protocols/friends.rs @@ -29,14 +29,14 @@ pub struct NNAInfo { pub unk2: u8, } -#[derive(RmcSerialize)] +#[derive(RmcSerialize, Clone, Copy, Debug)] #[rmc_struct(0)] pub struct GameKey { pub tid: u64, pub version: u16, } -#[derive(RmcSerialize)] +#[derive(RmcSerialize, Clone, Debug)] #[rmc_struct(0)] pub struct NintendoPresenceV2 { pub changed_flags: u32, @@ -143,6 +143,8 @@ pub trait Friends { ), ErrorCode, >; + #[method_id(13)] + async fn update_presence(&self, presence: NintendoPresenceV2) -> Result<(), ErrorCode>; #[method_id(19)] async fn check_setting_status(&self) -> Result; } diff --git a/rnex-core/src/rmc/protocols/mod.rs b/rnex-core/src/rmc/protocols/mod.rs index 8feb2f3..eed0597 100644 --- a/rnex-core/src/rmc/protocols/mod.rs +++ b/rnex-core/src/rmc/protocols/mod.rs @@ -7,6 +7,7 @@ pub mod matchmake; pub mod matchmake_ext; pub mod matchmake_extension; pub mod nat_traversal; +pub mod nintendo_notification; pub mod notifications; pub mod ranking; pub mod secure; diff --git a/rnex-core/src/rmc/protocols/nintendo_notification.rs b/rnex-core/src/rmc/protocols/nintendo_notification.rs new file mode 100644 index 0000000..f7503fd --- /dev/null +++ b/rnex-core/src/rmc/protocols/nintendo_notification.rs @@ -0,0 +1,39 @@ +use macros::{RmcSerialize, method_id, rmc_proto}; + +use rnex_core::PID; +use rnex_core::rmc::structures::any::Any; + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct NintendoNotificationEvent { + pub event_type: u32, + pub sender: PID, + pub data: Any, +} + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct NintendoNotificationEventGeneral { + pub param1: u32, + pub param2: u64, + pub param3: u64, + pub str_param: String, +} + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct NintendoNotificationEventProfile { + pub region: u8, + pub country: u8, + pub area: u8, + pub language: u8, + pub platform: u8, +} + +#[rmc_proto(3, NoReturn)] +pub trait NintendoNotification { + #[method_id(1)] + async fn process_nintendo_notification_event_1(&self, notif: NintendoNotificationEvent); + #[method_id(2)] + async fn process_nintendo_notification_event_2(&self, notif: NintendoNotificationEvent); +} diff --git a/rnex-core/src/rmc/structures/any.rs b/rnex-core/src/rmc/structures/any.rs index c4dc2ce..45ab453 100644 --- a/rnex-core/src/rmc/structures/any.rs +++ b/rnex-core/src/rmc/structures/any.rs @@ -1,8 +1,8 @@ use rnex_core::rmc::structures::{Result, RmcSerialize}; -use std::io::{Read, Write}; +use std::io::{Cursor, Read, Write}; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub struct Any { pub name: String, pub data: Vec, @@ -14,7 +14,7 @@ impl RmcSerialize for Any { let u32_len = self.data.len() as u32; - u32_len.serialize(writer)?; + (u32_len + 4).serialize(writer)?; u32_len.serialize(writer)?; self.data.serialize(writer)?; @@ -35,3 +35,18 @@ impl RmcSerialize for Any { Ok(Any { name, data }) } } + +impl Any { + pub fn try_get(&self) -> Option> { + if self.name != T::name() { + return None; + } + return Some(T::deserialize(&mut Cursor::new(&self.data[..]))); + } + pub fn new(val: &T) -> Result { + return Ok(Self { + name: T::name().to_owned(), + data: val.to_data()?, + }); + } +} diff --git a/rnex-core/src/rmc/structures/mod.rs b/rnex-core/src/rmc/structures/mod.rs index 996cc4b..99bef0c 100644 --- a/rnex-core/src/rmc/structures/mod.rs +++ b/rnex-core/src/rmc/structures/mod.rs @@ -61,6 +61,9 @@ pub trait RmcSerialize { Ok(data) } + fn name() -> &'static str { + "NoNameSpecified" + } } impl RmcSerialize for () { From 0d026373db1db1a0f355ee348700a291e8b52715 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 14:24:33 +0200 Subject: [PATCH 106/203] fix compile error --- macros/src/lib.rs | 12 ++++++++++-- prudpv0/src/server.rs | 2 +- rnex-core/src/executables/friends_backend.rs | 6 ++++-- rnex-core/src/nex/friends_handler.rs | 5 ++--- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index d0fc909..432fc03 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -10,8 +10,8 @@ use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; use syn::spanned::Spanned; use syn::{ - parse_macro_input, Attribute, Data, DataStruct, DeriveInput, Fields, FnArg, LitInt, Pat, Token, - TraitItem, + parse_macro_input, Attribute, Data, DataStruct, DeriveInput, Fields, FnArg, Lit, LitInt, + LitStr, Pat, Token, TraitItem, }; struct ProtoInputParams { @@ -400,6 +400,10 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { // generate base data + let str_name = Lit::Str(LitStr::new( + &derive_input.ident.to_string(), + derive_input.ident.span(), + )); let ident = derive_input.ident; let tokens = quote! { @@ -414,6 +418,10 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { } #write_size + + fn name() -> &'static str{ + #str_name + } } }; diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index a336abb..d7a6dcc 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -145,7 +145,7 @@ impl Server { }; info!("send attempt {}", n); - self.socket + this.socket .send_to(&data, conn.addr.regular_socket_addr) .await; diff --git a/rnex-core/src/executables/friends_backend.rs b/rnex-core/src/executables/friends_backend.rs index 6dceda1..5dfcf02 100644 --- a/rnex-core/src/executables/friends_backend.rs +++ b/rnex-core/src/executables/friends_backend.rs @@ -9,7 +9,9 @@ use tokio::net::TcpListener; use crate::{ executables::common::{OWN_IP_PRIVATE, SERVER_PORT, new_simple_backend}, - nex::friends_handler::{FriendsGuest, FriendsManager, FriendsUser, RemoteFriendsUser}, + nex::friends_handler::{ + FriendsGuest, FriendsManager, FriendsUser, RemoteFriendRemote, RemoteFriendsUser, + }, reggie::UnitPacketRead, rmc::{ protocols::{ @@ -59,7 +61,7 @@ pub async fn start_friends_backend() { data: Default::default(), current_friends: Default::default(), this: this.clone(), - remote: RemoteFriendsUser::new(r), + remote: RemoteFriendRemote::new(r), }) }); } else { diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 2d9c2a8..adab2b9 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -37,9 +37,8 @@ use rnex_core::rmc::protocols::friends::{GameKey, MiiV2, PrincipalBasicInfo}; use rnex_core::PID; -use crate::nex::user; -use crate::rmc::protocols::account_management::NintendoCreateAccountData; -use crate::rmc::protocols::nintendo_notification::NintendoNotificationEvent; +use rnex_core::rmc::protocols::account_management::NintendoCreateAccountData; +use rnex_core::rmc::protocols::nintendo_notification::NintendoNotificationEvent; use rnex_core::rmc::structures::RmcSerialize; define_rmc_proto!( From 02c08e6c759e43e746662761950078fa3bda6db1 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 15:06:00 +0200 Subject: [PATCH 107/203] add debugging --- rnex-core/src/nex/friends_handler.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index adab2b9..64b359c 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -127,6 +127,7 @@ impl Friends for FriendsUser { ), ErrorCode, > { + println!("updating own data"); let mut data = self.data.write().await; *data = Some(UserData { info, presence }); let self_fr_info = friend_info_from_user(data.as_ref().unwrap()); @@ -183,8 +184,10 @@ impl Friends for FriendsUser { unk: 0 }]; + println!("acquiring user and current friends locks"); let users = self.fm.users.read().await; let mut curr_friends = self.current_friends.write().await; + println!("started summing users"); for u in users.deref().iter().filter_map(|u| u.upgrade()) { let data = u.data.read().await; let Some(data) = data.as_ref() else { @@ -207,13 +210,16 @@ impl Friends for FriendsUser { fr_list.push(friend_info_from_user(&data)); curr_friends.push(u.pid); } + println!("finished summing users"); drop(curr_friends); drop(users); + println!("adding self to users"); let mut users = self.fm.users.write().await; users.push(self.this.clone()); drop(users); + println!("done..."); Ok(( PrincipalPreference { block_friend_request: false, @@ -237,11 +243,11 @@ impl Friends for FriendsUser { async fn update_presence(&self, presence: NintendoPresenceV2) -> Result<(), ErrorCode> { let mut data = self.data.write().await; - let Some(data) = data.as_mut() else { + let Some(inner_data) = data.as_mut() else { return Err(ErrorCode::RendezVous_PermissionDenied); }; - data.presence = presence; - let Ok(any_self_fr_info) = Any::new(&data.presence) else { + inner_data.presence = presence; + let Ok(any_self_fr_info) = Any::new(&inner_data.presence) else { return Err(ErrorCode::RendezVous_ControlScriptFailure); }; drop(data); From aaa530341d6748dae2cc77a676c2c8d379d8e23b Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 15:23:53 +0200 Subject: [PATCH 108/203] minimize the time we hold locks for and add sleep --- prudpv0/src/server.rs | 1 + rnex-core/src/nex/friends_handler.rs | 37 +++++++++++++++++----------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index d7a6dcc..9a32bc7 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -153,6 +153,7 @@ impl Server { } }); frag_num += 1; + sleep(Duration::from_millis(16)).await; } drop(inner); } diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 64b359c..1a0b499 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -31,6 +31,7 @@ use rnex_core::{ }, }; use std::sync::atomic::Ordering::Relaxed; +use tokio::spawn; use tokio::sync::RwLock; use rnex_core::rmc::protocols::friends::{GameKey, MiiV2, PrincipalBasicInfo}; @@ -186,32 +187,40 @@ impl Friends for FriendsUser { println!("acquiring user and current friends locks"); let users = self.fm.users.read().await; - let mut curr_friends = self.current_friends.write().await; println!("started summing users"); for u in users.deref().iter().filter_map(|u| u.upgrade()) { let data = u.data.read().await; - let Some(data) = data.as_ref() else { + let Some(inner_data) = data.as_ref() else { continue; }; + fr_list.push(friend_info_from_user(&inner_data)); + drop(data); + + let mut curr_friends = self.current_friends.write().await; + curr_friends.push(u.pid); + drop(curr_friends); let mut fr = u.current_friends.write().await; if !fr.contains(&self.pid) { fr.push(self.pid); - u.remote - .process_nintendo_notification_event_1(NintendoNotificationEvent { - event_type: 30, - sender: self.pid, - data: any_self_fr_info.clone(), - }) - .await; + drop(fr); + let data = any_self_fr_info.clone(); + let u = u.clone(); + let sender = self.pid; + spawn(async move { + u.remote + .process_nintendo_notification_event_1(NintendoNotificationEvent { + event_type: 30, + sender, + data, + }) + .await; + }); + } else { + drop(fr); } - drop(fr); - - fr_list.push(friend_info_from_user(&data)); - curr_friends.push(u.pid); } println!("finished summing users"); - drop(curr_friends); drop(users); println!("adding self to users"); From f9ce137c046a4983b0c987825165fdb2d68efe6f Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 15:41:58 +0200 Subject: [PATCH 109/203] sleep inside the packet send task instead of outside --- prudpv0/src/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 9a32bc7..022f6da 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -133,6 +133,7 @@ impl Server { let this = Arc::downgrade(&self); spawn(async move { + sleep(Duration::from_millis(i as u64 * 16)).await; for n in 0..5 { let Some(data) = packet_ref.upgrade() else { return; @@ -153,7 +154,6 @@ impl Server { } }); frag_num += 1; - sleep(Duration::from_millis(16)).await; } drop(inner); } From 2c08e35c36c0a910f4429bc3901ad3ac8b4a6d18 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 16:40:54 +0200 Subject: [PATCH 110/203] make fragment size smaller --- prudpv0/src/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 022f6da..899bbd6 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -106,7 +106,7 @@ impl Server { .expect("packet malformed in creation"), );*/ let mut inner = conn.inner.lock().await; - let pieces = data.chunks(1000); + let pieces = data.chunks(700); let max_piece = pieces.len() - 1; let mut frag_num = 1; for (i, piece) in pieces.enumerate() { From 666a0b1ad7c6f202e1b94c3959d79d4e9159860d Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 16:56:55 +0200 Subject: [PATCH 111/203] fix nintendo notifications --- rnex-core/src/rmc/protocols/nintendo_notification.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rnex-core/src/rmc/protocols/nintendo_notification.rs b/rnex-core/src/rmc/protocols/nintendo_notification.rs index f7503fd..ae31467 100644 --- a/rnex-core/src/rmc/protocols/nintendo_notification.rs +++ b/rnex-core/src/rmc/protocols/nintendo_notification.rs @@ -30,7 +30,7 @@ pub struct NintendoNotificationEventProfile { pub platform: u8, } -#[rmc_proto(3, NoReturn)] +#[rmc_proto(100, NoReturn)] pub trait NintendoNotification { #[method_id(1)] async fn process_nintendo_notification_event_1(&self, notif: NintendoNotificationEvent); From 51e7c63d667e80ee596b1dfab13c2303edcd4167 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 17:24:28 +0200 Subject: [PATCH 112/203] add delete persistent notif --- rnex-core/src/nex/friends_handler.rs | 9 ++++++++- rnex-core/src/rmc/protocols/friends.rs | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 1a0b499..88190b2 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -99,7 +99,7 @@ pub fn friend_info_from_user(data: &UserData) -> FriendInfo { presence: data.presence.clone(), comment: Comment { unk: 0, - message: "litterally everyone is friends here =w=".to_string(), + message: "haii =w=".to_string(), last_changed: KerberosDateTime::now(), }, became_friends: KerberosDateTime::now(), @@ -276,6 +276,13 @@ impl Friends for FriendsUser { Ok(()) } + async fn delete_persistent_notification( + &self, + notifs: Vec, + ) -> Result<(), ErrorCode> { + Ok(()) + } + async fn check_setting_status(&self) -> Result { Ok(0xFF) } diff --git a/rnex-core/src/rmc/protocols/friends.rs b/rnex-core/src/rmc/protocols/friends.rs index fb179ce..b575c08 100644 --- a/rnex-core/src/rmc/protocols/friends.rs +++ b/rnex-core/src/rmc/protocols/friends.rs @@ -2,6 +2,8 @@ use macros::{RmcSerialize, method_id, rmc_proto}; use rnex_core::{kerberos::KerberosDateTime, rmc::response::ErrorCode}; +use crate::rmc::structures::rmc_struct; + #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] pub struct MiiV2 { @@ -145,6 +147,11 @@ pub trait Friends { >; #[method_id(13)] async fn update_presence(&self, presence: NintendoPresenceV2) -> Result<(), ErrorCode>; + #[method_id(18)] + async fn delete_persistent_notification( + &self, + notifs: Vec, + ) -> Result<(), ErrorCode>; #[method_id(19)] async fn check_setting_status(&self) -> Result; } From f6318f082ebaae5cce12645f285168d5512bfa67 Mon Sep 17 00:00:00 2001 From: red binder Date: Sat, 25 Apr 2026 18:05:47 +0200 Subject: [PATCH 113/203] wii u chat --- editions.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/editions.yaml b/editions.yaml index 40c2e10..d3c5a54 100644 --- a/editions.yaml +++ b/editions.yaml @@ -1,3 +1,13 @@ +wiiu-chat: + features: + - prudpv1 + - v3-8-15 + settings: + AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" + RNEX_VIRTUAL_PORT_INSECURE: "1:10" + RNEX_VIRTUAL_PORT_SECURE: "1:10" + RNEX_DEFAULT_PORT: 10000 + RNEX_ACCESS_KEY: "e7a47214" splatoon: features: - prudpv1 From 3c8ba491ddf2864634a5c84df685d2e7938254dc Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 18:40:32 +0200 Subject: [PATCH 114/203] add data --- rnex-core/src/nex/friends_handler.rs | 3 +++ rnex-core/src/rmc/protocols/friends.rs | 4 +++- rnex-core/src/rmc/structures/data.rs | 5 +++++ rnex-core/src/rmc/structures/mod.rs | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 rnex-core/src/rmc/structures/data.rs diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 88190b2..b7f44e8 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -42,6 +42,8 @@ use rnex_core::rmc::protocols::account_management::NintendoCreateAccountData; use rnex_core::rmc::protocols::nintendo_notification::NintendoNotificationEvent; use rnex_core::rmc::structures::RmcSerialize; +use crate::rmc::structures::data::Data; + define_rmc_proto!( proto FriendsUser{ Secure, @@ -95,6 +97,7 @@ impl FriendsManager { pub fn friend_info_from_user(data: &UserData) -> FriendInfo { FriendInfo { + data: Data {}, nna_info: data.info.clone(), presence: data.presence.clone(), comment: Comment { diff --git a/rnex-core/src/rmc/protocols/friends.rs b/rnex-core/src/rmc/protocols/friends.rs index b575c08..766797f 100644 --- a/rnex-core/src/rmc/protocols/friends.rs +++ b/rnex-core/src/rmc/protocols/friends.rs @@ -2,7 +2,7 @@ use macros::{RmcSerialize, method_id, rmc_proto}; use rnex_core::{kerberos::KerberosDateTime, rmc::response::ErrorCode}; -use crate::rmc::structures::rmc_struct; +use crate::rmc::structures::{data::Data, rmc_struct}; #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] @@ -76,6 +76,8 @@ pub struct Comment { #[derive(RmcSerialize)] #[rmc_struct(0)] pub struct FriendInfo { + #[extends] + pub data: Data, pub nna_info: NNAInfo, pub presence: NintendoPresenceV2, pub comment: Comment, diff --git a/rnex-core/src/rmc/structures/data.rs b/rnex-core/src/rmc/structures/data.rs new file mode 100644 index 0000000..0350c96 --- /dev/null +++ b/rnex-core/src/rmc/structures/data.rs @@ -0,0 +1,5 @@ +use macros::RmcSerialize; + +#[derive(RmcSerialize)] +#[rmc_struct(0)] +pub struct Data {} diff --git a/rnex-core/src/rmc/structures/mod.rs b/rnex-core/src/rmc/structures/mod.rs index 99bef0c..35dce08 100644 --- a/rnex-core/src/rmc/structures/mod.rs +++ b/rnex-core/src/rmc/structures/mod.rs @@ -26,6 +26,7 @@ pub type Result = std::result::Result; pub mod any; pub mod buffer; pub mod connection_data; +pub mod data; pub mod helpers; pub mod list; pub mod matchmake; From 3e8b96c82008bfe9dcc0f7c2e7b367a23119d6c5 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 18:49:18 +0200 Subject: [PATCH 115/203] fix build error --- rnex-core/src/nex/friends_handler.rs | 3 ++- rnex-core/src/rmc/protocols/friends.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index b7f44e8..08cca05 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -42,7 +42,7 @@ use rnex_core::rmc::protocols::account_management::NintendoCreateAccountData; use rnex_core::rmc::protocols::nintendo_notification::NintendoNotificationEvent; use rnex_core::rmc::structures::RmcSerialize; -use crate::rmc::structures::data::Data; +use rnex_core::rmc::structures::data::Data; define_rmc_proto!( proto FriendsUser{ @@ -142,6 +142,7 @@ impl Friends for FriendsUser { let mut fr_list = vec![FriendInfo { + data: Data{}, became_friends: KerberosDateTime::now(), comment: Comment { last_changed: KerberosDateTime::now(), diff --git a/rnex-core/src/rmc/protocols/friends.rs b/rnex-core/src/rmc/protocols/friends.rs index 766797f..fa32120 100644 --- a/rnex-core/src/rmc/protocols/friends.rs +++ b/rnex-core/src/rmc/protocols/friends.rs @@ -2,7 +2,7 @@ use macros::{RmcSerialize, method_id, rmc_proto}; use rnex_core::{kerberos::KerberosDateTime, rmc::response::ErrorCode}; -use crate::rmc::structures::{data::Data, rmc_struct}; +use rnex_core::rmc::structures::{data::Data, rmc_struct}; #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] From 9d89bc56e02f963fe379af8e622490dfb972ff53 Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 19:15:23 +0200 Subject: [PATCH 116/203] add data to structs which were missing it --- rnex-core/src/nex/friends_handler.rs | 98 ++++++++++++++------------ rnex-core/src/rmc/protocols/friends.rs | 22 ++++++ rnex-core/src/rmc/structures/data.rs | 2 +- 3 files changed, 76 insertions(+), 46 deletions(-) diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 08cca05..941b747 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -101,6 +101,7 @@ pub fn friend_info_from_user(data: &UserData) -> FriendInfo { nna_info: data.info.clone(), presence: data.presence.clone(), comment: Comment { + data: Data {}, unk: 0, message: "haii =w=".to_string(), last_changed: KerberosDateTime::now(), @@ -140,54 +141,59 @@ impl Friends for FriendsUser { }; drop(data); - let mut fr_list = - vec![FriendInfo { + let mut fr_list = vec![FriendInfo { + data: Data{}, + became_friends: KerberosDateTime::now(), + comment: Comment { data: Data{}, - became_friends: KerberosDateTime::now(), - comment: Comment { - last_changed: KerberosDateTime::now(), - message: "I'm just a dummy account :3".to_string(), - unk: 0, - }, - last_online: KerberosDateTime::now(), - nna_info: NNAInfo { - principal_basic_info: PrincipalBasicInfo { - pid: 101, - nnid: "dummy:3".to_string(), - mii: MiiV2{ - date_time: KerberosDateTime::now(), - name: "TheDummy".to_string(), - mii_data: hex::decode("030000402bd7c32986a771f2dc6b35e31da15e37ff7c0000391e6f006f006d0069000000000000000000000000004040001065033568641e2013661a611821640f0000290052485000000000000000000000000000000000000000000000e838").unwrap(), - unk: 0, - unk2: 0, - }, - unk: 0 - }, - unk: 0, - unk2: 0 - }, - presence: NintendoPresenceV2{ - changed_flags: 0, - message: "".to_string(), - app_data: vec![], - game_key: GameKey{ - tid: 0x00050002101ce400, - version: 0x0 - }, - game_server_id: 0, - is_online: true, - gid: 0, + last_changed: KerberosDateTime::now(), + message: "I'm just a dummy account :3".to_string(), + unk: 0, + }, + last_online: KerberosDateTime::now(), + nna_info: NNAInfo { + data: Data{}, + principal_basic_info: PrincipalBasicInfo { + data: Data{}, pid: 101, - unk: 0, - unk2: 0, - unk3: 0, - unk4: 0, - unk5: 0, - unk6: 0, - unk7: 0 + nnid: "dummy:3".to_string(), + mii: MiiV2{ + data: Data{}, + date_time: KerberosDateTime::now(), + name: "TheDummy".to_string(), + mii_data: hex::decode("030000402bd7c32986a771f2dc6b35e31da15e37ff7c0000391e6f006f006d0069000000000000000000000000004040001065033568641e2013661a611821640f0000290052485000000000000000000000000000000000000000000000e838").unwrap(), + unk: 0, + unk2: 0, + }, + unk: 0 }, - unk: 0 - }]; + unk: 0, + unk2: 0 + }, + presence: NintendoPresenceV2{ + data: Data{}, + changed_flags: 0, + message: "".to_string(), + app_data: vec![], + game_key: GameKey{ + data: Data{}, + tid: 0x00050002101ce400, + version: 0x0 + }, + game_server_id: 0, + is_online: true, + gid: 0, + pid: 101, + unk: 0, + unk2: 0, + unk3: 0, + unk4: 0, + unk5: 0, + unk6: 0, + unk7: 0 + }, + unk: 0 + }]; println!("acquiring user and current friends locks"); let users = self.fm.users.read().await; @@ -235,11 +241,13 @@ impl Friends for FriendsUser { println!("done..."); Ok(( PrincipalPreference { + data: Data {}, block_friend_request: false, show_online: false, show_playing_title: false, }, Comment { + data: Data {}, last_changed: KerberosDateTime::now(), message: "".to_string(), unk: 0, diff --git a/rnex-core/src/rmc/protocols/friends.rs b/rnex-core/src/rmc/protocols/friends.rs index fa32120..81dd63e 100644 --- a/rnex-core/src/rmc/protocols/friends.rs +++ b/rnex-core/src/rmc/protocols/friends.rs @@ -7,6 +7,8 @@ use rnex_core::rmc::structures::{data::Data, rmc_struct}; #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] pub struct MiiV2 { + #[extends] + pub data: Data, pub name: String, pub unk: u8, pub unk2: u8, @@ -17,6 +19,8 @@ pub struct MiiV2 { #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] pub struct PrincipalBasicInfo { + #[extends] + pub data: Data, pub pid: u32, pub nnid: String, pub mii: MiiV2, @@ -26,6 +30,8 @@ pub struct PrincipalBasicInfo { #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] pub struct NNAInfo { + #[extends] + pub data: Data, pub principal_basic_info: PrincipalBasicInfo, pub unk: u8, pub unk2: u8, @@ -34,6 +40,8 @@ pub struct NNAInfo { #[derive(RmcSerialize, Clone, Copy, Debug)] #[rmc_struct(0)] pub struct GameKey { + #[extends] + pub data: Data, pub tid: u64, pub version: u16, } @@ -41,6 +49,8 @@ pub struct GameKey { #[derive(RmcSerialize, Clone, Debug)] #[rmc_struct(0)] pub struct NintendoPresenceV2 { + #[extends] + pub data: Data, pub changed_flags: u32, pub is_online: bool, pub game_key: GameKey, @@ -60,6 +70,8 @@ pub struct NintendoPresenceV2 { #[derive(RmcSerialize)] #[rmc_struct(0)] pub struct PrincipalPreference { + #[extends] + pub data: Data, pub show_online: bool, pub show_playing_title: bool, pub block_friend_request: bool, @@ -68,6 +80,8 @@ pub struct PrincipalPreference { #[derive(RmcSerialize)] #[rmc_struct(0)] pub struct Comment { + #[extends] + pub data: Data, pub unk: u8, pub message: String, pub last_changed: KerberosDateTime, @@ -89,6 +103,8 @@ pub struct FriendInfo { #[derive(RmcSerialize)] #[rmc_struct(0)] pub struct FriendRequestMessage { + #[extends] + pub data: Data, pub friend_request_id: u64, pub is_recieved: u8, pub unk: u8, @@ -103,6 +119,8 @@ pub struct FriendRequestMessage { #[derive(RmcSerialize)] #[rmc_struct(0)] pub struct FriendRequest { + #[extends] + pub data: Data, pub basic_info: PrincipalBasicInfo, pub request_message: FriendRequestMessage, pub sent_on: KerberosDateTime, @@ -111,6 +129,8 @@ pub struct FriendRequest { #[derive(RmcSerialize)] #[rmc_struct(0)] pub struct BlacklistedPrincipal { + #[extends] + pub data: Data, pub basic_info: PrincipalBasicInfo, pub game_key: GameKey, pub since: KerberosDateTime, @@ -118,6 +138,8 @@ pub struct BlacklistedPrincipal { #[derive(RmcSerialize)] #[rmc_struct(0)] pub struct PersistentNotification { + #[extends] + pub data: Data, pub unk1: u64, pub unk2: u32, pub unk3: u32, diff --git a/rnex-core/src/rmc/structures/data.rs b/rnex-core/src/rmc/structures/data.rs index 0350c96..c6064ae 100644 --- a/rnex-core/src/rmc/structures/data.rs +++ b/rnex-core/src/rmc/structures/data.rs @@ -1,5 +1,5 @@ use macros::RmcSerialize; -#[derive(RmcSerialize)] +#[derive(RmcSerialize, Debug, Clone, Copy)] #[rmc_struct(0)] pub struct Data {} From c705b59e314059cda872a68d8665e1d0d046390f Mon Sep 17 00:00:00 2001 From: Maple Date: Sat, 25 Apr 2026 20:49:31 +0200 Subject: [PATCH 117/203] fix anydataholder --- rnex-core/src/rmc/structures/any.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/rnex-core/src/rmc/structures/any.rs b/rnex-core/src/rmc/structures/any.rs index 45ab453..0f531d8 100644 --- a/rnex-core/src/rmc/structures/any.rs +++ b/rnex-core/src/rmc/structures/any.rs @@ -13,10 +13,7 @@ impl RmcSerialize for Any { self.name.serialize(writer)?; let u32_len = self.data.len() as u32; - (u32_len + 4).serialize(writer)?; - u32_len.serialize(writer)?; - self.data.serialize(writer)?; Ok(()) @@ -26,11 +23,7 @@ impl RmcSerialize for Any { // also length ? let _len2: u32 = reader.read_struct(IS_BIG_ENDIAN)?; - let length: u32 = reader.read_struct(IS_BIG_ENDIAN)?; - - let mut data = vec![0; length as usize]; - - reader.read_exact(&mut data)?; + let data = Vec::deserialize(reader)?; Ok(Any { name, data }) } From 50f6d496d715c9f26e8f5fcf37831f3756c13e2a Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 00:32:38 +0200 Subject: [PATCH 118/203] Preliminary CI --- .forgejo/workflows/build.yml | 69 ++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 .forgejo/workflows/build.yml diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml new file mode 100644 index 0000000..ae6df51 --- /dev/null +++ b/.forgejo/workflows/build.yml @@ -0,0 +1,69 @@ +name: Build and Test + +on: + push: + branches: ["**"] + pull_request: + +env: + DOCKER_TLS_CERTDIR: /certs + IMAGE_TAG: ${{ github.ref_name }} + +jobs: + splatoon: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Cache container storage + uses: actions/cache@v4 + with: + path: | + /var/lib/containers/storage + /run/containers/storage + ~/.local/share/containers/storage + key: image-cache + + - name: Install Podman + run: | + sudo apt-get update + sudo apt-get install -y podman + + - name: Login to registry + run: podman login -u ${{ vars.PACKAGE_USER }} -p ${{ vars.PACKAGE_PWD }} ${{ vars.PACKAGE_URL }} + + - name: Build Splatoon edition + run: ./.ci-scripts/make-edition.sh splatoon + + friends: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Cache container storage + uses: actions/cache@v4 + with: + path: | + /var/lib/containers/storage + /run/containers/storage + ~/.local/share/containers/storage + key: image-cache + + - name: Install Podman + run: | + sudo apt-get update + sudo apt-get install -y podman + + - name: Login to registry + run: podman login -u ${{ vars.PACKAGE_USER }} -p ${{ vars.PACKAGE_PWD }} ${{ vars.PACKAGE_URL }} + + - name: Build Friends edition + run: ./.ci-scripts/make-edition.sh friends From 5379d99c2923e2f4b5b92a8668f37da3249765a5 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 00:40:49 +0200 Subject: [PATCH 119/203] Preliminary CI #2 --- .forgejo/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index ae6df51..eb52bbf 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -11,7 +11,7 @@ env: jobs: splatoon: - runs-on: ubuntu-latest + runs-on: alpine:latest steps: - name: Checkout repository @@ -40,7 +40,7 @@ jobs: run: ./.ci-scripts/make-edition.sh splatoon friends: - runs-on: ubuntu-latest + runs-on: alpine:latest steps: - name: Checkout repository From 1befcf11a28f0cf66902f315f7d82ca50308faf6 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 00:43:38 +0200 Subject: [PATCH 120/203] Fix CI formatting bug --- .forgejo/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index eb52bbf..22a20f2 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -11,7 +11,7 @@ env: jobs: splatoon: - runs-on: alpine:latest + runs-on: alpine steps: - name: Checkout repository @@ -40,7 +40,7 @@ jobs: run: ./.ci-scripts/make-edition.sh splatoon friends: - runs-on: alpine:latest + runs-on: alpine steps: - name: Checkout repository From 6d3f4bd8a26ba08291eaae75d1e8dfc7d1ace845 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 00:46:47 +0200 Subject: [PATCH 121/203] i understand why crafterpika was in pain --- .forgejo/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 22a20f2..c72f3ab 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -11,7 +11,7 @@ env: jobs: splatoon: - runs-on: alpine + runs-on: debian-trixie steps: - name: Checkout repository @@ -40,7 +40,7 @@ jobs: run: ./.ci-scripts/make-edition.sh splatoon friends: - runs-on: alpine + runs-on: debian-trixie steps: - name: Checkout repository From 242054e333445983b19222a176df48653396cb56 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 00:49:39 +0200 Subject: [PATCH 122/203] this isn't a container we have podman lol --- .forgejo/workflows/build.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index c72f3ab..6af3d5f 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -28,11 +28,6 @@ jobs: ~/.local/share/containers/storage key: image-cache - - name: Install Podman - run: | - sudo apt-get update - sudo apt-get install -y podman - - name: Login to registry run: podman login -u ${{ vars.PACKAGE_USER }} -p ${{ vars.PACKAGE_PWD }} ${{ vars.PACKAGE_URL }} From cd794cef374bc4a75563943293477c4443c6132d Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 00:58:26 +0200 Subject: [PATCH 123/203] switch to docker bc podman sucks --- .forgejo/workflows/build.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 6af3d5f..2a2c60b 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -29,7 +29,7 @@ jobs: key: image-cache - name: Login to registry - run: podman login -u ${{ vars.PACKAGE_USER }} -p ${{ vars.PACKAGE_PWD }} ${{ vars.PACKAGE_URL }} + run: docker login -u ${{ vars.PACKAGE_USER }} -p ${{ vars.PACKAGE_PWD }} ${{ vars.PACKAGE_URL }} - name: Build Splatoon edition run: ./.ci-scripts/make-edition.sh splatoon @@ -52,13 +52,8 @@ jobs: ~/.local/share/containers/storage key: image-cache - - name: Install Podman - run: | - sudo apt-get update - sudo apt-get install -y podman - - name: Login to registry - run: podman login -u ${{ vars.PACKAGE_USER }} -p ${{ vars.PACKAGE_PWD }} ${{ vars.PACKAGE_URL }} + run: docker login -u ${{ vars.PACKAGE_USER }} -p ${{ vars.PACKAGE_PWD }} ${{ vars.PACKAGE_URL }} - name: Build Friends edition run: ./.ci-scripts/make-edition.sh friends From b4ad3d9c6f530315241b51905a18cce950a7068a Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 00:24:54 +0200 Subject: [PATCH 124/203] inform about people coming online --- rnex-core/src/nex/friends_handler.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 941b747..f299593 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -139,6 +139,9 @@ impl Friends for FriendsUser { let Ok(any_self_fr_info) = Any::new(&self_fr_info) else { return Err(ErrorCode::RendezVous_ControlScriptFailure); }; + let Ok(any_self_presence) = Any::new(&self_fr_info.presence) else { + return Err(ErrorCode::RendezVous_ControlScriptFailure); + }; drop(data); let mut fr_list = vec![FriendInfo { @@ -227,6 +230,18 @@ impl Friends for FriendsUser { .await; }); } else { + let data = any_self_presence.clone(); + let u = u.clone(); + let sender = self.pid; + spawn(async move { + u.remote + .process_nintendo_notification_event_2(NintendoNotificationEvent { + event_type: 24, + sender, + data, + }) + .await; + }); drop(fr); } } @@ -263,18 +278,22 @@ impl Friends for FriendsUser { } async fn update_presence(&self, presence: NintendoPresenceV2) -> Result<(), ErrorCode> { + info!("user updated presence: {:?}", presence); let mut data = self.data.write().await; let Some(inner_data) = data.as_mut() else { + log::error!("unable to get presence data"); return Err(ErrorCode::RendezVous_PermissionDenied); }; inner_data.presence = presence; let Ok(any_self_fr_info) = Any::new(&inner_data.presence) else { + log::error!("unable to create presence any data holder"); return Err(ErrorCode::RendezVous_ControlScriptFailure); }; drop(data); let users = self.fm.users.read().await; for u in users.deref().iter().filter_map(|u| u.upgrade()) { + info!("sending presence update"); u.remote .process_nintendo_notification_event_2(NintendoNotificationEvent { event_type: 24, From 21e3227347937ce09648d71af5d1adc815585af4 Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 01:06:05 +0200 Subject: [PATCH 125/203] add user limit --- rnex-core/src/nex/friends_handler.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index f299593..71cd652 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -200,6 +200,9 @@ impl Friends for FriendsUser { println!("acquiring user and current friends locks"); let users = self.fm.users.read().await; + if users.len() >= 100 { + return Err(ErrorCode::RendezVous_ConnectionFailure); + } println!("started summing users"); for u in users.deref().iter().filter_map(|u| u.upgrade()) { let data = u.data.read().await; @@ -327,6 +330,10 @@ impl Secure for FriendsUser { station_urls: Vec, ) -> Result<(QResult, u32, StationUrl), ErrorCode> { let cid = self.fm.next_cid(); + let users = self.fm.users.read().await; + if users.len() >= 100 { + return Err(ErrorCode::RendezVous_ConnectionFailure); + } Ok(( QResult::success(ErrorCode::Core_Unknown), cid, From b7a9455e55970ac1d1501192ce42ebb0cfee65a8 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 01:21:44 +0200 Subject: [PATCH 126/203] gonna crash out --- .forgejo/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 2a2c60b..66d1922 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -29,7 +29,9 @@ jobs: key: image-cache - name: Login to registry - run: docker login -u ${{ vars.PACKAGE_USER }} -p ${{ vars.PACKAGE_PWD }} ${{ vars.PACKAGE_URL }} + run: | + echo ${{ vars.PACKAGE_URL }} + docker login -u ${{ vars.PACKAGE_USER }} -p ${{ vars.PACKAGE_PWD }} ${{ vars.PACKAGE_URL }} - name: Build Splatoon edition run: ./.ci-scripts/make-edition.sh splatoon From 53d71957b546bfb226a84199f9f202cae6463769 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 01:24:22 +0200 Subject: [PATCH 127/203] forgejo docs were wrong --- .forgejo/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 66d1922..cf299f5 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -30,8 +30,8 @@ jobs: - name: Login to registry run: | - echo ${{ vars.PACKAGE_URL }} - docker login -u ${{ vars.PACKAGE_USER }} -p ${{ vars.PACKAGE_PWD }} ${{ vars.PACKAGE_URL }} + echo ${{ secrets.PACKAGE_URL }} + docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} ${{ secrets.PACKAGE_URL }} - name: Build Splatoon edition run: ./.ci-scripts/make-edition.sh splatoon @@ -55,7 +55,7 @@ jobs: key: image-cache - name: Login to registry - run: docker login -u ${{ vars.PACKAGE_USER }} -p ${{ vars.PACKAGE_PWD }} ${{ vars.PACKAGE_URL }} + run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} ${{ secrets.PACKAGE_URL }} - name: Build Friends edition run: ./.ci-scripts/make-edition.sh friends From 8c9703f1a90716f3547b97b317d1bd035df1ae0f Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 01:25:04 +0200 Subject: [PATCH 128/203] forgejo docs were wrong AGAIN --- .forgejo/workflows/build.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index cf299f5..000411e 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -29,9 +29,7 @@ jobs: key: image-cache - name: Login to registry - run: | - echo ${{ secrets.PACKAGE_URL }} - docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} ${{ secrets.PACKAGE_URL }} + run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} ${{ secrets.PACKAGE_URL }} - name: Build Splatoon edition run: ./.ci-scripts/make-edition.sh splatoon @@ -55,7 +53,7 @@ jobs: key: image-cache - name: Login to registry - run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} ${{ secrets.PACKAGE_URL }} + run: podman login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} ${{ secrets.PACKAGE_URL }} - name: Build Friends edition run: ./.ci-scripts/make-edition.sh friends From 7f79a53f8c0f486cd932c3ebd7b96dd7647aebf0 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 01:30:10 +0200 Subject: [PATCH 129/203] pass env --- .forgejo/workflows/build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 000411e..9ed0250 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -32,6 +32,9 @@ jobs: run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} ${{ secrets.PACKAGE_URL }} - name: Build Splatoon edition + env: + CI_REGISTRY_IMAGE: ${{ secrets.PACKAGE_URL }} + CI_COMMIT_SHORT_SHA: ${{ github.ref_name }} run: ./.ci-scripts/make-edition.sh splatoon friends: @@ -56,4 +59,7 @@ jobs: run: podman login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} ${{ secrets.PACKAGE_URL }} - name: Build Friends edition + env: + CI_REGISTRY_IMAGE: ${{ secrets.PACKAGE_URL }} + CI_COMMIT_SHORT_SHA: ${{ github.ref_name }} run: ./.ci-scripts/make-edition.sh friends From f5d4c56ce0336c731f6244ef051f46682e1a443c Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 01:46:46 +0200 Subject: [PATCH 130/203] fix team counting --- rnex-core/src/nex/user.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 57c36d8..052ab53 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -230,10 +230,8 @@ impl MatchmakeExtension for User { .await?; let mut session = session.lock().await; - if session.session.user_password_enabled { - if join_session_param.user_password != session.session.user_password { - return Err(ErrorCode::RendezVous_InvalidPassword); - } + if join_session_param.user_password != session.session.user_password { + return Err(ErrorCode::RendezVous_InvalidPassword); } session @@ -656,7 +654,7 @@ impl Ranking for User { let team_votes = fetch_team_votes(fest_id)?; let mut wins = vec![0u32, 0u32]; for r in &results { - let won_team = r.team_id ^ (!r.team_win); + let won_team = (r.team_id ^ (!r.team_win)) & 1; if let Some(team) = wins.get_mut(won_team as usize) { *team += 1 }; From 479e4fa6c07baac65582c2033f5cd89d3badf3a6 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 01:56:27 +0200 Subject: [PATCH 131/203] ok this time it will work --- .forgejo/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 9ed0250..1cdeb3c 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -60,6 +60,6 @@ jobs: - name: Build Friends edition env: - CI_REGISTRY_IMAGE: ${{ secrets.PACKAGE_URL }} + CI_REGISTRY_IMAGE: ${{ secrets.PACKAGE_URL }}/rust-nex CI_COMMIT_SHORT_SHA: ${{ github.ref_name }} run: ./.ci-scripts/make-edition.sh friends From f27051ff2c5964472c5003a4ded610b71396a621 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 02:05:33 +0200 Subject: [PATCH 132/203] pls --- .forgejo/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 1cdeb3c..36f47d3 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -29,11 +29,11 @@ jobs: key: image-cache - name: Login to registry - run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} ${{ secrets.PACKAGE_URL }} + run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net - name: Build Splatoon edition env: - CI_REGISTRY_IMAGE: ${{ secrets.PACKAGE_URL }} + CI_REGISTRY_IMAGE: git.spbr.net/rust-nex CI_COMMIT_SHORT_SHA: ${{ github.ref_name }} run: ./.ci-scripts/make-edition.sh splatoon @@ -56,10 +56,10 @@ jobs: key: image-cache - name: Login to registry - run: podman login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} ${{ secrets.PACKAGE_URL }} + run: podman login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net - name: Build Friends edition env: - CI_REGISTRY_IMAGE: ${{ secrets.PACKAGE_URL }}/rust-nex + CI_REGISTRY_IMAGE: git.spbr.net/rust-nex CI_COMMIT_SHORT_SHA: ${{ github.ref_name }} run: ./.ci-scripts/make-edition.sh friends From cc7c3ff4b33313346f4414204d5492397160be1d Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 02:13:18 +0200 Subject: [PATCH 133/203] AAAAAAA --- .forgejo/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 36f47d3..87d40b4 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -7,7 +7,7 @@ on: env: DOCKER_TLS_CERTDIR: /certs - IMAGE_TAG: ${{ github.ref_name }} + IMAGE_TAG: ${{ github.sha }} jobs: splatoon: @@ -33,8 +33,8 @@ jobs: - name: Build Splatoon edition env: - CI_REGISTRY_IMAGE: git.spbr.net/rust-nex - CI_COMMIT_SHORT_SHA: ${{ github.ref_name }} + CI_REGISTRY_IMAGE: git.spbr.net/Spacebar/rust-nex + CI_COMMIT_SHORT_SHA: ${{ github.sha }} run: ./.ci-scripts/make-edition.sh splatoon friends: @@ -60,6 +60,6 @@ jobs: - name: Build Friends edition env: - CI_REGISTRY_IMAGE: git.spbr.net/rust-nex - CI_COMMIT_SHORT_SHA: ${{ github.ref_name }} + CI_REGISTRY_IMAGE: git.spbr.net/Spacebar/rust-nex + CI_COMMIT_SHORT_SHA: ${{ github.sha }} run: ./.ci-scripts/make-edition.sh friends From 289f1a438fa512550a5d2049599420d6c8c6daf6 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 02:14:10 +0200 Subject: [PATCH 134/203] repo name must be lowercase --- .forgejo/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 87d40b4..9dbc209 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -33,7 +33,7 @@ jobs: - name: Build Splatoon edition env: - CI_REGISTRY_IMAGE: git.spbr.net/Spacebar/rust-nex + CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex CI_COMMIT_SHORT_SHA: ${{ github.sha }} run: ./.ci-scripts/make-edition.sh splatoon @@ -60,6 +60,6 @@ jobs: - name: Build Friends edition env: - CI_REGISTRY_IMAGE: git.spbr.net/Spacebar/rust-nex + CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex CI_COMMIT_SHORT_SHA: ${{ github.sha }} run: ./.ci-scripts/make-edition.sh friends From 40c3f65650afc80ab881b47007d4c14c9c29e1c5 Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 02:40:19 +0200 Subject: [PATCH 135/203] remove unnescesary files --- out/backend_server_secure | Bin 2005008 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 out/backend_server_secure diff --git a/out/backend_server_secure b/out/backend_server_secure deleted file mode 100755 index be14059810d86e98b2f98e8d87b12bef6bae892f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2005008 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

    nQ{Jju+qp@IhHTW*uSl=I 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


    RYsHSDH#Y5KpYp&Ot*zbrfR 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∼uKa-gb6^)XXF7%-?%W&Y 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

    o!L0 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¥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 a{NH&ocKsK>XRd$wZ~vP6ss7!){{H~_eVK^> From f3718ed68057b7e131c70798e2c67f32d3f0185b Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 03:21:36 +0200 Subject: [PATCH 136/203] short SHA --- .forgejo/workflows/build.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 9dbc209..2470324 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -8,6 +8,7 @@ on: env: DOCKER_TLS_CERTDIR: /certs IMAGE_TAG: ${{ github.sha }} + SHORT_SHA: ${{ github.sha }} jobs: splatoon: @@ -31,10 +32,13 @@ jobs: - name: Login to registry run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net + - name: Set short SHA + run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV + - name: Build Splatoon edition env: CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex - CI_COMMIT_SHORT_SHA: ${{ github.sha }} + CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} run: ./.ci-scripts/make-edition.sh splatoon friends: @@ -55,11 +59,14 @@ jobs: ~/.local/share/containers/storage key: image-cache + - name: Set short SHA + run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV + - name: Login to registry run: podman login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net - name: Build Friends edition env: CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex - CI_COMMIT_SHORT_SHA: ${{ github.sha }} + CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} run: ./.ci-scripts/make-edition.sh friends From 70ced21e59b70fc6402df57f553583d3079c3b2b Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 12:25:02 +0200 Subject: [PATCH 137/203] remove more unnescesary files --- perf.data | Bin 1541812 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 perf.data diff --git a/perf.data b/perf.data deleted file mode 100644 index 2cf011f2aead2710a3b379f9beeaec082efbec18..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1541812 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'@xPd1 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

      j81RpU3m_-J_3) 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 YS(dmz)sJ)B|0XtXKPk2+G3N*V5A-jpKmY&$ From a88f1898a5dbb9b1f19d7d29362d29ae585d3d9e Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 13:15:56 +0200 Subject: [PATCH 138/203] fix warnings --- macros/src/protos.rs | 2 +- proxy-common/src/lib.rs | 10 ++- prudplite/src/crypto/insecure.rs | 2 +- prudplite/src/{main.rs => executable.rs} | 0 prudplite/src/lib.rs | 27 +++--- prudplite/src/packet.rs | 13 ++- prudpv0/src/crypto/friends_insecure.rs | 5 +- prudpv0/src/crypto/friends_secure.rs | 1 + prudpv0/src/lib.rs | 23 +---- prudpv0/src/packet.rs | 9 +- prudpv0/src/server.rs | 83 +++++++++++-------- .../src/executables/backend_server_secure.rs | 7 -- rnex-core/src/executables/friends_backend.rs | 14 ++-- rnex-core/src/executables/mod.rs | 11 ++- rnex-core/src/kerberos/mod.rs | 6 +- rnex-core/src/nex/auth_handler.rs | 79 ------------------ rnex-core/src/nex/friends_handler.rs | 2 +- rnex-core/src/nex/mod.rs | 16 +++- rnex-core/src/prudp/ticket.rs | 4 +- rnex-core/src/prudp/virtual_port.rs | 5 +- rnex-core/src/rmc/protocols/auth.rs | 12 +-- rnex-core/src/rmc/protocols/friends.rs | 2 +- rnex-core/src/rmc/protocols/notifications.rs | 2 +- rnex-core/src/rmc/protocols/ranking.rs | 26 +++--- 24 files changed, 148 insertions(+), 213 deletions(-) rename prudplite/src/{main.rs => executable.rs} (100%) diff --git a/macros/src/protos.rs b/macros/src/protos.rs index 2e95e71..f7e7d0d 100644 --- a/macros/src/protos.rs +++ b/macros/src/protos.rs @@ -1,7 +1,7 @@ use proc_macro2::{Ident, Span, TokenStream}; use quote::{quote, ToTokens}; use syn::token::{Brace, Paren, Semi}; -use syn::{Attribute, LitInt, LitStr, ReturnType, Type}; +use syn::{LitInt, LitStr, ReturnType, Type}; pub struct ProtoMethodData { pub id: LitInt, diff --git a/proxy-common/src/lib.rs b/proxy-common/src/lib.rs index 5cc13b7..d5ef302 100644 --- a/proxy-common/src/lib.rs +++ b/proxy-common/src/lib.rs @@ -1,12 +1,12 @@ use log::{error, info}; use rnex_core::{ PID, - executables::common::{OWN_IP_PUBLIC, try_get_ip}, + executables::common::try_get_ip, prudp::{socket_addr::PRUDPSockAddr, virtual_port::VirtualPort}, reggie::{RemoteEdgeNodeHolder, UnitPacketWrite}, rmc::{ protocols::{ - OnlyRemote, RemoteDisconnectable, RmcCallable, RmcConnection, RmcPureRemoteObject, + RemoteDisconnectable, RmcCallable, RmcConnection, RmcPureRemoteObject, new_rmc_gateway_connection, }, structures::RmcSerialize, @@ -17,7 +17,7 @@ use rnex_core::{ use std::{ env::{self, VarError}, error, - net::{AddrParseError, IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4}, + net::{AddrParseError, Ipv4Addr, SocketAddr, SocketAddrV4}, ops::Deref, panic, str::FromStr, @@ -75,6 +75,7 @@ const VIRTUAL_PORT_INSECURE: LazyLock = const VIRTUAL_PORT_SECURE: LazyLock = LazyLock::new(|| VirtualPort::parse(env!("RNEX_VIRTUAL_PORT_SECURE")).unwrap()); impl ProxyStartupParam { + #[inline(always)] pub fn new(prox_ty: ProxyType) -> Result { let port = RNEX_DEFAULT_PORT + match prox_ty { @@ -82,7 +83,7 @@ impl ProxyStartupParam { ProxyType::Secure => 1, }; let self_private = try_get_env("SERVER_IP_PRIVATE") - .unwrap_or(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, RNEX_DEFAULT_PORT)); + .unwrap_or(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, port)); let self_public: SocketAddrV4 = match try_get_env("SERVER_IP_PUBLIC") { Ok(v) => v, Err(e) => try_get_ip() @@ -121,6 +122,7 @@ impl Option<(PID, Vec)> { + fn new_connection(&self, _data: &[u8]) -> Option<(PID, Vec)> { Some((100, vec![])) } fn new() -> Self { diff --git a/prudplite/src/main.rs b/prudplite/src/executable.rs similarity index 100% rename from prudplite/src/main.rs rename to prudplite/src/executable.rs diff --git a/prudplite/src/lib.rs b/prudplite/src/lib.rs index 05938d7..0df7b2e 100644 --- a/prudplite/src/lib.rs +++ b/prudplite/src/lib.rs @@ -17,7 +17,7 @@ use rnex_core::{ types_flags::{ TypesFlags, flags::{ACK, NEED_ACK, RELIABLE}, - types::{CONNECT, DATA, DISCONNECT, SYN}, + types::{CONNECT, DATA, DISCONNECT, PING, SYN}, }, virtual_port::VirtualPort, }, @@ -26,20 +26,20 @@ use rnex_core::{ use tokio::net::{TcpListener, TcpStream}; use tokio_tungstenite::{ WebSocketStream, - tungstenite::{ - Bytes, Message, client::IntoClientRequest, http::header::ACCESS_CONTROL_REQUEST_METHOD, - }, + tungstenite::{Bytes, Message}, }; struct ConnectionState { param: Arc, active: bool, websocket: WebSocketStream, + #[allow(dead_code)] pid: PID, backend_conn: SplittableBufferConnection, addr: PRUDPSockAddr, incoming_reliable: HashMap>, client_reliable_counter: u16, + #[allow(dead_code)] server_reliable_counter: u16, } @@ -71,10 +71,16 @@ impl ConnectionState { ); let data: Bytes = data.into(); if header.types_flags.get_types() == DISCONNECT { - self.websocket.send(Message::Binary(data.clone())).await; - self.websocket.send(Message::Binary(data.clone())).await; + self.websocket + .send(Message::Binary(data.clone())) + .await + .ok(); + self.websocket + .send(Message::Binary(data.clone())) + .await + .ok(); } - self.websocket.send(Message::Binary(data)).await; + self.websocket.send(Message::Binary(data)).await.ok(); } if (header.types_flags.get_flags() & ACK) != 0 { @@ -111,6 +117,7 @@ impl ConnectionState { } } } + #[allow(dead_code)] pub async fn process_reliable(&mut self) { while let Some(v) = self.incoming_reliable.remove(&self.client_reliable_counter) { self.handle_incoming_prudp(v, true).await; @@ -131,7 +138,7 @@ impl ConnectionState { } } } - v = self.backend_conn.recv() => { + _ = self.backend_conn.recv() => { } } @@ -197,7 +204,7 @@ pub async fn websocket_thread_unconnected( ], &[], ); - websocket.send(Message::Binary(data.into())).await; + websocket.send(Message::Binary(data.into())).await.ok(); } CONNECT => { let Some(supported) = packet.packet_specific_iter() else { @@ -242,7 +249,7 @@ pub async fn websocket_thread_unconnected( ], &data, ); - websocket.send(Message::Binary(data.into())).await; + websocket.send(Message::Binary(data.into())).await.ok(); let addr = PRUDPSockAddr::new( addr, diff --git a/prudplite/src/packet.rs b/prudplite/src/packet.rs index bd8d87c..e75750b 100644 --- a/prudplite/src/packet.rs +++ b/prudplite/src/packet.rs @@ -3,8 +3,7 @@ use std::{ io::{self, Cursor, Read, Write}, }; -use bytemuck::{Pod, Zeroable, bytes_of}; -use futures_util::Stream; +use bytemuck::{Pod, Zeroable, bytes_of_mut}; use rnex_core::prudp::types_flags::TypesFlags; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; @@ -30,10 +29,10 @@ pub enum PacketSpecificData { impl PacketSpecificData { fn consume(reader: &mut impl Read) -> io::Result { - let mut option_id = 0; - reader.read_exact(&mut [option_id])?; - let mut size = 0; - reader.read_exact(&mut [size])?; + let mut option_id = 0u8; + reader.read_exact(bytes_of_mut(&mut option_id))?; + let mut size = 0u8; + reader.read_exact(bytes_of_mut(&mut size))?; match option_id { 0 => { @@ -156,7 +155,7 @@ impl> LitePacket { .get_mut(size_of::()..size_of::() + len as usize) } - pub fn packet_specific_iter(&self) -> Option { + pub fn packet_specific_iter<'a>(&'a self) -> Option> { self.packet_specific_raw() .map(Cursor::new) .map(PacketSpecificIter) diff --git a/prudpv0/src/crypto/friends_insecure.rs b/prudpv0/src/crypto/friends_insecure.rs index 1f05681..ead738a 100644 --- a/prudpv0/src/crypto/friends_insecure.rs +++ b/prudpv0/src/crypto/friends_insecure.rs @@ -1,4 +1,4 @@ -use std::{io::Write, rc::Rc}; +use std::io::Write; use hmac::Mac; use md5::{Digest, Md5}; @@ -18,6 +18,7 @@ use crate::crypto::{ pub struct InsecureInstance { pair: EncryptionPair>, self_signat: [u8; 4], + #[allow(dead_code)] remote_signat: [u8; 4], } @@ -62,7 +63,7 @@ impl Crypto for Insecure { fn instantiate( &self, - packet_data: &[u8], + _packet_data: &[u8], self_signat: [u8; 4], remote_signat: [u8; 4], ) -> Option<(Self::Instance, Vec)> { diff --git a/prudpv0/src/crypto/friends_secure.rs b/prudpv0/src/crypto/friends_secure.rs index acfa3bc..14bdf7c 100644 --- a/prudpv0/src/crypto/friends_secure.rs +++ b/prudpv0/src/crypto/friends_secure.rs @@ -24,6 +24,7 @@ pub struct SecureInstance { pair: EncryptionPair>, uid: u32, self_signat: [u8; 4], + #[allow(dead_code)] remote_signat: [u8; 4], } diff --git a/prudpv0/src/lib.rs b/prudpv0/src/lib.rs index 444899a..86afe42 100644 --- a/prudpv0/src/lib.rs +++ b/prudpv0/src/lib.rs @@ -1,26 +1,13 @@ -cfg_if::cfg_if! { +use cfg_if::cfg_if; +cfg_if! { if #[cfg(feature = "prudpv0")] { - use bytemuck::{Pod, Zeroable}; - use cfg_if::cfg_if; - use log::{error, info, warn}; - use proxy_common::{ProxyStartupParam, setup_edge_node_connection}; - use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT}; - use rnex_core::prudp::types_flags::TypesFlags; - use rnex_core::prudp::types_flags::types::SYN; - use rnex_core::prudp::virtual_port::VirtualPort; - use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; - use rnex_core::reggie::RemoteEdgeNodeHolder; - use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; - use rnex_core::rmc::structures::RmcSerialize; - use rnex_core::util::SplittableBufferConnection; + use log::info; + use proxy_common::ProxyStartupParam; use std::env; use std::net::SocketAddrV4; - use std::process::abort; use std::sync::{Arc, LazyLock}; - use tokio::net::UdpSocket; use crate::crypto::{Crypto, Insecure, Secure}; - use crate::packet::PRUDPV0Packet; use crate::server::Server; mod crypto; @@ -44,8 +31,6 @@ cfg_if::cfg_if! { //implementations, e.g. secure and insecure(this also includes special cases like friends) async fn start_proxy(param: ProxyStartupParam) { - info!("creating cryptography instance"); - let mut crypto = Arc::new(T::new()); info!("binding to socket"); let server: Arc> = Arc::new(Server::new(param).await); diff --git a/prudpv0/src/packet.rs b/prudpv0/src/packet.rs index 50bfe55..b78102f 100644 --- a/prudpv0/src/packet.rs +++ b/prudpv0/src/packet.rs @@ -1,11 +1,9 @@ -use std::mem::transmute; - use bytemuck::{Pod, Zeroable, try_from_bytes, try_from_bytes_mut}; -use log::{error, info, warn}; +use log::{info, warn}; use rnex_core::prudp::{ types_flags::{ - self, TypesFlags, - flags::{HAS_SIZE, NEED_ACK}, + TypesFlags, + flags::HAS_SIZE, types::{CONNECT, DATA, DISCONNECT, PING, SYN}, }, virtual_port::VirtualPort, @@ -165,6 +163,7 @@ impl> PRUDPV0Packet { const DEFAULT_SIGNAT: [u8; 4] = [0x12, 0x34, 0x56, 0x78]; #[inline(always)] +#[allow(dead_code)] const fn get_size_offset(tf: TypesFlags) -> usize { size_of::() + (if tf.get_types() & (SYN | CONNECT) != 0 { diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 899bbd6..96b6416 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -1,32 +1,24 @@ use std::{ collections::HashMap, - hash::Hash, - net::{Ipv4Addr, SocketAddr, SocketAddrV4}, - sync::{ - Arc, LazyLock, Weak, - atomic::{AtomicBool, AtomicU32}, - }, + net::{SocketAddr, SocketAddrV4}, + sync::{Arc, Weak}, time::Duration, }; use log::{error, info, warn}; use proxy_common::{ProxyStartupParam, new_backend_connection}; use rnex_core::{ - executables::common::{OWN_IP_PRIVATE, SERVER_PORT}, prudp::{ socket_addr::PRUDPSockAddr, types_flags::{ - TypesFlags, - flags::{ACK, HAS_SIZE, NEED_ACK, RELIABLE}, + flags::{ACK, NEED_ACK, RELIABLE}, types::{CONNECT, DATA, DISCONNECT, PING, SYN}, }, - virtual_port::VirtualPort, }, - rnex_proxy_common::ConnectionInitData, util::{SendingBufferConnection, SplittableBufferConnection}, }; use tokio::{ - net::{TcpSocket, UdpSocket}, + net::UdpSocket, spawn, sync::{Mutex, RwLock}, time::{Instant, sleep}, @@ -35,8 +27,8 @@ use tokio::{ use crate::{ crypto::{Crypto, CryptoInstance}, packet::{ - PRUDPV0Header, PRUDPV0Packet, new_connect_packet, new_data_packet, new_disconnect_packet, - new_ping_packet, new_syn_packet, precalc_size, + PRUDPV0Packet, new_connect_packet, new_data_packet, new_disconnect_packet, new_ping_packet, + new_syn_packet, }, }; @@ -49,16 +41,14 @@ pub struct InternalConnection { packet_queue: HashMap>)>, } pub struct Connection { - alive: AtomicBool, session_id: u8, target: SendingBufferConnection, - self_signat: [u8; 4], - remote_signat: [u8; 4], addr: PRUDPSockAddr, inner: Mutex>, } impl InternalConnection { + #[allow(dead_code)] fn next_server_count(&mut self) -> u16 { let prev_val = self.server_packet_counter; let (val, _) = self.server_packet_counter.overflowing_add(1); @@ -148,7 +138,8 @@ impl Server { this.socket .send_to(&data, conn.addr.regular_socket_addr) - .await; + .await + .ok(); break; } @@ -192,7 +183,8 @@ impl Server { self.socket .send_to(&packet, conn.addr.regular_socket_addr) - .await; + .await + .ok(); } if (Instant::now() - inner.last_action).as_secs() > 15 { @@ -210,13 +202,16 @@ impl Server { self.socket .send_to(&packet, conn.addr.regular_socket_addr) - .await; + .await + .ok(); self.socket .send_to(&packet, conn.addr.regular_socket_addr) - .await; + .await + .ok(); self.socket .send_to(&packet, conn.addr.regular_socket_addr) - .await; + .await + .ok(); drop(inner); let mut conns = self.connections.write().await; @@ -236,7 +231,10 @@ impl Server { let signat = [signat[0], signat[1], signat[2], signat[3]]; let packet = new_syn_packet(ACK, header.destination, header.source, signat, &self.crypto); - self.socket.send_to(&packet, addr.regular_socket_addr).await; + self.socket + .send_to(&packet, addr.regular_socket_addr) + .await + .ok(); } async fn handle_connect(self: Arc, packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { let Some(data) = packet.payload() else { @@ -275,11 +273,8 @@ impl Server { let conn = Arc::new(Connection { target: buf_conn.duplicate_sender(), - remote_signat, - self_signat, addr, session_id: header.session_id, - alive: AtomicBool::new(true), inner: Mutex::new(InternalConnection { last_action: Instant::now(), crypto_instance: ci, @@ -320,9 +315,12 @@ impl Server { ); info!("sending back connection accept"); - self.socket.send_to(&packet, addr.regular_socket_addr).await; + self.socket + .send_to(&packet, addr.regular_socket_addr) + .await + .ok(); } - async fn handle_data(self: Arc, mut packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { + async fn handle_data(self: Arc, packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { let Some(frag_id) = packet.fragment_id() else { warn!("invalid packet from: {:?}", addr); return; @@ -349,7 +347,10 @@ impl Server { &mut conn.crypto_instance, &self.crypto, ); - self.socket.send_to(&ack, addr.regular_socket_addr).await; + self.socket + .send_to(&ack, addr.regular_socket_addr) + .await + .ok(); conn.packet_queue.insert( packet.header().unwrap().sequence_id, (Instant::now(), packet), @@ -375,7 +376,7 @@ impl Server { drop(conn); } - async fn handle_ping(self: Arc, mut packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { + async fn handle_ping(self: Arc, packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { info!("got ping"); let header = packet.header().unwrap(); @@ -395,11 +396,14 @@ impl Server { ); drop(inner); - self.socket.send_to(&packet, addr.regular_socket_addr).await; + self.socket + .send_to(&packet, addr.regular_socket_addr) + .await + .ok(); } async fn handle_disconnect( self: Arc, - mut packet: PRUDPV0Packet>, + packet: PRUDPV0Packet>, addr: PRUDPSockAddr, ) { info!("got disconnect"); @@ -425,9 +429,18 @@ impl Server { conns.remove(&(addr, header.session_id)); drop(conns); - self.socket.send_to(&packet, addr.regular_socket_addr).await; - self.socket.send_to(&packet, addr.regular_socket_addr).await; - self.socket.send_to(&packet, addr.regular_socket_addr).await; + self.socket + .send_to(&packet, addr.regular_socket_addr) + .await + .ok(); + self.socket + .send_to(&packet, addr.regular_socket_addr) + .await + .ok(); + self.socket + .send_to(&packet, addr.regular_socket_addr) + .await + .ok(); } async fn get_connection( &self, diff --git a/rnex-core/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs index 91b83b3..5ec36f1 100644 --- a/rnex-core/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -1,13 +1,6 @@ use cfg_if::cfg_if; use rnex_core::common::setup; -use rnex_core::executables::common::new_simple_backend; use rnex_core::executables::friends_backend::start_friends_backend; -use rnex_core::nex::matchmake::MatchmakeManager; -use rnex_core::nex::remote_console::RemoteConsole; -use rnex_core::nex::user::User; -use rnex_core::rmc::protocols::{RemoteDisconnectable, RmcPureRemoteObject}; -use std::sync::Arc; -use std::sync::atomic::AtomicU32; #[tokio::main] async fn main() { diff --git a/rnex-core/src/executables/friends_backend.rs b/rnex-core/src/executables/friends_backend.rs index 5dfcf02..d2ce497 100644 --- a/rnex-core/src/executables/friends_backend.rs +++ b/rnex-core/src/executables/friends_backend.rs @@ -8,15 +8,11 @@ use log::error; use tokio::net::TcpListener; use crate::{ - executables::common::{OWN_IP_PRIVATE, SERVER_PORT, new_simple_backend}, - nex::friends_handler::{ - FriendsGuest, FriendsManager, FriendsUser, RemoteFriendRemote, RemoteFriendsUser, - }, + executables::common::{OWN_IP_PRIVATE, SERVER_PORT}, + nex::friends_handler::{FriendsGuest, FriendsManager, FriendsUser, RemoteFriendRemote}, reggie::UnitPacketRead, rmc::{ - protocols::{ - RmcCallable, RmcPureRemoteObject, friends::RemoteFriends, new_rmc_gateway_connection, - }, + protocols::{RmcPureRemoteObject, new_rmc_gateway_connection}, structures::RmcSerialize, }, rnex_proxy_common::ConnectionInitData, @@ -65,8 +61,8 @@ pub async fn start_friends_backend() { }) }); } else { - new_rmc_gateway_connection(stream.into(), move |r| { - Arc::new_cyclic(move |this| FriendsGuest { + new_rmc_gateway_connection(stream.into(), move |_| { + Arc::new_cyclic(move |_| FriendsGuest { fm, addr: c.prudpsock_addr, }) diff --git a/rnex-core/src/executables/mod.rs b/rnex-core/src/executables/mod.rs index cc9b83d..83a9df5 100644 --- a/rnex-core/src/executables/mod.rs +++ b/rnex-core/src/executables/mod.rs @@ -1,3 +1,10 @@ +use cfg_if::cfg_if; + pub mod common; -pub mod friends_backend; -pub mod regular_backend; +cfg_if! { + if #[cfg(feature = "friends")]{ + pub mod friends_backend; + } else { + pub mod regular_backend; + } +} diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index 205c62a..f67af94 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -18,13 +18,13 @@ use rnex_core::PID; cfg_if! { if #[cfg(feature = "friends")]{ - pub type SESSION_KEY_LENGTH_TY = U16; + pub type SessionLengthTy = U16; } else { use rc4::consts::U32; - pub type SESSION_KEY_LENGTH_TY = U32; + pub type SessionLengthTy = U32; } } -pub const SESSION_KEY_LENGTH: usize = SESSION_KEY_LENGTH_TY::USIZE; +pub const SESSION_KEY_LENGTH: usize = SessionLengthTy::USIZE; type Md5Hmac = Hmac; diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index 341dc93..97b1008 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -337,82 +337,3 @@ impl Auth for AuthHandler { Err(ErrorCode::Core_Exception) } } - -mod test { - use std::io::Cursor; - - use rc4::{KeyInit, Rc4, StreamCipher}; - use rnex_core::PID; - use rnex_core::kerberos::KerberosDateTime; - use rnex_core::rmc::structures::connection_data::ConnectionData; - use rnex_core::rmc::{ - response::ErrorCode, - structures::{RmcSerialize, qresult::QResult}, - }; - - use crate::kerberos::{self, derive_key}; - use crate::rmc; - use crate::rmc::message::RMCMessage; - use crate::rmc::response::{RMCResponse, RMCResponseResult}; - - #[test] - fn test() { - return; - let packet = [ - 26, 1, 0, 0, 10, 1, 30, 0, 0, 0, 1, 128, 0, 0, 1, 0, 1, 0, 86, 4, 0, 0, 116, 0, 0, 0, - 144, 209, 130, 175, 45, 215, 95, 55, 226, 192, 51, 54, 201, 84, 118, 150, 159, 164, 32, - 103, 134, 252, 199, 168, 178, 5, 6, 208, 206, 241, 94, 23, 136, 37, 109, 247, 156, 252, - 189, 233, 142, 115, 206, 72, 180, 57, 106, 223, 37, 59, 144, 208, 250, 197, 51, 202, - 185, 156, 51, 159, 219, 117, 250, 103, 184, 1, 103, 108, 15, 14, 174, 160, 192, 146, - 135, 10, 55, 125, 68, 181, 88, 127, 183, 34, 4, 213, 19, 146, 81, 56, 248, 213, 241, - 168, 205, 253, 29, 10, 123, 198, 177, 157, 247, 209, 113, 167, 231, 42, 214, 15, 12, - 200, 192, 230, 125, 227, 74, 0, 112, 114, 117, 100, 112, 115, 58, 47, 80, 73, 68, 61, - 50, 59, 115, 105, 100, 61, 49, 59, 115, 116, 114, 101, 97, 109, 61, 49, 48, 59, 116, - 121, 112, 101, 61, 50, 59, 97, 100, 100, 114, 101, 115, 115, 61, 57, 49, 46, 57, 56, - 46, 49, 50, 56, 46, 56, 54, 59, 112, 111, 114, 116, 61, 54, 48, 48, 49, 59, 67, 73, 68, - 61, 49, 0, 0, 0, 0, 0, 1, 0, 0, 162, 243, 240, 168, 31, 0, 0, 0, 51, 0, 98, 114, 97, - 110, 99, 104, 58, 111, 114, 105, 103, 105, 110, 47, 112, 114, 111, 106, 101, 99, 116, - 47, 119, 117, 112, 45, 97, 103, 109, 106, 32, 98, 117, 105, 108, 100, 58, 51, 95, 56, - 95, 49, 53, 95, 50, 48, 48, 52, 95, 48, 0, - ]; - let rmc_packet = RMCResponse::new(&mut Cursor::new(&packet)).unwrap(); - println!("{:?}", rmc_packet); - - let RMCResponseResult::Success { - call_id, - method_id, - data, - } = rmc_packet.response_result - else { - panic!(); - }; - - println!("{}", hex::encode(&data)); - - let mut data = - <(QResult, PID, Vec, ConnectionData, String) as RmcSerialize>::deserialize( - &mut Cursor::new(&data[..]), - ) - .unwrap(); - - println!("{:?}", data); - - let key = derive_key(1110, "AAAAAAAAAAAAAAAA".as_bytes()); - - let mut rc4 = Rc4::new((&key).into()); - - rc4.apply_keystream(&mut data.2); - println!("raw tick: {:?}", data.2); - - let tick: &kerberos::Ticket = - bytemuck::from_bytes(&data.2[..size_of::()]); - - let remainder = &data.2[size_of::()..]; - - println!("tick: {:?}", tick); - let data = as RmcSerialize>::deserialize(&mut Cursor::new(remainder)).unwrap(); - println!("inner ticket raw: {:?}", data); - - println!("{:?}", data); - } -} diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 71cd652..27f31d9 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -312,7 +312,7 @@ impl Friends for FriendsUser { async fn delete_persistent_notification( &self, - notifs: Vec, + _notifs: Vec, ) -> Result<(), ErrorCode> { Ok(()) } diff --git a/rnex-core/src/nex/mod.rs b/rnex-core/src/nex/mod.rs index 0f52c13..79c2085 100644 --- a/rnex-core/src/nex/mod.rs +++ b/rnex-core/src/nex/mod.rs @@ -1,7 +1,15 @@ +use cfg_if::cfg_if; + pub mod account; pub mod auth_handler; pub mod common; -pub mod friends_handler; -pub mod matchmake; -pub mod remote_console; -pub mod user; + +cfg_if! { + if #[cfg(feature = "friends")]{ + pub mod friends_handler; + } else { + pub mod matchmake; + pub mod remote_console; + pub mod user; + } +} diff --git a/rnex-core/src/prudp/ticket.rs b/rnex-core/src/prudp/ticket.rs index 98e181f..97dc5d5 100644 --- a/rnex-core/src/prudp/ticket.rs +++ b/rnex-core/src/prudp/ticket.rs @@ -6,7 +6,7 @@ use typenum::U16; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::{ - kerberos::{SESSION_KEY_LENGTH, SESSION_KEY_LENGTH_TY, TicketInternalData, derive_key}, + kerberos::{SESSION_KEY_LENGTH, SessionLengthTy, TicketInternalData, derive_key}, nex::account::Account, rmc::structures::RmcSerialize, }; @@ -53,7 +53,7 @@ pub fn read_secure_connection_data( let request_data_length = request_data.len(); let request_data = &mut request_data[0..request_data_length - 0x10]; - let mut rc4: StreamCipherCoreWrapper> = + let mut rc4: StreamCipherCoreWrapper> = Rc4::new_from_slice(&session_key).expect("unable to init rc4 keystream"); rc4.apply_keystream(request_data); diff --git a/rnex-core/src/prudp/virtual_port.rs b/rnex-core/src/prudp/virtual_port.rs index 625709b..b23b5d0 100644 --- a/rnex-core/src/prudp/virtual_port.rs +++ b/rnex-core/src/prudp/virtual_port.rs @@ -1,8 +1,5 @@ use bytemuck::{Pod, Zeroable}; -use std::{ - fmt::{Debug, Formatter}, - slice, -}; +use std::fmt::{Debug, Formatter}; use v_byte_helpers::SwapEndian; #[repr(transparent)] diff --git a/rnex-core/src/rmc/protocols/auth.rs b/rnex-core/src/rmc/protocols/auth.rs index ca387f9..a065418 100644 --- a/rnex-core/src/rmc/protocols/auth.rs +++ b/rnex-core/src/rmc/protocols/auth.rs @@ -8,11 +8,11 @@ use rnex_core::rmc::structures::qresult::QResult; cfg_if! { if #[cfg(feature = "nx")]{ - type LOGIN_EX_RET = (QResult, PID, Vec, ConnectionData, String, String); - type REQUEST_TICKET_RET = (QResult, Vec, String); + type LoginExRet = (QResult, PID, Vec, ConnectionData, String, String); + type RequestTicketRet = (QResult, Vec, String); } else { - type LOGIN_EX_RET = (QResult, PID, Vec, ConnectionData, String); - type REQUEST_TICKET_RET = (QResult, Vec); + type LoginExRet = (QResult, PID, Vec, ConnectionData, String); + type RequestTicketRet = (QResult, Vec); } } @@ -31,14 +31,14 @@ pub trait Auth { /// representation of the `LoginEx` method(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) #[method_id(2)] - async fn login_ex(&self, name: String, extra_data: Any) -> Result; + async fn login_ex(&self, name: String, extra_data: Any) -> Result; #[method_id(3)] async fn request_ticket( &self, source_pid: PID, destination_pid: PID, - ) -> Result; + ) -> Result; /// representation of the `RequestTicket` method(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) diff --git a/rnex-core/src/rmc/protocols/friends.rs b/rnex-core/src/rmc/protocols/friends.rs index 81dd63e..98fa501 100644 --- a/rnex-core/src/rmc/protocols/friends.rs +++ b/rnex-core/src/rmc/protocols/friends.rs @@ -2,7 +2,7 @@ use macros::{RmcSerialize, method_id, rmc_proto}; use rnex_core::{kerberos::KerberosDateTime, rmc::response::ErrorCode}; -use rnex_core::rmc::structures::{data::Data, rmc_struct}; +use rnex_core::rmc::structures::data::Data; #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] diff --git a/rnex-core/src/rmc/protocols/notifications.rs b/rnex-core/src/rmc/protocols/notifications.rs index eef5c6c..afbebd8 100644 --- a/rnex-core/src/rmc/protocols/notifications.rs +++ b/rnex-core/src/rmc/protocols/notifications.rs @@ -1,4 +1,4 @@ -use macros::{RmcSerialize, method_id, rmc_proto, rmc_struct}; +use macros::{RmcSerialize, method_id, rmc_proto}; use rnex_core::PID; diff --git a/rnex-core/src/rmc/protocols/ranking.rs b/rnex-core/src/rmc/protocols/ranking.rs index b9dba06..eff1ae4 100644 --- a/rnex-core/src/rmc/protocols/ranking.rs +++ b/rnex-core/src/rmc/protocols/ranking.rs @@ -1,4 +1,4 @@ -use macros::{rmc_struct, rmc_proto, RmcSerialize, method_id}; +use macros::{RmcSerialize, method_id, rmc_proto}; use rnex_core::kerberos::KerberosDateTime; use rnex_core::rmc::structures::qbuffer::QBuffer; @@ -8,9 +8,9 @@ use rnex_core::rmc::structures::ranking::UploadCompetitionData; #[derive(RmcSerialize, Debug, Default, Clone)] #[rmc_struct(0)] -pub struct ResultsRange{ +pub struct ResultsRange { pub offset: u32, - pub size: u32 + pub size: u32, } #[derive(RmcSerialize, Debug, Default, Clone)] @@ -23,29 +23,35 @@ pub struct CompetitionRankingGetParam { #[derive(RmcSerialize, Debug, Default, Clone)] #[rmc_struct(0)] -pub struct CompetitionRankingScoreInfo{ +pub struct CompetitionRankingScoreInfo { pub fest_id: u32, pub score_data: Vec, pub unk: u32, pub team_wins: Vec, - pub team_votes: Vec + pub team_votes: Vec, } #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] -pub struct CompetitionRankingScoreData{ +pub struct CompetitionRankingScoreData { pub unk: u32, pub pid: u32, pub score: u32, pub modified: KerberosDateTime, pub unk2: u8, - pub appdata: QBuffer + pub appdata: QBuffer, } #[rmc_proto(112)] -pub trait Ranking{ +pub trait Ranking { #[method_id(16)] - async fn competition_ranking_get_param(&self, param: CompetitionRankingGetParam) -> Result,ErrorCode>; + async fn competition_ranking_get_param( + &self, + param: CompetitionRankingGetParam, + ) -> Result, ErrorCode>; #[method_id(18)] - async fn upload_competition_ranking_score(&self, param: UploadCompetitionData) -> Result; + async fn upload_competition_ranking_score( + &self, + param: UploadCompetitionData, + ) -> Result; } From 7f27ad0a3c39a204785a5792808eab0383604420 Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 13:48:26 +0200 Subject: [PATCH 139/203] fix more warnings and add script to check all editions --- build-edition.sh | 3 +- buildscripts/common.sh | 1 + check-all.sh | 7 ++++ check-edition.sh | 12 +++++++ editions.yaml | 10 ------ prudpv1/src/executables/common.rs | 17 --------- prudpv1/src/executables/mod.rs | 1 - prudpv1/src/executables/proxy_insecure.rs | 36 +++---------------- prudpv1/src/executables/proxy_secure.rs | 22 +++--------- prudpv1/src/lib.rs | 6 ++-- prudpv1/src/prudp/packet.rs | 2 +- prudpv1/src/prudp/secure.rs | 6 +--- prudpv1/src/prudp/unsecure.rs | 4 +-- .../src/executables/backend_server_secure.rs | 2 +- 14 files changed, 38 insertions(+), 91 deletions(-) create mode 100755 check-all.sh create mode 100755 check-edition.sh delete mode 100644 prudpv1/src/executables/common.rs diff --git a/build-edition.sh b/build-edition.sh index 5d65fc3..ce17110 100755 --- a/build-edition.sh +++ b/build-edition.sh @@ -5,9 +5,8 @@ fi # comma seperated list of features for the specified version source ./buildscripts/common.sh +echo building $EDITION echo FEATURES: echo $EDITION_FEATURES -echo ENV SETTINGS: -env OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl diff --git a/buildscripts/common.sh b/buildscripts/common.sh index 8c5e67e..f224752 100755 --- a/buildscripts/common.sh +++ b/buildscripts/common.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -e pipefail TMP_FEATURES_TRAILINGCOMMA=$(yq ea ".$EDITION.features" editions.yaml | sed 's/- //g' | tr '\n' ',') export EDITION_FEATURES=${TMP_FEATURES_TRAILINGCOMMA::-1} SETTINGS=$(yq ea ".$EDITION.settings" editions.yaml | yq 'keys[]') diff --git a/check-all.sh b/check-all.sh new file mode 100755 index 0000000..e44fa1b --- /dev/null +++ b/check-all.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +SETTINGS=$(yq ea "." editions.yaml | yq 'keys[]') +IFS=$'\n' +while IFS=$'\n' read -r EDITION; do + ./check-edition.sh $EDITION +done <<< "$SETTINGS" diff --git a/check-edition.sh b/check-edition.sh new file mode 100755 index 0000000..9caaa67 --- /dev/null +++ b/check-edition.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +if [ -z ${EDITION+x} ]; then + EDITION=$1 +fi + +# comma seperated list of features for the specified version +source ./buildscripts/common.sh +echo CHECKING $EDITION +echo FEATURES: +echo $EDITION_FEATURES + +cargo check --features "$EDITION_FEATURES" diff --git a/editions.yaml b/editions.yaml index 7a6869c..ab27550 100644 --- a/editions.yaml +++ b/editions.yaml @@ -8,16 +8,6 @@ splatoon: RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 6000 RNEX_ACCESS_KEY: "6f599f81" -splatoon2: - features: - - v4-3-11 - - prudplite - - nx - settings: - AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" - RNEX_VIRTUAL_PORT_INSECURE: "1:10" - RNEX_VIRTUAL_PORT_SECURE: "1:10" - RNEX_DEFAULT_PORT: 6000 friends: features: - friends diff --git a/prudpv1/src/executables/common.rs b/prudpv1/src/executables/common.rs deleted file mode 100644 index 8d6f4c1..0000000 --- a/prudpv1/src/executables/common.rs +++ /dev/null @@ -1,17 +0,0 @@ -use once_cell::sync::Lazy; -use std::env; -use std::net::SocketAddrV4; - -pub static EDGE_NODE_HOLDER: Lazy = Lazy::new(|| { - env::var("EDGE_NODE_HOLDER") - .ok() - .and_then(|s| s.parse().ok()) - .expect("EDGE_NODE_HOLDER not set") -}); - -pub static FORWARD_DESTINATION: Lazy = Lazy::new(|| { - env::var("FORWARD_DESTINATION") - .ok() - .and_then(|s| s.parse().ok()) - .expect("FORWARD_DESTINATION not set") -}); diff --git a/prudpv1/src/executables/mod.rs b/prudpv1/src/executables/mod.rs index 2c0d6cf..dbcfdd7 100644 --- a/prudpv1/src/executables/mod.rs +++ b/prudpv1/src/executables/mod.rs @@ -1,3 +1,2 @@ -pub mod common; pub mod proxy_insecure; pub mod proxy_secure; diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index 06299d1..b9b974c 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -1,45 +1,19 @@ -use crate::executables::common::{EDGE_NODE_HOLDER, FORWARD_DESTINATION}; use crate::prudp::router::Router; use crate::prudp::unsecure::Unsecure; use log::error; -use rnex_core::common::setup; -use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT}; +use proxy_common::{ProxyStartupParam, RNEX_ACCESS_KEY}; use rnex_core::prudp::virtual_port::VirtualPort; -use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; -use rnex_core::reggie::RemoteEdgeNodeHolder; use rnex_core::reggie::UnitPacketRead; use rnex_core::reggie::UnitPacketWrite; -use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; use rnex_core::rmc::structures::RmcSerialize; use rnex_core::rnex_proxy_common::ConnectionInitData; -use rnex_core::util::SplittableBufferConnection; -use std::net::SocketAddrV4; -use std::sync::Arc; use std::time::Duration; use tokio::net::TcpStream; use tokio::task; use tokio::time::sleep; -use proxy_common::RNEX_ACCESS_KEY; -pub async fn start() { - /*let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER) - .await - .unwrap(); - - let conn: SplittableBufferConnection = conn.into(); - - conn.send( - Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)) - .to_data() - .unwrap(), - ) - .await; - - let conn = new_rmc_gateway_connection(conn, |r| { - Arc::new(OnlyRemote::::new(r)) - });*/ - - let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) +pub async fn start(param: ProxyStartupParam) { + let (router_secure, _) = Router::new(param.self_private) .await .expect("unable to start router"); @@ -48,8 +22,6 @@ pub async fn start() { .await .expect("unable to add socket"); - // let conn = socket_secure.connect(auth_sockaddr).await.unwrap(); - loop { let Some(mut conn) = socket_secure.accept().await else { error!("server crashed"); @@ -57,7 +29,7 @@ pub async fn start() { }; task::spawn(async move { - let mut stream = match TcpStream::connect(*FORWARD_DESTINATION).await { + let mut stream = match TcpStream::connect(param.forward_destination).await { Ok(v) => v, Err(e) => { error!("unable to connect: {}", e); diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index 6bf3434..2e79317 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -1,30 +1,20 @@ -use crate::executables::common::{EDGE_NODE_HOLDER, FORWARD_DESTINATION}; use crate::prudp::router::Router; use crate::prudp::secure::Secure; use log::error; -use rnex_core::common::setup; -use rnex_core::executables::common::{ - OWN_IP_PRIVATE, OWN_IP_PUBLIC, SECURE_SERVER_ACCOUNT, SERVER_PORT, -}; +use proxy_common::{ProxyStartupParam, RNEX_ACCESS_KEY}; +use rnex_core::executables::common::SECURE_SERVER_ACCOUNT; use rnex_core::prudp::virtual_port::VirtualPort; -use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; -use rnex_core::reggie::RemoteEdgeNodeHolder; use rnex_core::reggie::UnitPacketRead; use rnex_core::reggie::UnitPacketWrite; -use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; use rnex_core::rmc::structures::RmcSerialize; use rnex_core::rnex_proxy_common::ConnectionInitData; -use rnex_core::util::SplittableBufferConnection; -use std::net::SocketAddrV4; -use std::sync::Arc; use std::time::Duration; use tokio::net::TcpStream; use tokio::task; use tokio::time::sleep; -use proxy_common::RNEX_ACCESS_KEY; -pub async fn start() { - let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) +pub async fn start(param: ProxyStartupParam) { + let (router_secure, _) = Router::new(param.self_private) .await .expect("unable to start router"); @@ -36,8 +26,6 @@ pub async fn start() { .await .expect("unable to add socket"); - // let conn = socket_secure.connect(auth_sockaddr).await.unwrap(); - loop { let Some(mut conn) = socket_secure.accept().await else { error!("server crashed"); @@ -45,7 +33,7 @@ pub async fn start() { }; task::spawn(async move { - let mut stream = match TcpStream::connect(*FORWARD_DESTINATION).await { + let mut stream = match TcpStream::connect(param.forward_destination).await { Ok(v) => v, Err(e) => { error!("unable to connect: {}", e); diff --git a/prudpv1/src/lib.rs b/prudpv1/src/lib.rs index 0660a4b..a24f714 100644 --- a/prudpv1/src/lib.rs +++ b/prudpv1/src/lib.rs @@ -1,14 +1,14 @@ cfg_if::cfg_if! { if #[cfg(feature = "prudpv1")]{ - use proxy_common::{ProxyStartupParam, setup_edge_node_connection}; + use proxy_common::ProxyStartupParam; pub mod executables; pub mod prudp; pub async fn start_secure(param: ProxyStartupParam) { - executables::proxy_secure::start().await; + executables::proxy_secure::start(param).await; } pub async fn start_insecure(param: ProxyStartupParam) { - executables::proxy_insecure::start().await; + executables::proxy_insecure::start(param).await; } } } diff --git a/prudpv1/src/prudp/packet.rs b/prudpv1/src/prudp/packet.rs index 5a27d33..60e3feb 100644 --- a/prudpv1/src/prudp/packet.rs +++ b/prudpv1/src/prudp/packet.rs @@ -14,7 +14,7 @@ use rnex_core::prudp::socket_addr::PRUDPSockAddr; use rnex_core::prudp::types_flags::TypesFlags; use rnex_core::prudp::types_flags::flags::ACK; use rnex_core::prudp::virtual_port::VirtualPort; -use std::fmt::{Debug, Formatter}; +use std::fmt::Debug; use std::io; use std::io::{Cursor, Read, Seek, Write}; use std::net::SocketAddr; diff --git a/prudpv1/src/prudp/secure.rs b/prudpv1/src/prudp/secure.rs index 9bd441b..c7d312f 100644 --- a/prudpv1/src/prudp/secure.rs +++ b/prudpv1/src/prudp/secure.rs @@ -1,18 +1,13 @@ use crate::prudp::packet::PRUDPV1Packet; use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance}; use hmac::digest::consts::U32; -use log::error; use rc4::cipher::StreamCipherCoreWrapper; -use rc4::consts::U16; use rc4::{KeyInit, Rc4, Rc4Core, StreamCipher}; -use rnex_core::kerberos::{TicketInternalData, derive_key}; use rnex_core::nex::account::Account; use rnex_core::prudp::encryption::EncryptionPair; use rnex_core::prudp::ticket::read_secure_connection_data; use rnex_core::rmc::structures::RmcSerialize; -use std::io::Cursor; use typenum::U5; -use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; type Rc4U32 = StreamCipherCoreWrapper>; @@ -52,6 +47,7 @@ pub struct SecureInstance { session_key: [u8; 32], streams: Vec>>, self_signature: [u8; 16], + #[allow(dead_code)] remote_signature: [u8; 16], pid: u32, } diff --git a/prudpv1/src/prudp/unsecure.rs b/prudpv1/src/prudp/unsecure.rs index d47550f..79cc908 100644 --- a/prudpv1/src/prudp/unsecure.rs +++ b/prudpv1/src/prudp/unsecure.rs @@ -1,7 +1,6 @@ use crate::prudp::packet::PRUDPV1Packet; use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance}; -use once_cell::sync::Lazy; -use rc4::{Key, KeyInit, Rc4, StreamCipher}; +use rc4::{KeyInit, Rc4, StreamCipher}; use rnex_core::prudp::encryption::{DEFAULT_KEY, EncryptionPair}; use typenum::U5; @@ -11,6 +10,7 @@ pub struct UnsecureInstance { key: &'static str, streams: Vec>>, self_signature: [u8; 16], + #[allow(dead_code)] remote_signature: [u8; 16], } diff --git a/rnex-core/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs index 5ec36f1..9d5268d 100644 --- a/rnex-core/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -1,6 +1,5 @@ use cfg_if::cfg_if; use rnex_core::common::setup; -use rnex_core::executables::friends_backend::start_friends_backend; #[tokio::main] async fn main() { @@ -8,6 +7,7 @@ async fn main() { cfg_if! { if #[cfg(feature = "friends")]{ + use rnex_core::executables::friends_backend::start_friends_backend; start_friends_backend().await; } else { use rnex_core::executables::regular_backend; From 2a2dbd5ff1b248c442d457699248ebd1376e265f Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 13:53:52 +0200 Subject: [PATCH 140/203] count connected friends users correctly --- rnex-core/src/nex/friends_handler.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 27f31d9..897ff38 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -200,7 +200,7 @@ impl Friends for FriendsUser { println!("acquiring user and current friends locks"); let users = self.fm.users.read().await; - if users.len() >= 100 { + if users.iter().filter(|u| u.upgrade().is_some()).count() >= 100 { return Err(ErrorCode::RendezVous_ConnectionFailure); } println!("started summing users"); @@ -331,7 +331,7 @@ impl Secure for FriendsUser { ) -> Result<(QResult, u32, StationUrl), ErrorCode> { let cid = self.fm.next_cid(); let users = self.fm.users.read().await; - if users.len() >= 100 { + if users.iter().filter(|u| u.upgrade().is_some()).count() >= 100 { return Err(ErrorCode::RendezVous_ConnectionFailure); } Ok(( From 18c8ec77dd2b1f1fecbe81e924cd1cbfbd421498 Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 14:36:42 +0200 Subject: [PATCH 141/203] some small things --- rnex-core/Cargo.toml | 9 +++++-- rnex-core/src/util.rs | 61 +++++++++++++++++++++++++++++-------------- 2 files changed, 48 insertions(+), 22 deletions(-) diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index ff2b7b3..8d72719 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -13,7 +13,8 @@ v-byte-helpers = { git = "https://github.com/RusticMaple/VByteMacros", version = simplelog = "0.12.2" chrono = "0.4.39" log = "0.4.25" -rand = "0.8.5" +rand = "0.8.5 +" cfg-if = "1.0.4" hmac = "0.12.1" md-5 = "^0.10.6" @@ -29,13 +30,17 @@ ureq = { version = "3.1.4", features = [ "json" ] } serde = { version = "1.0.228", features = [ "derive" ] } serde_json = "1.0.149" +[dependencies.sqlx] +version = "0.8.6" +optional = true + [dev-dependencies] # criterion = "0.7.0" [features] rmc_struct_header = [] guest_login = [] -friends = ["guest_login"] +friends = ["guest_login", "dep:sqlx"] big_pid = [] v3-8-15 = ["rmc_struct_header"] v4-3-11 = ["v3-8-15"] diff --git a/rnex-core/src/util.rs b/rnex-core/src/util.rs index ff0150c..582c09b 100644 --- a/rnex-core/src/util.rs +++ b/rnex-core/src/util.rs @@ -1,24 +1,26 @@ -use std::ops::Deref; -use std::sync::Arc; -use log::{error, info}; -use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; -use tokio::sync::mpsc::{channel, Receiver, Sender}; -use tokio::sync::Notify; -use tokio::task; use crate::reggie::{UnitPacketRead, UnitPacketWrite}; +use log::{error, info}; +use std::iter::FilterMap; +use std::ops::Deref; +use std::sync::{Arc, Weak}; +use std::{slice, vec}; +use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; +use tokio::sync::Notify; +use tokio::sync::mpsc::{Receiver, Sender, channel}; +use tokio::task; #[derive(Clone)] pub struct SendingBufferConnection(Sender>, Arc); pub struct SplittableBufferConnection(SendingBufferConnection, Receiver>); -impl AsRef for SplittableBufferConnection{ +impl AsRef for SplittableBufferConnection { fn as_ref(&self) -> &SendingBufferConnection { &self.0 } } -impl Deref for SplittableBufferConnection{ +impl Deref for SplittableBufferConnection { type Target = SendingBufferConnection; fn deref(&self) -> &Self::Target { @@ -26,9 +28,7 @@ impl Deref for SplittableBufferConnection{ } } - - -impl From for SplittableBufferConnection{ +impl From for SplittableBufferConnection { fn from(value: T) -> Self { Self::new(value) } @@ -48,7 +48,6 @@ impl SplittableBufferConnection { let mut recver = inside_recv; let mut stream = stream; - loop { tokio::select! { data = recver.recv() => { @@ -81,7 +80,7 @@ impl SplittableBufferConnection { } } } - if let Err(e) = stream.shutdown().await{ + if let Err(e) = stream.shutdown().await { error!("failed to shut down stream: {}", e); } }); @@ -91,11 +90,11 @@ impl SplittableBufferConnection { } } -impl SendingBufferConnection{ - pub async fn send(&self, buffer: Vec) -> Option<()>{ +impl SendingBufferConnection { + pub async fn send(&self, buffer: Vec) -> Option<()> { self.0.send(buffer).await.ok() } - pub fn is_alive(&self) -> bool{ + pub fn is_alive(&self) -> bool { !self.0.is_closed() } pub async fn disconnect(&self) { @@ -106,12 +105,34 @@ impl SendingBufferConnection{ } } -impl SplittableBufferConnection{ - pub async fn recv(&mut self) -> Option>{ +impl SplittableBufferConnection { + pub async fn recv(&mut self) -> Option> { self.1.recv().await } - pub fn duplicate_sender(&self) -> SendingBufferConnection{ + pub fn duplicate_sender(&self) -> SendingBufferConnection { self.0.clone() } } + +struct WeakVec(Vec>); + +impl WeakVec { + pub fn new() -> Self { + Self(vec![]) + } + + pub fn from_vec(vec: Vec>) -> Self { + Self(vec) + } + + pub fn push(&mut self, val: Weak) { + self.0.retain(|v| v.upgrade().is_some()); + + self.0.push(val); + } + + pub fn iter(&self) -> impl Iterator> { + self.0.iter().filter_map(|w| w.upgrade()) + } +} From 50864770fecfa21fbeeeb17c389a31127454a12c Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 14:37:28 +0200 Subject: [PATCH 142/203] fix cargo.toml --- Cargo.lock | 816 ++++++++++++++++++++++++++++++++++++++++++- rnex-core/Cargo.toml | 3 +- 2 files changed, 804 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce7b5e9..0fd5a6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -49,6 +55,15 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -67,7 +82,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -76,11 +91,20 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + [[package]] name = "bitflags" version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -117,6 +141,12 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.10.1" @@ -162,6 +192,21 @@ dependencies = [ "inout", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "cookie" version = "0.18.1" @@ -216,6 +261,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + [[package]] name = "crc32fast" version = "1.5.0" @@ -225,6 +285,21 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "crypto-common" version = "0.1.6" @@ -241,6 +316,17 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.4.0" @@ -257,6 +343,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -287,12 +374,49 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] + [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + [[package]] name = "flate2" version = "1.1.5" @@ -303,12 +427,29 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + [[package]] name = "fnv" 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.2" @@ -318,12 +459,50 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + [[package]] name = "futures-core" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + [[package]] name = "futures-macro" version = "0.3.31" @@ -354,9 +533,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", + "futures-io", "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -401,18 +582,53 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -422,6 +638,15 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "http" version = "1.3.1" @@ -572,7 +797,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", ] [[package]] @@ -617,12 +842,49 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + [[package]] name = "libc" version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libredox" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +dependencies = [ + "bitflags", + "libc", + "plain", + "redox_syscall 0.7.4", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "pkg-config", + "vcpkg", +] + [[package]] name = "litemap" version = "0.8.2" @@ -707,12 +969,48 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -720,6 +1018,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -752,6 +1051,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.4" @@ -770,9 +1075,9 @@ checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.17", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -781,6 +1086,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -799,6 +1113,39 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "potential_utf" version = "0.1.4" @@ -999,6 +1346,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" +dependencies = [ + "bitflags", +] + [[package]] name = "ring" version = "0.17.14" @@ -1035,6 +1391,7 @@ dependencies = [ "serde", "serde_json", "simplelog", + "sqlx", "thiserror", "tokio", "typenum", @@ -1042,6 +1399,26 @@ dependencies = [ "v-byte-helpers", ] +[[package]] +name = "rsa" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rustc-demangle" version = "0.1.26" @@ -1101,6 +1478,12 @@ version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + [[package]] name = "schannel" version = "0.1.28" @@ -1182,6 +1565,18 @@ dependencies = [ "zmij", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha1" version = "0.10.6" @@ -1193,6 +1588,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1208,6 +1614,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -1236,6 +1652,9 @@ name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -1247,12 +1666,227 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlx" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" +dependencies = [ + "base64", + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.15.5", + "hashlink", + "indexmap", + "log", + "memchr", + "once_cell", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "thiserror", + "tracing", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.104", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 2.0.104", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" +dependencies = [ + "atoi", + "base64", + "bitflags", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" +dependencies = [ + "atoi", + "base64", + "bitflags", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "thiserror", + "tracing", + "url", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + [[package]] name = "subtle" version = "2.6.1" @@ -1364,6 +1998,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.47.1" @@ -1421,6 +2070,38 @@ dependencies = [ "tungstenite", ] +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + [[package]] name = "tungstenite" version = "0.28.0" @@ -1446,12 +2127,33 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" + [[package]] name = "untrusted" version = "0.9.0" @@ -1522,6 +2224,12 @@ dependencies = [ "macros 0.1.1", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" @@ -1543,6 +2251,12 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -1610,6 +2324,16 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "whoami" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +dependencies = [ + "libredox", + "wasite", +] + [[package]] name = "winapi-util" version = "0.1.9" @@ -1684,13 +2408,22 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -1699,7 +2432,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -1711,34 +2444,67 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "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]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1751,24 +2517,48 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 8d72719..94638a1 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -13,8 +13,7 @@ v-byte-helpers = { git = "https://github.com/RusticMaple/VByteMacros", version = simplelog = "0.12.2" chrono = "0.4.39" log = "0.4.25" -rand = "0.8.5 -" +rand = "0.8.5" cfg-if = "1.0.4" hmac = "0.12.1" md-5 = "^0.10.6" From be6aabb4ebbbb57b8ca07dea7239a7dc4511d96a Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 14:39:05 +0200 Subject: [PATCH 143/203] add pipefails propperly --- check-all.sh | 2 ++ check-edition.sh | 3 +++ 2 files changed, 5 insertions(+) diff --git a/check-all.sh b/check-all.sh index e44fa1b..47cbfbe 100755 --- a/check-all.sh +++ b/check-all.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +set -e pipefail + SETTINGS=$(yq ea "." editions.yaml | yq 'keys[]') IFS=$'\n' while IFS=$'\n' read -r EDITION; do diff --git a/check-edition.sh b/check-edition.sh index 9caaa67..7f814cb 100755 --- a/check-edition.sh +++ b/check-edition.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash + +set -e pipefail + if [ -z ${EDITION+x} ]; then EDITION=$1 fi From f870853630231d2982628a4281dfd57426a7e86b Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 14:57:02 +0200 Subject: [PATCH 144/203] clean up a bit and fix scripts --- build-edition.sh | 3 +++ buildscripts/common.sh | 4 +++- check-all.sh | 3 ++- check-edition.sh | 5 +++-- rnex-core/src/util.rs | 3 +-- test-edition.sh | 3 +++ 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/build-edition.sh b/build-edition.sh index ce17110..6898acf 100755 --- a/build-edition.sh +++ b/build-edition.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash + +set -euo pipefail + if [ -z ${EDITION+x} ]; then EDITION=$1 fi diff --git a/buildscripts/common.sh b/buildscripts/common.sh index f224752..697ae87 100755 --- a/buildscripts/common.sh +++ b/buildscripts/common.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash -set -e pipefail + +set -euo pipefail + TMP_FEATURES_TRAILINGCOMMA=$(yq ea ".$EDITION.features" editions.yaml | sed 's/- //g' | tr '\n' ',') export EDITION_FEATURES=${TMP_FEATURES_TRAILINGCOMMA::-1} SETTINGS=$(yq ea ".$EDITION.settings" editions.yaml | yq 'keys[]') diff --git a/check-all.sh b/check-all.sh index 47cbfbe..d6281ab 100755 --- a/check-all.sh +++ b/check-all.sh @@ -1,9 +1,10 @@ #!/usr/bin/env bash -set -e pipefail +set -euo pipefail SETTINGS=$(yq ea "." editions.yaml | yq 'keys[]') IFS=$'\n' while IFS=$'\n' read -r EDITION; do + export EDITION ./check-edition.sh $EDITION done <<< "$SETTINGS" diff --git a/check-edition.sh b/check-edition.sh index 7f814cb..c734770 100755 --- a/check-edition.sh +++ b/check-edition.sh @@ -1,9 +1,10 @@ #!/usr/bin/env bash -set -e pipefail + +set -euo pipefail if [ -z ${EDITION+x} ]; then - EDITION=$1 + export EDITION=$1 fi # comma seperated list of features for the specified version diff --git a/rnex-core/src/util.rs b/rnex-core/src/util.rs index 582c09b..2bcf87b 100644 --- a/rnex-core/src/util.rs +++ b/rnex-core/src/util.rs @@ -1,9 +1,8 @@ use crate::reggie::{UnitPacketRead, UnitPacketWrite}; use log::{error, info}; -use std::iter::FilterMap; use std::ops::Deref; use std::sync::{Arc, Weak}; -use std::{slice, vec}; +use std::vec; use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; use tokio::sync::Notify; use tokio::sync::mpsc::{Receiver, Sender, channel}; diff --git a/test-edition.sh b/test-edition.sh index ac3fc49..aaafad6 100755 --- a/test-edition.sh +++ b/test-edition.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash + +set -euo pipefail + if [ -z ${EDITION+x} ]; then EDITION=$1 fi From ebefd8f9552f8632b8ba92b0abf886dff82ab5ff Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 15:09:03 +0200 Subject: [PATCH 145/203] add precommit hook --- buildscripts/pre-commit | 14 ++++++++++++++ setup-hook.sh | 3 +++ 2 files changed, 17 insertions(+) create mode 100755 buildscripts/pre-commit create mode 100755 setup-hook.sh diff --git a/buildscripts/pre-commit b/buildscripts/pre-commit new file mode 100755 index 0000000..26c6064 --- /dev/null +++ b/buildscripts/pre-commit @@ -0,0 +1,14 @@ +#!/bin/sh + +echo "running cargo check..." + +./check-all.sh +STATUS=$? + +if [ $STATUS -ne 0 ]; then + echo "cargo check failed, aborting" + exit 1 +fi + +echo "cargo check passed" +exit 0 diff --git a/setup-hook.sh b/setup-hook.sh new file mode 100755 index 0000000..04774d6 --- /dev/null +++ b/setup-hook.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +cp buildscripts/pre-commit .git/hooks/ From 6ff9b33966ce0a9de5b8c091d88d79ac7bd9a8b0 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 16:14:43 +0200 Subject: [PATCH 146/203] shit i forgot to update something --- rnex-core/Cargo.toml | 9 +++------ rnex-core/src/nex/user.rs | 2 -- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 07d4fda..780249c 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -35,22 +35,19 @@ base64 = "0.22.1" sha2 = "0.10.9" urlencoding = "2.1.3" -[dependencies.sqlx] -version = "0.8.6" -optional = true - [dev-dependencies] # criterion = "0.7.0" [features] rmc_struct_header = [] guest_login = [] -friends = ["guest_login", "dep:sqlx"] +friends = ["guest_login", "database-support"] big_pid = [] v3-8-15 = ["rmc_struct_header"] v4-3-11 = ["v3-8-15"] nx = ["big_pid"] -datastore = ["dep:sqlx", "v3-8-15", "dep:aws-sdk-s3", "dep:aws-config"] +datastore = ["database-support", "v3-8-15", "dep:aws-sdk-s3", "dep:aws-config"] +database-support = ["dep:sqlx"] [[bench]] name = "rmc_serialization" diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 1239452..ed8a76f 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -46,8 +46,6 @@ use rnex_core::rmc::structures::qresult::QResult; use rnex_core::rmc::structures::ranking::UploadCompetitionData; use std::sync::{Arc, Weak}; use cfg_if::cfg_if; -use rnex_core::rmc::protocols::ranking::{CompetitionRankingScoreData, CompetitionRankingGetParam, CompetitionRankingScoreInfo}; -use rnex_core::rmc::structures::ranking::{UploadCompetitionData}; use tokio::sync::{Mutex, RwLock}; cfg_if! { From 0b777d00aec5bece16b66004bb513c12a5cf3bf8 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 16:41:40 +0200 Subject: [PATCH 147/203] Seperate sqlx queries --- .ci-scripts/make-edition.sh | 2 +- .forgejo/workflows/build.yml | 4 +- Dockerfile | 1 + ...d3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json | 28 ---- ...df67d1812b99e1ec952a044fc03e1a5c63703.json | 112 ---------------- ...a1675439bb44c91158f8b8a696e326c45447c.json | 38 ------ ...57f27247530878b7f82feeb65802d995a38c4.json | 16 --- ...b8158ea907d36588e1e59f6cbe752d89361bb.json | 22 --- ...e1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json | 22 --- ...002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json | 23 ---- ...8a7a9bf551126712c1d1089a4263453090e79.json | 29 ---- ...71340561031d8e5c91f46c041f83e54c31a7d.json | 40 ------ ...48f5eb4a3761dd71129ba6939cdd0d62569fb.json | 28 ---- ...fe18e500d243f1b55fd18e7d96d281605bcf9.json | 14 -- ...fcecccf8f0f8dd20d890a76acf85265b2192c.json | 125 ------------------ 15 files changed, 5 insertions(+), 499 deletions(-) delete mode 100644 rnex-core/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json delete mode 100644 rnex-core/.sqlx/query-1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703.json delete mode 100644 rnex-core/.sqlx/query-219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c.json delete mode 100644 rnex-core/.sqlx/query-29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4.json delete mode 100644 rnex-core/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json delete mode 100644 rnex-core/.sqlx/query-37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json delete mode 100644 rnex-core/.sqlx/query-3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json delete mode 100644 rnex-core/.sqlx/query-8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79.json delete mode 100644 rnex-core/.sqlx/query-8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d.json delete mode 100644 rnex-core/.sqlx/query-93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb.json delete mode 100644 rnex-core/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json delete mode 100644 rnex-core/.sqlx/query-efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c.json diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh index 57c857a..368b008 100755 --- a/.ci-scripts/make-edition.sh +++ b/.ci-scripts/make-edition.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash export EDITION=$1 -export BA="--build-arg EDITION=$1" +export BA="--build-arg EDITION=$1 --build-arg DATABASE_URL="$DATABASE_URL"" # podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . # podman push "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 4350d20..24ee2dc 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -69,6 +69,7 @@ jobs: env: CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} + DATABASE_URL: ${{ secrets.DATABASE_FRIENDS }} run: ./.ci-scripts/make-edition.sh friends super-mario-maker: @@ -95,8 +96,9 @@ jobs: - name: Login to registry run: podman login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net - - name: Build Friends edition + - name: Build Super Mario Maker edition env: CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} + DATABASE_URL: ${{ secrets.DATABASE_SMM }} run: ./.ci-scripts/make-edition.sh super-mario-maker diff --git a/Dockerfile b/Dockerfile index e181a93..059b9e8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,6 +9,7 @@ WORKDIR /app COPY . . ARG EDITION +ARG DATABASE_URL RUN git submodule update --init --recursive diff --git a/rnex-core/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json b/rnex-core/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json deleted file mode 100644 index abf5c03..0000000 --- a/rnex-core/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT owner, under_review FROM datastore.objects WHERE data_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "owner", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "under_review", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - true, - false - ] - }, - "hash": "164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9" -} diff --git a/rnex-core/.sqlx/query-1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703.json b/rnex-core/.sqlx/query-1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703.json deleted file mode 100644 index befa7e1..0000000 --- a/rnex-core/.sqlx/query-1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date\n FROM datastore.objects WHERE data_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "data_id", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "owner", - "type_info": "Int4" - }, - { - "ordinal": 2, - "name": "size", - "type_info": "Int4" - }, - { - "ordinal": 3, - "name": "name", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "data_type", - "type_info": "Int4" - }, - { - "ordinal": 5, - "name": "meta_binary", - "type_info": "Bytea" - }, - { - "ordinal": 6, - "name": "permission", - "type_info": "Int4" - }, - { - "ordinal": 7, - "name": "permission_recipients", - "type_info": "Int4Array" - }, - { - "ordinal": 8, - "name": "delete_permission", - "type_info": "Int4" - }, - { - "ordinal": 9, - "name": "delete_permission_recipients", - "type_info": "Int4Array" - }, - { - "ordinal": 10, - "name": "period", - "type_info": "Int4" - }, - { - "ordinal": 11, - "name": "refer_data_id", - "type_info": "Int8" - }, - { - "ordinal": 12, - "name": "flag", - "type_info": "Int4" - }, - { - "ordinal": 13, - "name": "tags", - "type_info": "TextArray" - }, - { - "ordinal": 14, - "name": "creation_date", - "type_info": "Timestamp" - }, - { - "ordinal": 15, - "name": "update_date", - "type_info": "Timestamp" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "hash": "1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703" -} diff --git a/rnex-core/.sqlx/query-219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c.json b/rnex-core/.sqlx/query-219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c.json deleted file mode 100644 index cf80412..0000000 --- a/rnex-core/.sqlx/query-219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n INSERT INTO datastore.objects (\n owner, size, name, data_type, meta_binary,\n permission, permission_recipients,\n delete_permission, delete_permission_recipients,\n flag, period, refer_data_id, tags,\n persistence_slot_id, extra_data, creation_date, update_date\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17\n ) RETURNING data_id\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "data_id", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int4", - "Int4", - "Text", - "Int4", - "Bytea", - "Int4", - "Int4Array", - "Int4", - "Int4Array", - "Int4", - "Int4", - "Int8", - "TextArray", - "Int4", - "TextArray", - "Timestamp", - "Timestamp" - ] - }, - "nullable": [ - false - ] - }, - "hash": "219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c" -} diff --git a/rnex-core/.sqlx/query-29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4.json b/rnex-core/.sqlx/query-29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4.json deleted file mode 100644 index 0c3393d..0000000 --- a/rnex-core/.sqlx/query-29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n INSERT INTO datastore.object_custom_rankings (data_id, application_id, value)\n VALUES ($1, $2, $3)\n ON CONFLICT (data_id, application_id)\n DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value\n ", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Int8" - ] - }, - "nullable": [] - }, - "hash": "29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4" -} diff --git a/rnex-core/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json b/rnex-core/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json deleted file mode 100644 index 83246ca..0000000 --- a/rnex-core/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "exists", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - null - ] - }, - "hash": "2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb" -} diff --git a/rnex-core/.sqlx/query-37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json b/rnex-core/.sqlx/query-37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json deleted file mode 100644 index 35c78ee..0000000 --- a/rnex-core/.sqlx/query-37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT data_id\n FROM datastore.objects\n WHERE owner = $1 AND data_type > 2 AND data_type < 50\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "data_id", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int4" - ] - }, - "nullable": [ - false - ] - }, - "hash": "37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92" -} diff --git a/rnex-core/.sqlx/query-3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json b/rnex-core/.sqlx/query-3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json deleted file mode 100644 index 166c25d..0000000 --- a/rnex-core/.sqlx/query-3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT buffer\n FROM datastore.buffer_queues\n WHERE data_id = $1 AND slot = $2\n ORDER BY creation_date ASC\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "buffer", - "type_info": "Bytea" - } - ], - "parameters": { - "Left": [ - "Int8", - "Int4" - ] - }, - "nullable": [ - false - ] - }, - "hash": "3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f" -} diff --git a/rnex-core/.sqlx/query-8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79.json b/rnex-core/.sqlx/query-8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79.json deleted file mode 100644 index dd1c783..0000000 --- a/rnex-core/.sqlx/query-8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n rankings.data_id,\n rankings.value\n FROM datastore.object_custom_rankings rankings\n JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord)\n ON rankings.data_id = rows.data_id\n AND rankings.application_id = $2\n ORDER BY rows.ord\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "data_id", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "value", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int8Array", - "Int8" - ] - }, - "nullable": [ - false, - true - ] - }, - "hash": "8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79" -} diff --git a/rnex-core/.sqlx/query-8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d.json b/rnex-core/.sqlx/query-8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d.json deleted file mode 100644 index dbab55e..0000000 --- a/rnex-core/.sqlx/query-8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT slot, total_value, count, initial_value\n FROM datastore.object_ratings\n WHERE data_id = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "slot", - "type_info": "Int2" - }, - { - "ordinal": 1, - "name": "total_value", - "type_info": "Int8" - }, - { - "ordinal": 2, - "name": "count", - "type_info": "Int4" - }, - { - "ordinal": 3, - "name": "initial_value", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false, - true, - false, - true - ] - }, - "hash": "8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d" -} diff --git a/rnex-core/.sqlx/query-93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb.json b/rnex-core/.sqlx/query-93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb.json deleted file mode 100644 index 0a8127b..0000000 --- a/rnex-core/.sqlx/query-93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT under_review, access_password\n FROM datastore.objects\n WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "under_review", - "type_info": "Bool" - }, - { - "ordinal": 1, - "name": "access_password", - "type_info": "Int8" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - false, - false - ] - }, - "hash": "93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb" -} diff --git a/rnex-core/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json b/rnex-core/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json deleted file mode 100644 index 552f92a..0000000 --- a/rnex-core/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [] - }, - "hash": "e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9" -} diff --git a/rnex-core/.sqlx/query-efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c.json b/rnex-core/.sqlx/query-efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c.json deleted file mode 100644 index 60714c0..0000000 --- a/rnex-core/.sqlx/query-efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c.json +++ /dev/null @@ -1,125 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date,\n access_password, under_review\n FROM datastore.objects\n WHERE owner = $1 AND persistence_slot_id = $2\n AND upload_completed = TRUE AND deleted = FALSE", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "data_id", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "owner", - "type_info": "Int4" - }, - { - "ordinal": 2, - "name": "size", - "type_info": "Int4" - }, - { - "ordinal": 3, - "name": "name", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "data_type", - "type_info": "Int4" - }, - { - "ordinal": 5, - "name": "meta_binary", - "type_info": "Bytea" - }, - { - "ordinal": 6, - "name": "permission", - "type_info": "Int4" - }, - { - "ordinal": 7, - "name": "permission_recipients", - "type_info": "Int4Array" - }, - { - "ordinal": 8, - "name": "delete_permission", - "type_info": "Int4" - }, - { - "ordinal": 9, - "name": "delete_permission_recipients", - "type_info": "Int4Array" - }, - { - "ordinal": 10, - "name": "period", - "type_info": "Int4" - }, - { - "ordinal": 11, - "name": "refer_data_id", - "type_info": "Int8" - }, - { - "ordinal": 12, - "name": "flag", - "type_info": "Int4" - }, - { - "ordinal": 13, - "name": "tags", - "type_info": "TextArray" - }, - { - "ordinal": 14, - "name": "creation_date", - "type_info": "Timestamp" - }, - { - "ordinal": 15, - "name": "update_date", - "type_info": "Timestamp" - }, - { - "ordinal": 16, - "name": "access_password", - "type_info": "Int8" - }, - { - "ordinal": 17, - "name": "under_review", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Int4", - "Int4" - ] - }, - "nullable": [ - false, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - false, - false - ] - }, - "hash": "efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c" -} From 547ae0d76d6a3129be94ce80f71ae71b674f5630 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 26 Apr 2026 17:30:07 +0200 Subject: [PATCH 148/203] fix(ci): set network mode to host --- .ci-scripts/make-edition.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh index 368b008..cb4a879 100755 --- a/.ci-scripts/make-edition.sh +++ b/.ci-scripts/make-edition.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash export EDITION=$1 -export BA="--build-arg EDITION=$1 --build-arg DATABASE_URL="$DATABASE_URL"" +export BA="--network=host --build-arg EDITION=$1 --build-arg DATABASE_URL="$DATABASE_URL"" # podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . # podman push "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" From f8e887496f64acdc4193e1a4dd94da176a4a8a10 Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 19:08:08 +0200 Subject: [PATCH 149/203] add checking of account level on proxy --- buildscripts/common.sh | 1 + prudpv1/src/executables/proxy_secure.rs | 19 +++++++ rnex-core/src/grpc/account.rs | 35 ++++++++++++ rnex-core/src/versions.rs | 72 ++++++++++++------------- 4 files changed, 90 insertions(+), 37 deletions(-) diff --git a/buildscripts/common.sh b/buildscripts/common.sh index 697ae87..e4b346c 100755 --- a/buildscripts/common.sh +++ b/buildscripts/common.sh @@ -3,6 +3,7 @@ set -euo pipefail TMP_FEATURES_TRAILINGCOMMA=$(yq ea ".$EDITION.features" editions.yaml | sed 's/- //g' | tr '\n' ',') +echo "tmpfeatures: $TMP_FEATURES_TRAILINGCOMMA" export EDITION_FEATURES=${TMP_FEATURES_TRAILINGCOMMA::-1} SETTINGS=$(yq ea ".$EDITION.settings" editions.yaml | yq 'keys[]') IFS=$'\n' diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index 2e79317..c338ef9 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -1,6 +1,7 @@ use crate::prudp::router::Router; use crate::prudp::secure::Secure; use log::error; +use log::warn; use proxy_common::{ProxyStartupParam, RNEX_ACCESS_KEY}; use rnex_core::executables::common::SECURE_SERVER_ACCOUNT; use rnex_core::prudp::virtual_port::VirtualPort; @@ -33,6 +34,24 @@ pub async fn start(param: ProxyStartupParam) { }; task::spawn(async move { + let Ok(mut c) = rnex_core::grpc::account::Client::new().await else { + error!("failed to initialize gql client"); + return; + }; + + let v = match c.get_user_level(conn.user_id).await { + Ok(v) => v, + Err(e) => { + error!("failed to get user level: {}", e); + return; + } + }; + + if v < 0 { + warn!("person with too low account level joined"); + return; + } + let mut stream = match TcpStream::connect(param.forward_destination).await { Ok(v) => v, Err(e) => { diff --git a/rnex-core/src/grpc/account.rs b/rnex-core/src/grpc/account.rs index d6ad140..9d2d4e8 100644 --- a/rnex-core/src/grpc/account.rs +++ b/rnex-core/src/grpc/account.rs @@ -103,6 +103,41 @@ impl Client { Ok(val.as_bytes().try_into().map_err(|_| SomethingHappened)?) } + pub async fn get_user_level(&mut self, pid: PID) -> Result { + let req = self + .do_request(object! { + "query": r"query($pid: Int!){ + userByPid(pid: $pid){ + accountLevel + } + }", + "variables": { + "pid": pid + } + }) + .await?; + + let Some(val) = req + .entries() + .find(|v| v.0 == "data") + .ok_or(SomethingHappened)? + .1 + .entries() + .find(|v| v.0 == "userByPid") + .ok_or(SomethingHappened)? + .1 + .entries() + .find(|v| v.0 == "accountLevel") + .ok_or(SomethingHappened)? + .1 + .as_i32() + else { + return Err(SomethingHappened); + }; + + Ok(val) + } + pub async fn get_pid_from_token(&mut self, token: String) -> Result { let req = self .do_request(object! { diff --git a/rnex-core/src/versions.rs b/rnex-core/src/versions.rs index 7b5ec30..03b71b5 100644 --- a/rnex-core/src/versions.rs +++ b/rnex-core/src/versions.rs @@ -3,95 +3,93 @@ use std::ops::{BitAnd, BitOr}; use typenum::{Cmp, IsEqual, IsLess, IsLessOrEqual, Unsigned}; /// This trait represents a version at compile time -trait Version{ +trait Version { type Major: Unsigned; type Minor: Unsigned; } /// This struct contains nothing and is used to represent specific versions as an instance of /// [`Version`]. It is instances as `Ver` -struct Ver{ - _phantom: PhantomData<(MAJ, MIN)> +struct Ver { + _phantom: PhantomData<(MAJ, MIN)>, } -impl Version for Ver{ +impl Version for Ver { type Major = MAJ; type Minor = MIN; } /// Represents two versions which can be compared -trait ComparableVersion: Version{ +trait ComparableVersion: Version { type IsAtLeast: SameOrUnit; } -impl ComparableVersion for U where +impl ComparableVersion for U +where ::Major: Cmp, ::Minor: IsLessOrEqual, - ::Major: IsEqual< - Self::Major, - Output: BitAnd< - typenum::LeEq - >, - >, + ::Major: + IsEqual>>, ::Major: IsLess< - Self::Major, - Output: BitOr< - typenum::And< - typenum::Eq, - typenum::LeEq, + Self::Major, + Output: BitOr< + typenum::And< + typenum::Eq, + typenum::LeEq, + >, + Output: SameOrUnit, >, - Output: SameOrUnit - > - > { - + >, +{ type IsAtLeast = typenum::Or< typenum::Le, - typenum::And< - typenum::Eq, - typenum::LeEq, - > + typenum::And, typenum::LeEq>, >; } - /// Simple check for testing if the `TEST` version is at least `REQ` or higher. type VersionAbove = >::IsAtLeast; -trait VersionIsAtLeast{} - -impl> VersionIsAtLeast for T{} +trait VersionIsAtLeast {} +impl> VersionIsAtLeast + for T +{ +} /// Trait for containing the result of elements which only conditionally exist -trait CondElemResult{ +trait CondElemResult { type Output; } /// Empty helper struct which only servers to give a concrete type when creating fields in rmc /// structs which have a version requirement. This is not meant to be used directly, use /// [`MinVersion`] instead. -struct MinVersionElementHelper>{ - _phantom: PhantomData<(T, REQUIRED, VER)> +struct MinVersionElementHelper> { + _phantom: PhantomData<(T, REQUIRED, VER)>, } /// This should be used either with [`typenum::True`] or [`typenum::False`]. When `True` the [`Self::Output`] /// will be the same as the `T` you put into Output. When `False` it will always be `()` -trait SameOrUnit{ +trait SameOrUnit { type Output; } -impl SameOrUnit for typenum::True{ +impl SameOrUnit for typenum::True { type Output = T; } -impl SameOrUnit for typenum::False{ +impl SameOrUnit for typenum::False { type Output = (); } -impl> CondElemResult for MinVersionElementHelper where { +impl> CondElemResult + for MinVersionElementHelper +{ type Output = <>::IsAtLeast as SameOrUnit>::Output; } /// When the version condition is met the field will exist and will simply be `T` if not it will be /// replaced by `()`. Use this when you need to add versioning to rmc structs. -type MinVersion = as CondElemResult>::Output; \ No newline at end of file +type MinVersion = + as CondElemResult>::Output; From 9275f3b09f4ed824ff3bc9b4531f815bb28140e9 Mon Sep 17 00:00:00 2001 From: Maple Date: Sun, 26 Apr 2026 23:20:42 +0200 Subject: [PATCH 150/203] restrict what gets checked and implement sending of fragmented packets --- check-all.sh | 11 +++-- editions.yaml | 4 ++ prudpv1/src/prudp/socket.rs | 47 +++++++++++-------- rnex-core/src/executables/common.rs | 7 +-- rnex-core/src/nex/user.rs | 4 +- rnex-core/src/rmc/protocols/datastore.rs | 60 +++++++++++++++++------- 6 files changed, 86 insertions(+), 47 deletions(-) diff --git a/check-all.sh b/check-all.sh index d6281ab..1494e10 100755 --- a/check-all.sh +++ b/check-all.sh @@ -2,9 +2,12 @@ set -euo pipefail -SETTINGS=$(yq ea "." editions.yaml | yq 'keys[]') +EDITIONS=$(yq ea "." editions.yaml | yq 'keys[]') IFS=$'\n' while IFS=$'\n' read -r EDITION; do - export EDITION - ./check-edition.sh $EDITION -done <<< "$SETTINGS" + if [[ $(yq ea ".$EDITION.include-in-checkall" editions.yaml) == "true" ]] + then + export EDITION + ./check-edition.sh $EDITION + fi +done <<< "$EDITIONS" diff --git a/editions.yaml b/editions.yaml index 632274f..3801571 100644 --- a/editions.yaml +++ b/editions.yaml @@ -1,4 +1,5 @@ wiiu-chat: + include-in-checkall: true features: - prudpv1 - v3-8-15 @@ -9,6 +10,7 @@ wiiu-chat: RNEX_DEFAULT_PORT: 10000 RNEX_ACCESS_KEY: "e7a47214" splatoon: + include-in-checkall: true features: - prudpv1 - v3-8-15 @@ -19,6 +21,7 @@ splatoon: RNEX_DEFAULT_PORT: 6000 RNEX_ACCESS_KEY: "6f599f81" friends: + include-in-checkall: false features: - friends settings: @@ -28,6 +31,7 @@ friends: RNEX_DEFAULT_PORT: 6000 RNEX_ACCESS_KEY: "ridfebb9" super-mario-maker: + include-in-checkall: false features: - prudpv1 - v3-8-15 diff --git a/prudpv1/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs index a3b0445..c04f106 100644 --- a/prudpv1/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -177,31 +177,40 @@ pub(super) trait AnyInternalConnection: #[async_trait] impl AnyInternalConnection for InternalConnection { async fn send_data_packet(&mut self, data: Vec) { - let mut packet = PRUDPV1Packet { - header: PRUDPV1Header { - sequence_id: self.next_server_count(), - substream_id: 0, - session_id: self.session_id, - types_and_flags: TypesFlags::default().types(DATA).flags(RELIABLE | NEED_ACK), - destination_port: self.common.socket_addr.virtual_port, - source_port: self.server_port, + let pieces = data.chunks(600); + let max_piece = pieces.len() - 1; + let mut piece_num = 1; + for (i, piece) in pieces.enumerate() { + let mut packet = PRUDPV1Packet { + header: PRUDPV1Header { + sequence_id: self.next_server_count(), + substream_id: 0, + session_id: self.session_id, + types_and_flags: TypesFlags::default().types(DATA).flags(RELIABLE | NEED_ACK), + destination_port: self.common.socket_addr.virtual_port, + source_port: self.server_port, + ..Default::default() + }, + payload: piece.to_owned(), + options: vec![FragmentId(if i == max_piece { 0 } else { piece_num })], ..Default::default() - }, - payload: data, - options: vec![FragmentId(0)], - ..Default::default() - }; + }; - self.crypto_handler_instance - .encrypt_outgoing(0, &mut packet.payload[..]); + self.crypto_handler_instance + .encrypt_outgoing(0, &mut packet.payload[..]); - packet.set_sizes(); + packet.set_sizes(); - self.crypto_handler_instance.sign_packet(&mut packet); + self.crypto_handler_instance.sign_packet(&mut packet); - self.send_raw_packet(&packet).await; + self.send_raw_packet(&packet).await; - self.unacknowleged_packets.push((Instant::now(), packet)); + self.unacknowleged_packets.push((Instant::now(), packet)); + + sleep(Duration::from_secs(16)).await; + + piece_num += 1; + } } async fn close_connection(&mut self) { diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index 280ab7f..b2ea50d 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -8,18 +8,15 @@ use std::io::Cursor; use std::net::{Ipv4Addr, SocketAddrV4}; use std::sync::Arc; use tokio::net::TcpListener; -use std::sync::LazyLock; -use std::sync::OnceLock; cfg_if! { if #[cfg(feature = "datastore")] { use sqlx::postgres::PgPool; } } +use crate::reggie::UnitPacketRead; +use cfg_if::cfg_if; use log::error; use std::error::Error; -use std::string::ToString; -use cfg_if::cfg_if; -use crate::reggie::UnitPacketRead; const IP_REQ_SERVICE_URL: &str = "https://ipinfo.io/ip"; diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index ed8a76f..757bb72 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -23,7 +23,6 @@ use rnex_core::rmc::protocols::matchmake_extension::{ }; use rnex_core::rmc::protocols::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking}; use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; -use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore}; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::any::Any; use rnex_core::rmc::structures::matchmake::{ @@ -34,6 +33,7 @@ use std::env; use std::str::FromStr; use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; +use cfg_if::cfg_if; use log::{error, info}; use macros::rmc_struct; use rnex_core::prudp::socket_addr::PRUDPSockAddr; @@ -45,11 +45,11 @@ use rnex_core::rmc::structures::qbuffer::QBuffer; use rnex_core::rmc::structures::qresult::QResult; use rnex_core::rmc::structures::ranking::UploadCompetitionData; use std::sync::{Arc, Weak}; -use cfg_if::cfg_if; use tokio::sync::{Mutex, RwLock}; cfg_if! { if #[cfg(feature = "datastore")] { + use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore}; define_rmc_proto!( proto UserProtocol{ Secure, diff --git a/rnex-core/src/rmc/protocols/datastore.rs b/rnex-core/src/rmc/protocols/datastore.rs index 0c68fc5..51d5365 100644 --- a/rnex-core/src/rmc/protocols/datastore.rs +++ b/rnex-core/src/rmc/protocols/datastore.rs @@ -1,9 +1,9 @@ -use macros::{method_id, rmc_proto, RmcSerialize, rmc_struct}; -use rnex_core::rmc::structures::qbuffer::QBuffer; -use rnex_core::rmc::response::ErrorCode; -use rnex_core::rmc::structures::qresult::QResult; -use rnex_core::kerberos::KerberosDateTime; +use macros::{RmcSerialize, method_id, rmc_proto}; use rnex_core::PID; +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::structures::qbuffer::QBuffer; +use rnex_core::rmc::structures::qresult::QResult; use rnex_core::rmc::structures::resultsrange::ResultsRange; #[derive(RmcSerialize, Clone, Debug, Default)] @@ -78,7 +78,7 @@ pub struct RatingInitParam { pub range_min: i32, pub range_max: i32, pub period_hour: i8, - pub period_duration: i16 + pub period_duration: i16, } #[derive(RmcSerialize, Clone)] @@ -214,27 +214,53 @@ pub struct DataStoreSearchParam { } #[rmc_proto(115)] -pub trait DataStore{ +pub trait DataStore { #[method_id(8)] async fn get_meta(&self, metaparam: GetMetaParam) -> Result; #[method_id(36)] - async fn get_metas_multiple_param(&self, params: Vec) -> Result<(Vec, Vec), ErrorCode>; + async fn get_metas_multiple_param( + &self, + params: Vec, + ) -> Result<(Vec, Vec), ErrorCode>; #[method_id(24)] - async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result; + async fn prepare_post_object( + &self, + postparam: PreparePostParam, + ) -> Result; #[method_id(26)] - async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode>; + async fn complete_post_object(&self, completeparam: CompletePostParam) + -> Result<(), ErrorCode>; #[method_id(48)] - async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode>; + async fn rate_custom_ranking( + &self, + rankingparam: Vec, + ) -> Result<(), ErrorCode>; #[method_id(61)] async fn get_application_config(&self, appid: u32) -> Result, ErrorCode>; #[method_id(50)] - async fn get_custom_ranking_by_data_id(&self, custom_ranking_param: DataStoreGetCustomRankingByDataIDParam) -> Result<(Vec, Vec), ErrorCode>; + async fn get_custom_ranking_by_data_id( + &self, + custom_ranking_param: DataStoreGetCustomRankingByDataIDParam, + ) -> Result<(Vec, Vec), ErrorCode>; #[method_id(54)] - async fn get_buffer_queue(&self, bufferparam: BufferQueueParam) -> Result, ErrorCode>; + async fn get_buffer_queue( + &self, + bufferparam: BufferQueueParam, + ) -> Result, ErrorCode>; #[method_id(25)] - async fn prepare_get_object(&self, prepare_get_param: DataStorePrepareGetParam) -> Result; + async fn prepare_get_object( + &self, + prepare_get_param: DataStorePrepareGetParam, + ) -> Result; #[method_id(65)] - async fn followings_latest_course_search_object(&self, course_search_param: DataStoreSearchParam, extra_data: Vec) -> Result, ErrorCode>; + async fn followings_latest_course_search_object( + &self, + course_search_param: DataStoreSearchParam, + extra_data: Vec, + ) -> Result, ErrorCode>; #[method_id(74)] - async fn get_application_config_string(&self, application_id: u32) -> Result, ErrorCode>; -} \ No newline at end of file + async fn get_application_config_string( + &self, + application_id: u32, + ) -> Result, ErrorCode>; +} From dc6307cfcf85c88140483c21ae86598f0f4fadb5 Mon Sep 17 00:00:00 2001 From: Maple Date: Mon, 27 Apr 2026 00:09:55 +0200 Subject: [PATCH 151/203] dont lock up the connection whilest sending fragments --- prudpv1/src/prudp/socket.rs | 138 +-- rnex-core/src/executables/common.rs | 1 + rnex-core/src/nex/datastore.rs | 1497 ++++++++++++++++----------- 3 files changed, 953 insertions(+), 683 deletions(-) diff --git a/prudpv1/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs index c04f106..c6f5faa 100644 --- a/prudpv1/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -16,6 +16,7 @@ use std::io::Cursor; use std::marker::PhantomData; use std::ops::Deref; use std::sync::{Arc, Weak}; +use tokio::spawn; use v_byte_helpers::ReadExtensions; use v_byte_helpers::little_endian::read_u16; @@ -68,6 +69,33 @@ impl InternalConnection { prev_val } + async fn close_connection(&mut self) { + let mut packet = PRUDPV1Packet { + header: PRUDPV1Header { + sequence_id: self.next_server_count(), + substream_id: 0, + session_id: self.session_id, + types_and_flags: TypesFlags::default().types(DISCONNECT), + destination_port: self.common.socket_addr.virtual_port, + source_port: self.server_port, + ..Default::default() + }, + payload: Vec::new(), + options: vec![FragmentId(0)], + ..Default::default() + }; + + // no need for encryption the, the payload is empty + + packet.set_sizes(); + + self.crypto_handler_instance.sign_packet(&mut packet); + + self.send_raw_packet(&packet).await; + + self.delete_connection().await; + } + /// Sends a raw packet to a given client on the connection /// /// a raw packet is one which does not get processed any further(other than to send it @@ -103,7 +131,7 @@ pub struct ExternalConnection { #[derive(Clone)] pub struct SendingConnection { common: Arc, - internal: Weak>, + internal: Weak, } pub struct CommonSocket { @@ -166,80 +194,67 @@ pub(super) trait AnyInternalSocket: } #[async_trait] -pub(super) trait AnyInternalConnection: - Send + Sync + Deref + 'static -{ - async fn send_data_packet(&mut self, data: Vec); +pub(super) trait AnyInternalConnection: Send + Sync + 'static { + async fn send_data_packet(&self, data: Vec); - async fn close_connection(&mut self); + async fn close_connection(&self); } #[async_trait] -impl AnyInternalConnection for InternalConnection { - async fn send_data_packet(&mut self, data: Vec) { +impl AnyInternalConnection for Mutex> { + async fn send_data_packet(&self, data: Vec) { let pieces = data.chunks(600); let max_piece = pieces.len() - 1; let mut piece_num = 1; - for (i, piece) in pieces.enumerate() { - let mut packet = PRUDPV1Packet { - header: PRUDPV1Header { - sequence_id: self.next_server_count(), - substream_id: 0, - session_id: self.session_id, - types_and_flags: TypesFlags::default().types(DATA).flags(RELIABLE | NEED_ACK), - destination_port: self.common.socket_addr.virtual_port, - source_port: self.server_port, + let mut locked = self.lock().await; + let packets: Vec<_> = pieces + .enumerate() + .map(|(i, piece)| { + let mut packet = PRUDPV1Packet { + header: PRUDPV1Header { + sequence_id: locked.next_server_count(), + substream_id: 0, + session_id: locked.session_id, + types_and_flags: TypesFlags::default() + .types(DATA) + .flags(RELIABLE | NEED_ACK), + destination_port: locked.common.socket_addr.virtual_port, + source_port: locked.server_port, + ..Default::default() + }, + payload: piece.to_owned(), + options: vec![FragmentId(if i == max_piece { 0 } else { piece_num })], ..Default::default() - }, - payload: piece.to_owned(), - options: vec![FragmentId(if i == max_piece { 0 } else { piece_num })], - ..Default::default() - }; + }; - self.crypto_handler_instance - .encrypt_outgoing(0, &mut packet.payload[..]); + locked + .crypto_handler_instance + .encrypt_outgoing(0, &mut packet.payload[..]); - packet.set_sizes(); + packet.set_sizes(); - self.crypto_handler_instance.sign_packet(&mut packet); + locked.crypto_handler_instance.sign_packet(&mut packet); - self.send_raw_packet(&packet).await; + piece_num += 1; + packet + }) + .collect(); + drop(locked); - self.unacknowleged_packets.push((Instant::now(), packet)); + for packet in packets { + let mut locked = self.lock().await; + locked.send_raw_packet(&packet).await; + locked.unacknowleged_packets.push((Instant::now(), packet)); + drop(locked); sleep(Duration::from_secs(16)).await; - - piece_num += 1; } } - async fn close_connection(&mut self) { - // jon confirmed that this should be a safe way to dc a client + async fn close_connection(&self) { + let mut locked = self.lock().await; - let mut packet = PRUDPV1Packet { - header: PRUDPV1Header { - sequence_id: self.next_server_count(), - substream_id: 0, - session_id: self.session_id, - types_and_flags: TypesFlags::default().types(DISCONNECT), - destination_port: self.common.socket_addr.virtual_port, - source_port: self.server_port, - ..Default::default() - }, - payload: Vec::new(), - options: vec![FragmentId(0)], - ..Default::default() - }; - - // no need for encryption the, the payload is empty - - packet.set_sizes(); - - self.crypto_handler_instance.sign_packet(&mut packet); - - self.send_raw_packet(&packet).await; - - self.delete_connection().await; + locked.close_connection().await; } } @@ -403,7 +418,7 @@ impl InternalSocket { let internal = Arc::new(Mutex::new(internal)); - let dyn_internal: Arc> = internal.clone(); + let dyn_internal: Arc = internal.clone(); let external = ExternalConnection { sending: SendingConnection { @@ -884,10 +899,9 @@ impl ExternalConnection { impl SendingConnection { pub async fn send(&self, data: Vec) -> Option<()> { let internal = self.internal.upgrade()?; - - let mut internal = internal.lock().await; - - internal.send_data_packet(data).await; + spawn(async move { + internal.send_data_packet(data).await; + }); Some(()) } @@ -896,8 +910,6 @@ impl SendingConnection { return; }; - let mut internal = internal.lock().await; - internal.close_connection().await; } } diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index b2ea50d..c94a463 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -22,6 +22,7 @@ const IP_REQ_SERVICE_URL: &str = "https://ipinfo.io/ip"; cfg_if! { if #[cfg(feature = "datastore")] { + use std::sync::{LazyLock, OnceLock}; pub static RNEX_DATASTORE_DATABASE_URL: LazyLock = LazyLock::new(|| { std::env::var("RNEX_DATASTORE_DATABASE_URL") .expect("RNEX_DATASTORE_DATABASE_URL must be set") diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index 763bc3e..fad7300 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -1,140 +1,144 @@ -use cfg_if::cfg_if; -cfg_if! { - if #[cfg(feature = "datastore")] { - use crate::define_rmc_proto; - use macros::rmc_struct; - use rnex_core::prudp::socket_addr::PRUDPSockAddr; - use std::sync::{Weak}; - use chrono::Utc; - use sqlx::types::time; - use sqlx::types::time::PrimitiveDateTime; - use rnex_core::PID; - use rnex_core::nex::remote_console::RemoteConsole; - use rnex_core::nex::s3presigner::S3Presigner; - use rnex_core::rmc::response::ErrorCode; - use rnex_core::rmc::protocols::secure::{Secure, RawSecure, RawSecureInfo, RemoteSecure}; - use rnex_core::rmc::protocols::datastore::{BufferQueueParam, CompletePostParam, DataStoreCustomRankingResult, DataStoreGetCustomRankingByDataIDParam, DataStorePrepareGetParam, DataStoreReqGetInfo, DataStoreSearchParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, RateCustomRankingParam, RatingInfo, RatingInfoWithSlot}; - use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore, PreparePostParam, ReqPostInfo}; - use crate::nex::user::User; - use rnex_core::executables::common::{RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db}; - use rnex_core::rmc::structures::qbuffer::QBuffer; - use sqlx::types::chrono::DateTime; - use rnex_core::kerberos::KerberosDateTime; - use rnex_core::rmc::structures::qresult::QResult; +use crate::nex::user::User; +use rnex_core::executables::common::{ + RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db, +}; +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::nex::s3presigner::S3Presigner; +use rnex_core::rmc::protocols::datastore::{ + BufferQueueParam, CompletePostParam, DataStoreCustomRankingResult, + DataStoreGetCustomRankingByDataIDParam, DataStorePrepareGetParam, DataStoreReqGetInfo, + DataStoreSearchParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, + RateCustomRankingParam, RatingInfo, RatingInfoWithSlot, +}; +use rnex_core::rmc::protocols::datastore::{DataStore, PreparePostParam, ReqPostInfo}; +use rnex_core::rmc::response::ErrorCode; +use rnex_core::rmc::structures::qbuffer::QBuffer; +use rnex_core::rmc::structures::qresult::QResult; +use sqlx::types::time; - fn map_row_to_meta_info( - row_data_id: i64, - row_owner: i32, - row_size: i32, - row_name: String, - row_data_type: i16, - row_meta_binary: Vec, - row_permission: i16, - row_permission_recipients: Vec, - row_delete_permission: i16, - row_delete_permission_recipients: Vec, - row_period: i16, - row_refer_data_id: i64, - row_flag: i32, - row_tags: Vec, - row_creation_date: chrono::NaiveDateTime, - row_update_date: chrono::NaiveDateTime, - ratings: Vec - ) -> GetMetaInfo { - GetMetaInfo { - dataid: row_data_id as u64, - owner: row_owner as u32, - size: row_size as u32, - name: row_name, - data_type: row_data_type as u16, - meta_binary: QBuffer(row_meta_binary), - permission: Permission { - permission: row_permission as u8, - recipient_ids: row_permission_recipients.into_iter().map(|id| id as u32).collect(), - }, - del_permission: Permission { - permission: row_delete_permission as u8, - recipient_ids: row_delete_permission_recipients.into_iter().map(|id| id as u32).collect(), - }, - period: row_period as u16, - status: 0, - referred_count: 0, - refer_dat_id: row_refer_data_id as u32, - flag: row_flag as u32, - tags: row_tags, - expire_time: KerberosDateTime::from_u64(0x9C3F3E0000), - created_time: KerberosDateTime::from_naive(row_creation_date), - updated_time: KerberosDateTime::from_naive(row_update_date), - referred_time: KerberosDateTime::from_naive(row_creation_date), - ratings, - } - } +fn map_row_to_meta_info( + row_data_id: i64, + row_owner: i32, + row_size: i32, + row_name: String, + row_data_type: i16, + row_meta_binary: Vec, + row_permission: i16, + row_permission_recipients: Vec, + row_delete_permission: i16, + row_delete_permission_recipients: Vec, + row_period: i16, + row_refer_data_id: i64, + row_flag: i32, + row_tags: Vec, + row_creation_date: chrono::NaiveDateTime, + row_update_date: chrono::NaiveDateTime, + ratings: Vec, +) -> GetMetaInfo { + GetMetaInfo { + dataid: row_data_id as u64, + owner: row_owner as u32, + size: row_size as u32, + name: row_name, + data_type: row_data_type as u16, + meta_binary: QBuffer(row_meta_binary), + permission: Permission { + permission: row_permission as u8, + recipient_ids: row_permission_recipients + .into_iter() + .map(|id| id as u32) + .collect(), + }, + del_permission: Permission { + permission: row_delete_permission as u8, + recipient_ids: row_delete_permission_recipients + .into_iter() + .map(|id| id as u32) + .collect(), + }, + period: row_period as u16, + status: 0, + referred_count: 0, + refer_dat_id: row_refer_data_id as u32, + flag: row_flag as u32, + tags: row_tags, + expire_time: KerberosDateTime::from_u64(0x9C3F3E0000), + created_time: KerberosDateTime::from_naive(row_creation_date), + updated_time: KerberosDateTime::from_naive(row_update_date), + referred_time: KerberosDateTime::from_naive(row_creation_date), + ratings, + } +} - async fn check_object_availability(data_id: u64, password: u64) -> Result<(), ErrorCode> { - let row = sqlx::query!( - r#" +async fn check_object_availability(data_id: u64, password: u64) -> Result<(), ErrorCode> { + let row = sqlx::query!( + r#" SELECT under_review, access_password FROM datastore.objects WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE "#, - data_id as i64 - ) - .fetch_optional(get_db()) - .await - .map_err(|e| { - eprintln!("Availability check DB error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })? - .ok_or(ErrorCode::DataStore_NotFound)?; + data_id as i64 + ) + .fetch_optional(get_db()) + .await + .map_err(|e| { + eprintln!("Availability check DB error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })? + .ok_or(ErrorCode::DataStore_NotFound)?; - let access_password = row.access_password as u64; - if access_password != 0 && access_password != password { - return Err(ErrorCode::DataStore_InvalidPassword); - } + let access_password = row.access_password as u64; + if access_password != 0 && access_password != password { + return Err(ErrorCode::DataStore_InvalidPassword); + } - if row.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } + if row.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } - Ok(()) - } + Ok(()) +} - async fn get_object_ratings(data_id: u64, password: u64) -> Result, ErrorCode> { - check_object_availability(data_id, password).await?; +async fn get_object_ratings( + data_id: u64, + password: u64, +) -> Result, ErrorCode> { + check_object_availability(data_id, password).await?; - let rows = sqlx::query!( - r#" + let rows = sqlx::query!( + r#" SELECT slot, total_value, count, initial_value FROM datastore.object_ratings WHERE data_id = $1 "#, - data_id as i64 - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - eprintln!("Ratings fetch error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; + data_id as i64 + ) + .fetch_all(get_db()) + .await + .map_err(|e| { + eprintln!("Ratings fetch error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; - let ratings = rows.into_iter().map(|row| { - RatingInfoWithSlot { - slot: row.slot as i8, - rating: RatingInfo { - total_value: row.total_value.unwrap_or(0), - count: row.count as u32, - initial_value: row.initial_value.unwrap_or(0), - }, - } - }).collect(); + let ratings = rows + .into_iter() + .map(|row| RatingInfoWithSlot { + slot: row.slot as i8, + rating: RatingInfo { + total_value: row.total_value.unwrap_or(0), + count: row.count as u32, + initial_value: row.initial_value.unwrap_or(0), + }, + }) + .collect(); - Ok(ratings) - } + Ok(ratings) +} - async fn get_object_info_by_data_id(data_id: u64, password: u64) -> Result { - check_object_availability(data_id, password).await?; +async fn get_object_info_by_data_id(data_id: u64, password: u64) -> Result { + check_object_availability(data_id, password).await?; - let row = sqlx::query!( + let row = sqlx::query!( r#"SELECT data_id, owner, size, name, data_type, meta_binary, permission, permission_recipients, delete_permission, delete_permission_recipients, period, refer_data_id, flag, tags, creation_date, update_date @@ -146,37 +150,68 @@ cfg_if! { .map_err(|_| ErrorCode::DataStore_SystemFileError)? .ok_or(ErrorCode::DataStore_NotFound)?; - let ratings = get_object_ratings(data_id, password).await?; + let ratings = get_object_ratings(data_id, password).await?; - Ok(map_row_to_meta_info( - row.data_id, - row.owner.unwrap_or(0), - row.size.unwrap_or(0), - row.name.unwrap_or_default(), - row.data_type.unwrap_or(0) as i16, - row.meta_binary.unwrap_or_default(), - row.permission.unwrap_or(0) as i16, - row.permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), - row.delete_permission.unwrap_or(0) as i16, - row.delete_permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), - row.period.unwrap_or(0) as i16, - row.refer_data_id.unwrap_or(0), - row.flag.unwrap_or(0), - row.tags.unwrap_or_default(), - row.creation_date.map(|dt| chrono::NaiveDateTime::new( - chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), - chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() - )).unwrap_or_default(), - row.update_date.map(|dt| chrono::NaiveDateTime::new( - chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), - chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() - )).unwrap_or_default(), - ratings - )) - } + Ok(map_row_to_meta_info( + row.data_id, + row.owner.unwrap_or(0), + row.size.unwrap_or(0), + row.name.unwrap_or_default(), + row.data_type.unwrap_or(0) as i16, + row.meta_binary.unwrap_or_default(), + row.permission.unwrap_or(0) as i16, + row.permission_recipients + .unwrap_or_default() + .into_iter() + .map(|id| id as i64) + .collect(), + row.delete_permission.unwrap_or(0) as i16, + row.delete_permission_recipients + .unwrap_or_default() + .into_iter() + .map(|id| id as i64) + .collect(), + row.period.unwrap_or(0) as i16, + row.refer_data_id.unwrap_or(0), + row.flag.unwrap_or(0), + row.tags.unwrap_or_default(), + row.creation_date + .map(|dt| { + chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32) + .unwrap(), + chrono::NaiveTime::from_hms_opt( + dt.hour() as u32, + dt.minute() as u32, + dt.second() as u32, + ) + .unwrap(), + ) + }) + .unwrap_or_default(), + row.update_date + .map(|dt| { + chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32) + .unwrap(), + chrono::NaiveTime::from_hms_opt( + dt.hour() as u32, + dt.minute() as u32, + dt.second() as u32, + ) + .unwrap(), + ) + }) + .unwrap_or_default(), + ratings, + )) +} - async fn get_object_info_by_persistence_target(target: PersistenceTarget, password: u64) -> Result { - let row = sqlx::query!( +async fn get_object_info_by_persistence_target( + target: PersistenceTarget, + password: u64, +) -> Result { + let row = sqlx::query!( r#"SELECT data_id, owner, size, name, data_type, meta_binary, permission, permission_recipients, delete_permission, delete_permission_recipients, period, refer_data_id, flag, tags, creation_date, update_date, @@ -192,124 +227,146 @@ cfg_if! { .map_err(|_| ErrorCode::DataStore_SystemFileError)? .ok_or(ErrorCode::DataStore_NotFound)?; - let db_password = row.access_password as u64; - if db_password != 0 && db_password != password { - return Err(ErrorCode::DataStore_InvalidPassword); - } + let db_password = row.access_password as u64; + if db_password != 0 && db_password != password { + return Err(ErrorCode::DataStore_InvalidPassword); + } - if row.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } + if row.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } - let ratings = get_object_ratings(row.data_id as u64, password).await?; + let ratings = get_object_ratings(row.data_id as u64, password).await?; - Ok(map_row_to_meta_info( - row.data_id, - row.owner.unwrap_or(0), - row.size.unwrap_or(0), - row.name.unwrap_or_default(), - row.data_type.unwrap_or(0) as i16, - row.meta_binary.unwrap_or_default(), - row.permission.unwrap_or(0) as i16, - row.permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), - row.delete_permission.unwrap_or(0) as i16, - row.delete_permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), - row.period.unwrap_or(0) as i16, - row.refer_data_id.unwrap_or(0), - row.flag.unwrap_or(0), - row.tags.unwrap_or_default(), - row.creation_date.map(|dt| chrono::NaiveDateTime::new( - chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), - chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() - )).unwrap_or_default(), - row.update_date.map(|dt| chrono::NaiveDateTime::new( - chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), - chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() - )).unwrap_or_default(), - ratings - )) - } + Ok(map_row_to_meta_info( + row.data_id, + row.owner.unwrap_or(0), + row.size.unwrap_or(0), + row.name.unwrap_or_default(), + row.data_type.unwrap_or(0) as i16, + row.meta_binary.unwrap_or_default(), + row.permission.unwrap_or(0) as i16, + row.permission_recipients + .unwrap_or_default() + .into_iter() + .map(|id| id as i64) + .collect(), + row.delete_permission.unwrap_or(0) as i16, + row.delete_permission_recipients + .unwrap_or_default() + .into_iter() + .map(|id| id as i64) + .collect(), + row.period.unwrap_or(0) as i16, + row.refer_data_id.unwrap_or(0), + row.flag.unwrap_or(0), + row.tags.unwrap_or_default(), + row.creation_date + .map(|dt| { + chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32) + .unwrap(), + chrono::NaiveTime::from_hms_opt( + dt.hour() as u32, + dt.minute() as u32, + dt.second() as u32, + ) + .unwrap(), + ) + }) + .unwrap_or_default(), + row.update_date + .map(|dt| { + chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32) + .unwrap(), + chrono::NaiveTime::from_hms_opt( + dt.hour() as u32, + dt.minute() as u32, + dt.second() as u32, + ) + .unwrap(), + ) + }) + .unwrap_or_default(), + ratings, + )) +} - async fn get_buffer_queues_by_data_id_and_slot( - data_id: u64, - slot: u32 - ) -> Result, ErrorCode> { - check_object_availability(data_id, 0).await?; +async fn get_buffer_queues_by_data_id_and_slot( + data_id: u64, + slot: u32, +) -> Result, ErrorCode> { + check_object_availability(data_id, 0).await?; - let rows = sqlx::query!( - r#" + let rows = sqlx::query!( + r#" SELECT buffer FROM datastore.buffer_queues WHERE data_id = $1 AND slot = $2 ORDER BY creation_date ASC "#, - data_id as i64, - slot as i32 - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - log::error!("Buffer queue fetch error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; + data_id as i64, + slot as i32 + ) + .fetch_all(get_db()) + .await + .map_err(|e| { + log::error!("Buffer queue fetch error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; - let buffer_queues = rows - .into_iter() - .map(|row| QBuffer(row.buffer)) - .collect(); + let buffer_queues = rows.into_iter().map(|row| QBuffer(row.buffer)).collect(); - Ok(buffer_queues) - } + Ok(buffer_queues) +} - fn verify_object_permission( - owner_id: u32, - viewer_id: u32, - permission: &Permission, - ) -> Result<(), ErrorCode> { - if owner_id == viewer_id { - return Ok(()); - } +fn verify_object_permission( + owner_id: u32, + viewer_id: u32, + permission: &Permission, +) -> Result<(), ErrorCode> { + if owner_id == viewer_id { + return Ok(()); + } - match permission.permission { - 0 => Ok(()), // All can read - 1 => Err(ErrorCode::DataStore_PermissionDenied), // Friends only, unimplemented - 2 => { - // Recipient IDs can read - if permission.recipient_ids.contains(&viewer_id) { - Ok(()) - } else { - Err(ErrorCode::DataStore_PermissionDenied) - } - } - 3 => Err(ErrorCode::DataStore_PermissionDenied), // Owner only, redundant - _ => Err(ErrorCode::DataStore_InvalidArgument), // ??? haxx0r + match permission.permission { + 0 => Ok(()), // All can read + 1 => Err(ErrorCode::DataStore_PermissionDenied), // Friends only, unimplemented + 2 => { + // Recipient IDs can read + if permission.recipient_ids.contains(&viewer_id) { + Ok(()) + } else { + Err(ErrorCode::DataStore_PermissionDenied) } } + 3 => Err(ErrorCode::DataStore_PermissionDenied), // Owner only, redundant + _ => Err(ErrorCode::DataStore_InvalidArgument), // ??? haxx0r + } +} - fn filter_properties_by_result_option( - meta_info: &mut GetMetaInfo, - result_option: u8, - ) { - if (result_option & 0x01) == 0 { - meta_info.meta_binary = QBuffer(Vec::new()); - } +fn filter_properties_by_result_option(meta_info: &mut GetMetaInfo, result_option: u8) { + if (result_option & 0x01) == 0 { + meta_info.meta_binary = QBuffer(Vec::new()); + } - if (result_option & 0x04) == 0 { - meta_info.ratings = Vec::new(); - } + if (result_option & 0x04) == 0 { + meta_info.ratings = Vec::new(); + } - // No idea what the other things do. :shrug: - } + // No idea what the other things do. :shrug: +} - // Dawg... - async fn get_custom_rankings_by_data_ids( - application_id: u32, - data_ids: Vec - ) -> Vec { - let mut results = Vec::with_capacity(data_ids.len()); +// Dawg... +async fn get_custom_rankings_by_data_ids( + application_id: u32, + data_ids: Vec, +) -> Vec { + let mut results = Vec::with_capacity(data_ids.len()); - let rows = sqlx::query!( - r#" + let rows = sqlx::query!( + r#" SELECT rankings.data_id, rankings.value @@ -319,124 +376,263 @@ cfg_if! { AND rankings.application_id = $2 ORDER BY rows.ord "#, - &data_ids.iter().map(|&id| id as i64).collect::>(), - application_id as i32 - ) - .fetch_all(get_db()) - .await; + &data_ids.iter().map(|&id| id as i64).collect::>(), + application_id as i32 + ) + .fetch_all(get_db()) + .await; - let rows = match rows { - Ok(r) => r, - Err(e) => { - log::error!("Custom ranking query error: {:?}", e); - return results; - } - }; - - for row in rows { - let data_id = row.data_id as u64; - let score = row.value.unwrap_or(0) as u32; - - if let Ok(meta) = get_object_info_by_data_id(data_id, 0).await { - results.push(DataStoreCustomRankingResult { - order: 0, - score, - meta_info: meta, - }); - } else { - log::warn!("Could not find metadata for ranked object {}", data_id); - } - } - - results + let rows = match rows { + Ok(r) => r, + Err(e) => { + log::error!("Custom ranking query error: {:?}", e); + return results; } + }; - async fn get_user_course_object_ids(owner_pid: u32) -> Result, ErrorCode> { - let rows = sqlx::query!( - r#" + for row in rows { + let data_id = row.data_id as u64; + let score = row.value.unwrap_or(0) as u32; + + if let Ok(meta) = get_object_info_by_data_id(data_id, 0).await { + results.push(DataStoreCustomRankingResult { + order: 0, + score, + meta_info: meta, + }); + } else { + log::warn!("Could not find metadata for ranked object {}", data_id); + } + } + + results +} + +async fn get_user_course_object_ids(owner_pid: u32) -> Result, ErrorCode> { + let rows = sqlx::query!( + r#" SELECT data_id FROM datastore.objects WHERE owner = $1 AND data_type > 2 AND data_type < 50 "#, - owner_pid as i64 + owner_pid as i64 + ) + .fetch_all(get_db()) + .await + .map_err(|e| { + log::error!("error fetching course IDs for PID {}: {:?}", owner_pid, e); + ErrorCode::DataStore_SystemFileError + })?; + + let mut valid_ids = Vec::new(); + for row in rows { + let data_id = row.data_id as u64; + // always check avail + if check_object_availability(data_id, 0).await.is_ok() { + valid_ids.push(data_id); + } + } + + Ok(valid_ids) +} + +fn get_blacklist_1() -> Vec { + vec![ + "けされ", + "消され", + "削除され", + "リセットされ", + "BANされ", + "BANされ", + "キミのコース", + "君のコース", + "きみのコース", + "い い ね", + "遊びます", + "地震", + "震災", + "被災", + "津波", + "バンされ", + "い~ね", + "震度", + "じしん", + "banされ", + "くわしくは", + "詳しくは", + "ちんちん", + "ち0こ", + "bicth", + "い.い.ね", + "ナイ~ス", + "い&い", + "い-いね", + "いぃね", + "nigger", + "ngger", + "star if u", + "Star if u", + "Star if you", + "star if you", + "PENlS", + "マンコ", + "butthole", + "LILI", + "vagina", + "vagyna", + "うんち", + "うんこ", + "ウンコ", + "Iine", + "EENE", + "まんこ", + "ウンチ", + "niglet", + "nigglet", + "please like", + "きんたま", + "Butthole", + "llね", + "iいね", + "give a star", + "ちんぽ", + "亀頭", + "penis", + "ウンコ", + "plz more stars", + "star plz", + "い()ね", + "PLEASE star", + "Bitte Sterne", + ] + .into_iter() + .map(String::from) + .collect() +} + +fn get_blacklist_2() -> Vec { + vec![ + "ゼロから", + "0から", + "0から", + "い  い  ね", + "いい", + "東日本", + "大震", + ] + .into_iter() + .map(String::from) + .collect() +} + +fn get_blacklist_3() -> Vec { + vec![ + "いいね", + "下さい", + "ください", + "押して", + "おして", + "返す", + "かえす", + "星", + "してくれ", + "するよ", + "☆くれたら", + "☆あげます", + "★くれたら", + "★あげます", + "しね", + "ころす", + "ころされた", + "アナル", + "ファック", + "キンタマ", + "○ね", + "キチガイ", + "うんこ", + "KITIGAI", + "金玉", + "おっぱい", + "☆おす", + "☆押す", + "★おす", + "★押す", + "いいする", + "いいよ", + "イイネ", + "ケツ", + "うんち", + "かくせいざい", + "覚せい剤", + "シャブ", + "きんたま", + "ちんちん", + "おしっこ", + "ちんぽこ", + "ころして", + "グッド", + "グット", + "レ●プ", + "バーカ", + "きちがい", + "ちんげ", + "マンコ", + "まんこ", + "チンポ", + "クズ", + "ウンコ", + "ナイスおねがいします", + "penis", + "イイね", + "☆よろ", + "ナイス!して", + "ま/んこ", + "まん/こ", + ] + .into_iter() + .map(String::from) + .collect() +} + +impl DataStore for User { + async fn get_meta(&self, mut metaparam: GetMetaParam) -> Result { + let mut meta_info = if metaparam.dataid != 0 { + get_object_info_by_data_id(metaparam.dataid, metaparam.access_password).await? + } else { + get_object_info_by_persistence_target( + metaparam.persistence_target, + metaparam.access_password, ) - .fetch_all(get_db()) - .await - .map_err(|e| { - log::error!("error fetching course IDs for PID {}: {:?}", owner_pid, e); - ErrorCode::DataStore_SystemFileError - })?; + .await? + }; - let mut valid_ids = Vec::new(); - for row in rows { - let data_id = row.data_id as u64; - // always check avail - if check_object_availability(data_id, 0).await.is_ok() { - valid_ids.push(data_id); - } - } + let current_pid = self.pid; + verify_object_permission(meta_info.owner, current_pid, &meta_info.permission)?; - Ok(valid_ids) - } + filter_properties_by_result_option(&mut meta_info, metaparam.result_option); - fn get_blacklist_1() -> Vec { - vec![ - "けされ", "消され", "削除され", "リセットされ", "BANされ", "BANされ", - "キミのコース", "君のコース", "きみのコース", "い い ね", "遊びます", "地震", - "震災", "被災", "津波", "バンされ", "い~ね", "震度", "じしん", "banされ", - "くわしくは", "詳しくは", "ちんちん", "ち0こ", "bicth", "い.い.ね", - "ナイ~ス", "い&い", "い-いね", "いぃね", "nigger", "ngger", "star if u", - "Star if u", "Star if you", "star if you", "PENlS", "マンコ", "butthole", - "LILI", "vagina", "vagyna", "うんち", "うんこ", "ウンコ", "Iine", - "EENE", "まんこ", "ウンチ", "niglet", "nigglet", "please like", "きんたま", - "Butthole", "llね", "iいね", "give a star", "ちんぽ", "亀頭", "penis", - "ウンコ", "plz more stars", "star plz", "い()ね", "PLEASE star", "Bitte Sterne", - ].into_iter().map(String::from).collect() - } + Ok(meta_info) + } - fn get_blacklist_2() -> Vec { - vec![ - "ゼロから", "0から", "0から", "い  い  ね", "いい", "東日本", "大震", - ].into_iter().map(String::from).collect() - } + async fn prepare_post_object( + &self, + postparam: PreparePostParam, + ) -> Result { + let recipient_ids: Vec = postparam + .permission + .recipient_ids + .iter() + .map(|&id| id as i32) + .collect(); + let del_recipient_ids: Vec = postparam + .del_permission + .recipient_ids + .iter() + .map(|&id| id as i32) + .collect(); + let now = time::OffsetDateTime::now_utc(); - fn get_blacklist_3() -> Vec { - vec![ - "いいね", "下さい", "ください", "押して", "おして", "返す", "かえす", - "星", "してくれ", "するよ", "☆くれたら", "☆あげます", "★くれたら", - "★あげます", "しね", "ころす", "ころされた", "アナル", "ファック", - "キンタマ", "○ね", "キチガイ", "うんこ", "KITIGAI", "金玉", "おっぱい", - "☆おす", "☆押す", "★おす", "★押す", "いいする", "いいよ", "イイネ", - "ケツ", "うんち", "かくせいざい", "覚せい剤", "シャブ", "きんたま", - "ちんちん", "おしっこ", "ちんぽこ", "ころして", "グッド", "グット", - "レ●プ", "バーカ", "きちがい", "ちんげ", "マンコ", "まんこ", "チンポ", - "クズ", "ウンコ", "ナイスおねがいします", "penis", "イイね", "☆よろ", - "ナイス!して", "ま/んこ", "まん/こ", - ].into_iter().map(String::from).collect() - } - - impl DataStore for User { - async fn get_meta(&self, mut metaparam: GetMetaParam) -> Result { - let mut meta_info = if metaparam.dataid != 0 { - get_object_info_by_data_id(metaparam.dataid, metaparam.access_password).await? - } else { - get_object_info_by_persistence_target(metaparam.persistence_target, metaparam.access_password).await? - }; - - let current_pid = self.pid; - verify_object_permission(meta_info.owner, current_pid, &meta_info.permission)?; - - filter_properties_by_result_option(&mut meta_info, metaparam.result_option); - - Ok(meta_info) - } - - async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result { - let recipient_ids: Vec = postparam.permission.recipient_ids.iter().map(|&id| id as i32).collect(); - let del_recipient_ids: Vec = postparam.del_permission.recipient_ids.iter().map(|&id| id as i32).collect(); - let now = time::OffsetDateTime::now_utc(); - - let row = sqlx::query!( + let row = sqlx::query!( r#" INSERT INTO datastore.objects ( owner, size, name, data_type, meta_binary, @@ -473,87 +669,95 @@ cfg_if! { ErrorCode::DataStore_SystemFileError })?; - let data_id = row.data_id as u64; - let presigner = S3Presigner::new( - &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), - format!("{}", *RNEX_DATASTORE_S3_BUCKET) - ).await; + let data_id = row.data_id as u64; + let presigner = S3Presigner::new( + &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), + format!("{}", *RNEX_DATASTORE_S3_BUCKET), + ) + .await; - let key = format!("data/{}.bin", data_id); + let key = format!("data/{}.bin", data_id); - let (upload_url, fields) = presigner.generate_presigned_post(&key).await; + let (upload_url, fields) = presigner.generate_presigned_post(&key).await; - let form_fields = fields.into_iter().map(|(k, v)| { - KeyValue { key: k, value: v } - }).collect(); + let form_fields = fields + .into_iter() + .map(|(k, v)| KeyValue { key: k, value: v }) + .collect(); - Ok(ReqPostInfo { - dataid: data_id, - url: upload_url, - request_headers: vec![], - form_fields, - root_ca_cert: vec![], - }) + Ok(ReqPostInfo { + dataid: data_id, + url: upload_url, + request_headers: vec![], + form_fields, + root_ca_cert: vec![], + }) + } + + async fn complete_post_object( + &self, + completeparam: CompletePostParam, + ) -> Result<(), ErrorCode> { + log::info!("Data ID: {:?}", completeparam.dataid); + log::info!("Success: {:?}", completeparam.success); + + let record = sqlx::query!( + r#"SELECT owner, under_review FROM datastore.objects WHERE data_id = $1"#, + completeparam.dataid as i64 + ) + .fetch_optional(get_db()) + .await + .map_err(|e| { + eprintln!("select error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + + let record = record.ok_or(ErrorCode::DataStore_NotFound)?; + + if record.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } + + if record.owner.unwrap_or(0) as u32 != self.pid { + return Err(ErrorCode::DataStore_PermissionDenied); + } + + if completeparam.success { + sqlx::query!( + r#"UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1"#, + completeparam.dataid as i64 + ) + .execute(get_db()) + .await + .map_err(|e| { + eprintln!("update error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + } else { + return Err(ErrorCode::Transport_TemporaryServerError); + } + + Ok(()) + } + + async fn rate_custom_ranking( + &self, + rankingparam: Vec, + ) -> Result<(), ErrorCode> { + for abcparam in rankingparam { + let exists = sqlx::query_scalar!( + r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#, + abcparam.dataid as i64 + ) + .fetch_one(get_db()) + .await + .map_err(|_| ErrorCode::DataStore_SystemFileError)?; + + if !exists.unwrap_or(false) { + return Err(ErrorCode::DataStore_NotFound); } - async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode> { - log::info!("Data ID: {:?}", completeparam.dataid); - log::info!("Success: {:?}", completeparam.success); - - let record = sqlx::query!( - r#"SELECT owner, under_review FROM datastore.objects WHERE data_id = $1"#, - completeparam.dataid as i64 - ) - .fetch_optional(get_db()) - .await - .map_err(|e| { - eprintln!("select error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; - - let record = record.ok_or(ErrorCode::DataStore_NotFound)?; - - if record.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } - - if record.owner.unwrap_or(0) as u32 != self.pid { - return Err(ErrorCode::DataStore_PermissionDenied); - } - - if completeparam.success { - sqlx::query!( - r#"UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1"#, - completeparam.dataid as i64 - ) - .execute(get_db()) - .await - .map_err(|e| { - eprintln!("update error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; - } else { - return Err(ErrorCode::Transport_TemporaryServerError); - } - - Ok(()) - } - - async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode> { - for abcparam in rankingparam { - let exists = sqlx::query_scalar!( - r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#, - abcparam.dataid as i64 - ) - .fetch_one(get_db()) - .await - .map_err(|_| ErrorCode::DataStore_SystemFileError)?; - - if !exists.unwrap_or(false) { - return Err(ErrorCode::DataStore_NotFound); - } - - sqlx::query!( + sqlx::query!( r#" INSERT INTO datastore.object_custom_rankings (data_id, application_id, value) VALUES ($1, $2, $3) @@ -570,216 +774,269 @@ cfg_if! { log::error!("update/insert error: {:?}", e); ErrorCode::DataStore_SystemFileError })?; + } + + Ok(()) + } + + async fn get_application_config(&self, appid: u32) -> Result, ErrorCode> { + const MAX_COURSE_UPLOADS: i32 = 100; + + let config = match appid { + 0 => vec![ + 0x00000001, + 0x00000032, + 0x00000096, + 0x0000012c, + 0x000001f4, + 0x00000320, + 0x00000514, + 0x000007d0, + 0x00000bb8, + 0x00001388, + MAX_COURSE_UPLOADS, + 0x00000014, + 0x0000001e, + 0x00000028, + 0x00000032, + 0x0000003c, + 0x00000046, + 0x00000050, + 0x0000005a, + 0x00000064, + 0x00000023, + 0x0000004b, + 0x00000023, + 0x0000004b, + 0x00000032, + 0x00000000, + 0x00000003, + 0x00000003, + 0x00000064, + 0x00000006, + 0x00000001, + 0x00000060, + 0x00000005, + 0x00000060, + 0x00000000, + 0x000007e4, + 0x00000001, + 0x00000001, + 0x0000000c, + 0x00000000, + ], + 1 => vec![ + 2, 1770179696, 1770179664, 1770179640, 1770180827, 1770180777, 1770180745, + 1770177625, 1770177590, + ], + 2 => vec![0x000007df, 0x0000000c, 0x00000016, 0x00000005, 0x00000000], + 10 => vec![35, 75, 96, 40, 5, 6], + _ => { + log::error!("unknown SMM app id: {}", appid); + return Err(ErrorCode::DataStore_Unknown); + } + }; + + Ok(config) + } + + async fn get_custom_ranking_by_data_id( + &self, + custom_ranking_param: DataStoreGetCustomRankingByDataIDParam, + ) -> Result<(Vec, Vec), ErrorCode> { + println!("appid: {:?}", custom_ranking_param.application_id); + println!("dataid list: {:?}", custom_ranking_param.data_id_list); + println!("result option: {:?}", custom_ranking_param.result_option); + + let mut ranking_results = get_custom_rankings_by_data_ids( + custom_ranking_param.application_id, + custom_ranking_param.data_id_list, + ) + .await; + + let mut q_results = Vec::with_capacity(ranking_results.len()); + + for result in &mut ranking_results { + if (custom_ranking_param.result_option & 0x01) == 0 { + result.meta_info.tags = Vec::new(); + } + + if (custom_ranking_param.result_option & 0x02) == 0 { + result.meta_info.ratings = Vec::new(); + } + + if (custom_ranking_param.result_option & 0x04) == 0 { + result.meta_info.meta_binary = QBuffer(Vec::new()); + } + + if (custom_ranking_param.result_option & 0x20) == 0 { + result.score = 0; + } + + q_results.push(QResult::success(ErrorCode::Core_Unknown)); + } + + Ok((ranking_results, q_results)) + } + + async fn get_buffer_queue( + &self, + bufferparam: BufferQueueParam, + ) -> Result, ErrorCode> { + // log::info!("GetBufferQueue: dataid={}, slot={}", param.dataid, param.slot); + + let buffers = + get_buffer_queues_by_data_id_and_slot(bufferparam.dataid, bufferparam.slot).await?; + + Ok(buffers) + } + + async fn prepare_get_object( + &self, + prepare_get_param: DataStorePrepareGetParam, + ) -> Result { + let meta_info = if prepare_get_param.dataid != 0 { + get_object_info_by_data_id(prepare_get_param.dataid, prepare_get_param.access_password) + .await? + } else { + get_object_info_by_persistence_target( + prepare_get_param.persistence_target, + prepare_get_param.access_password, + ) + .await? + }; + + verify_object_permission(meta_info.owner, self.pid, &meta_info.permission)?; + + let presigner = S3Presigner::new( + &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), + format!("{}", *RNEX_DATASTORE_S3_BUCKET), + ) + .await; + + let key = format!("data/{}.bin", meta_info.dataid); + let download_url = presigner.generate_presigned_get(&key); + + Ok(DataStoreReqGetInfo { + url: download_url, + request_headers: vec![], + size: meta_info.size, + root_ca_cert: vec![], + dataid: meta_info.dataid, + }) + } + + async fn followings_latest_course_search_object( + &self, + course_search_param: DataStoreSearchParam, + _extra_data: Vec, + ) -> Result, ErrorCode> { + let mut all_results = Vec::new(); + + for &owner_pid in &course_search_param.owner_ids { + let course_ids = get_user_course_object_ids(owner_pid).await?; + + if course_ids.is_empty() { + continue; + } + + let mut results = get_custom_rankings_by_data_ids(0, course_ids).await; + + // Flag 0x1: Return Tags + // Flag 0x2: Return Ratings + // Flag 0x4: Return MetaBinary + // Flag 0x20: Return Score + for res in &mut results { + if course_search_param.result_option & 0x1 == 0 { + res.meta_info.tags = Vec::new(); } - - Ok(()) - } - - async fn get_application_config(&self, appid: u32) -> Result, ErrorCode> { - const MAX_COURSE_UPLOADS: i32 = 100; - - let config = match appid { - 0 => vec![ - 0x00000001, 0x00000032, 0x00000096, 0x0000012c, 0x000001f4, - 0x00000320, 0x00000514, 0x000007d0, 0x00000bb8, 0x00001388, - MAX_COURSE_UPLOADS, 0x00000014, 0x0000001e, 0x00000028, 0x00000032, - 0x0000003c, 0x00000046, 0x00000050, 0x0000005a, 0x00000064, - 0x00000023, 0x0000004b, 0x00000023, 0x0000004b, 0x00000032, - 0x00000000, 0x00000003, 0x00000003, 0x00000064, 0x00000006, - 0x00000001, 0x00000060, 0x00000005, 0x00000060, 0x00000000, - 0x000007e4, 0x00000001, 0x00000001, 0x0000000c, 0x00000000, - ], - 1 => vec![ - 2, - 1770179696, - 1770179664, - 1770179640, - 1770180827, - 1770180777, - 1770180745, - 1770177625, - 1770177590, - ], - 2 => vec![0x000007df, 0x0000000c, 0x00000016, 0x00000005, 0x00000000], - 10 => vec![35, 75, 96, 40, 5, 6], - _ => { - log::error!("unknown SMM app id: {}", appid); - return Err(ErrorCode::DataStore_Unknown); - } - }; - - Ok(config) - } - - async fn get_custom_ranking_by_data_id( - &self, - custom_ranking_param: DataStoreGetCustomRankingByDataIDParam - ) -> Result<(Vec, Vec), ErrorCode> { - println!("appid: {:?}", custom_ranking_param.application_id); - println!("dataid list: {:?}", custom_ranking_param.data_id_list); - println!("result option: {:?}", custom_ranking_param.result_option); - - let mut ranking_results = get_custom_rankings_by_data_ids(custom_ranking_param.application_id, custom_ranking_param.data_id_list).await; - - let mut q_results = Vec::with_capacity(ranking_results.len()); - - for result in &mut ranking_results { - if (custom_ranking_param.result_option & 0x01) == 0 { - result.meta_info.tags = Vec::new(); - } - - if (custom_ranking_param.result_option & 0x02) == 0 { - result.meta_info.ratings = Vec::new(); - } - - if (custom_ranking_param.result_option & 0x04) == 0 { - result.meta_info.meta_binary = QBuffer(Vec::new()); - } - - if (custom_ranking_param.result_option & 0x20) == 0 { - result.score = 0; - } - - q_results.push(QResult::success(ErrorCode::Core_Unknown)); + if course_search_param.result_option & 0x2 == 0 { + res.meta_info.ratings = Vec::new(); } - - Ok((ranking_results, q_results)) - } - - async fn get_buffer_queue(&self, bufferparam: BufferQueueParam) -> Result, ErrorCode> { - // log::info!("GetBufferQueue: dataid={}, slot={}", param.dataid, param.slot); - - let buffers = get_buffer_queues_by_data_id_and_slot(bufferparam.dataid, bufferparam.slot).await?; - - Ok(buffers) - } - - async fn prepare_get_object(&self, prepare_get_param: DataStorePrepareGetParam) -> Result { - let meta_info = if prepare_get_param.dataid != 0 { - get_object_info_by_data_id(prepare_get_param.dataid, prepare_get_param.access_password).await? - } else { - get_object_info_by_persistence_target(prepare_get_param.persistence_target, prepare_get_param.access_password).await? - }; - - verify_object_permission(meta_info.owner, self.pid, &meta_info.permission)?; - - let presigner = S3Presigner::new( - &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), - format!("{}", *RNEX_DATASTORE_S3_BUCKET) - ).await; - - let key = format!("data/{}.bin", meta_info.dataid); - let download_url = presigner.generate_presigned_get(&key); - - Ok(DataStoreReqGetInfo { - url: download_url, - request_headers: vec![], - size: meta_info.size, - root_ca_cert: vec![], - dataid: meta_info.dataid, - }) - } - - async fn followings_latest_course_search_object( - &self, - course_search_param: DataStoreSearchParam, - _extra_data: Vec - ) -> Result, ErrorCode> { - let mut all_results = Vec::new(); - - for &owner_pid in &course_search_param.owner_ids { - let course_ids = get_user_course_object_ids(owner_pid).await?; - - if course_ids.is_empty() { - continue; - } - - let mut results = get_custom_rankings_by_data_ids(0, course_ids).await; - - // Flag 0x1: Return Tags - // Flag 0x2: Return Ratings - // Flag 0x4: Return MetaBinary - // Flag 0x20: Return Score - for res in &mut results { - if course_search_param.result_option & 0x1 == 0 { - res.meta_info.tags = Vec::new(); - } - if course_search_param.result_option & 0x2 == 0 { - res.meta_info.ratings = Vec::new(); - } - if course_search_param.result_option & 0x4 == 0 { - res.meta_info.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); - } - if course_search_param.result_option & 0x20 == 0 { - res.score = 0; - } - } - - all_results.extend(results); + if course_search_param.result_option & 0x4 == 0 { + res.meta_info.meta_binary = + rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); + } + if course_search_param.result_option & 0x20 == 0 { + res.score = 0; } - - // note: we assume the client sorts the data lol - - Ok(all_results) } - async fn get_application_config_string(&self, application_id: u32) -> Result, ErrorCode> { - let config = match application_id { - 128 => get_blacklist_1(), - 129 => get_blacklist_2(), - 130 => get_blacklist_3(), - _ => { - log::warn!("unsupported application_id in GetApplicationConfigString: {}", application_id); - Vec::new() - } - }; + all_results.extend(results); + } - Ok(config) + // note: we assume the client sorts the data lol + + Ok(all_results) + } + + async fn get_application_config_string( + &self, + application_id: u32, + ) -> Result, ErrorCode> { + let config = match application_id { + 128 => get_blacklist_1(), + 129 => get_blacklist_2(), + 130 => get_blacklist_3(), + _ => { + log::warn!( + "unsupported application_id in GetApplicationConfigString: {}", + application_id + ); + Vec::new() } + }; - async fn get_metas_multiple_param( - &self, - params: Vec - ) -> Result<(Vec, Vec), ErrorCode> { - let mut metas = Vec::with_capacity(params.len()); - let mut results = Vec::with_capacity(params.len()); + Ok(config) + } - for param in params { - let info_result = if param.dataid != 0 { - get_object_info_by_data_id(param.dataid, param.access_password).await + async fn get_metas_multiple_param( + &self, + params: Vec, + ) -> Result<(Vec, Vec), ErrorCode> { + let mut metas = Vec::with_capacity(params.len()); + let mut results = Vec::with_capacity(params.len()); + + for param in params { + let info_result = if param.dataid != 0 { + get_object_info_by_data_id(param.dataid, param.access_password).await + } else { + get_object_info_by_persistence_target( + param.persistence_target, + param.access_password, + ) + .await + }; + + match info_result { + Ok(mut meta) => { + if let Err(e) = verify_object_permission(meta.owner, self.pid, &meta.permission) + { + metas.push(GetMetaInfo::default()); + results.push(QResult::error(e)); } else { - get_object_info_by_persistence_target(param.persistence_target, param.access_password).await - }; - - match info_result { - Ok(mut meta) => { - if let Err(e) = verify_object_permission(meta.owner, self.pid, &meta.permission) { - metas.push(GetMetaInfo::default()); - results.push(QResult::error(e)); - } else { - if param.result_option & 0x1 == 0 { - meta.tags = Vec::new(); - } - if param.result_option & 0x2 == 0 { - meta.ratings = Vec::new(); - } - if param.result_option & 0x4 == 0 { - meta.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); - } - - metas.push(meta); - results.push(QResult::success(ErrorCode::Core_Unknown)); - } + if param.result_option & 0x1 == 0 { + meta.tags = Vec::new(); } - Err(e) => { - metas.push(GetMetaInfo::default()); - results.push(QResult::error(e)); + if param.result_option & 0x2 == 0 { + meta.ratings = Vec::new(); } + if param.result_option & 0x4 == 0 { + meta.meta_binary = + rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); + } + + metas.push(meta); + results.push(QResult::success(ErrorCode::Core_Unknown)); } } - - Ok((metas, results)) + Err(e) => { + metas.push(GetMetaInfo::default()); + results.push(QResult::error(e)); + } } } + + Ok((metas, results)) } -} \ No newline at end of file +} From dd1926fd3a278618bb618185311bdc3a5d247797 Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 27 Apr 2026 03:21:00 +0200 Subject: [PATCH 152/203] debugging --- rnex-core/src/nex/user.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 757bb72..2575b00 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -698,6 +698,9 @@ impl Ranking for User { team_votes, }; + println!("info: {:?}", info); + println!("score data: {:?}", score_data); + Ok(vec![info]) } From a17e91484991045da197898c864e28e69f0bbb68 Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 27 Apr 2026 03:21:46 +0200 Subject: [PATCH 153/203] bro --- rnex-core/src/nex/user.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 2575b00..88a7498 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -692,7 +692,7 @@ impl Ranking for User { let info = CompetitionRankingScoreInfo { fest_id, - score_data, + score_data: score_data.clone(), unk: 0, team_wins: wins, team_votes, From ce14f2676e802d202b40f66a7430f7f050acd8c4 Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 27 Apr 2026 03:35:11 +0200 Subject: [PATCH 154/203] log resultsrange --- rnex-core/src/nex/user.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 88a7498..ce75c17 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -692,14 +692,13 @@ impl Ranking for User { let info = CompetitionRankingScoreInfo { fest_id, - score_data: score_data.clone(), + score_data, unk: 0, team_wins: wins, team_votes, }; - println!("info: {:?}", info); - println!("score data: {:?}", score_data); + println!("range: {:?}", param.range); Ok(vec![info]) } From 12ce2e59c025be2fa7d0fa4d1215fb47b5b99612 Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 27 Apr 2026 03:46:23 +0200 Subject: [PATCH 155/203] NEX ragebait --- rnex-core/src/nex/user.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index ce75c17..38bd357 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -657,6 +657,11 @@ impl Ranking for User { let url_results = format!("{}?splatfest_id={}", endpoint_results, fest_id); let response_results = ureq::get(&url_results).call(); + let offset = param.range.offset as usize; + let size = param.range.size as usize; + + let start = offset.min(results.len()); + let end = (start + size).min(results.len()); let results: Vec = match response_results { Ok(mut res) => res.body_mut().read_json().map_err(|e| { @@ -678,7 +683,7 @@ impl Ranking for User { }; } - let score_data: Vec = results + let score_data: Vec = results[start..end] .iter() .map(|r| CompetitionRankingScoreData { unk: 1, From e7044e21e9c05039602bfda82f9f0c9857675973 Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 27 Apr 2026 03:46:41 +0200 Subject: [PATCH 156/203] NEX ragebait again --- rnex-core/src/nex/user.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 38bd357..e8a50fa 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -657,11 +657,6 @@ impl Ranking for User { let url_results = format!("{}?splatfest_id={}", endpoint_results, fest_id); let response_results = ureq::get(&url_results).call(); - let offset = param.range.offset as usize; - let size = param.range.size as usize; - - let start = offset.min(results.len()); - let end = (start + size).min(results.len()); let results: Vec = match response_results { Ok(mut res) => res.body_mut().read_json().map_err(|e| { @@ -674,6 +669,12 @@ impl Ranking for User { } }; + let offset = param.range.offset as usize; + let size = param.range.size as usize; + + let start = offset.min(results.len()); + let end = (start + size).min(results.len()); + let team_votes = fetch_team_votes(fest_id)?; let mut wins = vec![0u32, 0u32]; for r in &results { From c5822ae632bdda0535ebcca5460864544782041c Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 27 Apr 2026 22:36:36 +0200 Subject: [PATCH 157/203] Add support for older NEX version and add Wii U Chat to CI --- .forgejo/workflows/build.yml | 30 ++++++++++++++++++++++++++++++ editions.yaml | 2 +- rnex-core/Cargo.toml | 3 ++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 24ee2dc..f76432e 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -11,6 +11,36 @@ env: SHORT_SHA: ${{ github.sha }} jobs: + wii-u-chat: + runs-on: debian-trixie + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Cache container storage + uses: actions/cache@v4 + with: + path: | + /var/lib/containers/storage + /run/containers/storage + ~/.local/share/containers/storage + key: image-cache + + - name: Login to registry + run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net + + - name: Set short SHA + run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV + + - name: Build Wii U Chat edition + env: + CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex + CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} + run: ./.ci-scripts/make-edition.sh wii-u-chat + splatoon: runs-on: debian-trixie diff --git a/editions.yaml b/editions.yaml index 3801571..dddf891 100644 --- a/editions.yaml +++ b/editions.yaml @@ -2,7 +2,7 @@ wiiu-chat: include-in-checkall: true features: - prudpv1 - - v3-8-15 + - v3-3-2 settings: AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" RNEX_VIRTUAL_PORT_INSECURE: "1:10" diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 780249c..56991b1 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -43,7 +43,8 @@ rmc_struct_header = [] guest_login = [] friends = ["guest_login", "database-support"] big_pid = [] -v3-8-15 = ["rmc_struct_header"] +v3-3-2 = [] +v3-8-15 = ["rmc_struct_header", "v3-3-2"] v4-3-11 = ["v3-8-15"] nx = ["big_pid"] datastore = ["database-support", "v3-8-15", "dep:aws-sdk-s3", "dep:aws-config"] From ed84a47a2e243236f50d8de7777ded688841f41c Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 27 Apr 2026 22:40:36 +0200 Subject: [PATCH 158/203] fix typo --- editions.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editions.yaml b/editions.yaml index dddf891..b1ae006 100644 --- a/editions.yaml +++ b/editions.yaml @@ -1,4 +1,4 @@ -wiiu-chat: +wii-u-chat: include-in-checkall: true features: - prudpv1 From c828d3b9733d19a53ddcb53f09e3ed3a858f74a5 Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 28 Apr 2026 00:13:07 +0200 Subject: [PATCH 159/203] add wii u chat functions --- rnex-core/Cargo.toml | 3 +- rnex-core/src/main.rs | 127 ----------------- rnex-core/src/nex/matchmake.rs | 88 +++++++----- rnex-core/src/nex/user.rs | 129 ++++++++++++++++-- .../src/rmc/protocols/matchmake_extension.rs | 68 +++++++-- rnex-core/src/rmc/protocols/notifications.rs | 16 +++ rnex-core/src/rmc/structures/matchmake.rs | 65 ++++++--- 7 files changed, 295 insertions(+), 201 deletions(-) delete mode 100644 rnex-core/src/main.rs diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 56991b1..6617a92 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -44,7 +44,8 @@ guest_login = [] friends = ["guest_login", "database-support"] big_pid = [] v3-3-2 = [] -v3-8-15 = ["rmc_struct_header", "v3-3-2"] +v3-5-0 = ["v3-3-2"] +v3-8-15 = ["rmc_struct_header", "v3-5-0"] v4-3-11 = ["v3-8-15"] nx = ["big_pid"] datastore = ["database-support", "v3-8-15", "dep:aws-sdk-s3", "dep:aws-config"] diff --git a/rnex-core/src/main.rs b/rnex-core/src/main.rs deleted file mode 100644 index eda5915..0000000 --- a/rnex-core/src/main.rs +++ /dev/null @@ -1,127 +0,0 @@ -#![allow(dead_code)] -#![allow(async_fn_in_trait)] -//#![warn(missing_docs)] - -//! # Splatoon RNEX server -//! -//! This server still includes the code for rnex itself as this is the first rnex server and thus -//! also the first and only current usage of rnex, expect this and rnex to be split into seperate -//! repos soon. - -extern crate self as rust_nex; - -use once_cell::sync::Lazy; -use std::hint::black_box; - -mod prudp; -pub mod rmc; -//mod protocols; - -mod grpc; -mod kerberos; -mod nex; -mod result; -mod versions; -pub mod reggie; -pub mod util; -pub mod common; - -pub mod config{ - pub const FEATURE_HAS_STRUCT_HEADER: bool = cfg!(feature = "rmc_struct_header"); -} - -use std::io::Cursor; -use std::ops::Deref; -use rnex_core::kerberos::KerberosDateTime; -use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, Gathering, MatchmakeParam, MatchmakeSession, MatchmakeSessionSearchCriteria}; -use rnex_core::rmc::structures::RmcSerialize; -use rnex_core::rmc::structures::variant::Variant; - -static DUMMY: Lazy = Lazy::new(|| AutoMatchmakeParam{ - additional_participants: vec![1,2,3,4], - auto_matchmake_option: 10, - gid_for_participation_check: 9, - join_message: "hi".to_string(), - participation_count: 32, - target_gids: vec![45,2,51,1,1,1,1], - search_criteria: vec![MatchmakeSessionSearchCriteria{ - attribs: vec!["hi".to_string(), "ig".to_string(), "gotta put data here".to_string()], - exclude_locked: true, - exclude_non_host_pid: false, - exclude_system_password_set: true, - exclude_user_password_set: false, - game_mode: "some gamemode".to_string(), - matchmake_param: MatchmakeParam{ - params: vec![ - ("SR".to_string(), Variant::Bool(true)), - ("SR2".to_string(), Variant::Double(1.0)), - ("SR3".to_string(), Variant::SInt64(42)), - ("SR4".to_string(), Variant::String("test".to_string())) - ] - }, - matchmake_system_type: "some type".to_string(), - maximum_participants: "???".to_string(), - minimum_participants: "-99".to_string(), - refer_gid: 123, - selection_method: 9999999, - vacant_only: true, - vacant_participants: 1000 - }], - matchmake_session: MatchmakeSession{ - refer_gid: 10, - matchmake_system_type: 139, - matchmake_param: MatchmakeParam{ - params: vec![ - ("QSR".to_string(), Variant::Bool(false)), - ("SRQ2".to_string(), Variant::Double(1.1)), - ("SQR3".to_string(), Variant::SInt64(422)), - ("SDR4".to_string(), Variant::String("tetst".to_string())) - ] - }, - participation_count: 99, - application_buffer: vec![1,2,3,4,5,6,7,8,9], - attributes: vec![10,20,99,100000], - datetime: KerberosDateTime::now(), - gamemode: 111, - open_participation: false, - option0: 100, - progress_score: 1, - system_password_enabled: false, - user_password: "aaa".to_string(), - session_key: vec![91,123,5,2,1,2,4,124,4], - user_password_enabled: false, - gathering: Gathering{ - minimum_participants: 1, - maximum_participants: 12, - description: "aaargh".to_string(), - flags: 100, - host_pid: 999999919, - owner_pid: 138830, - participant_policy: 1, - policy_argument: 99837, - self_gid: 129, - state: 1389488 - } - } -}); - -static DUMMY_SER: Lazy> = Lazy::new(|| serialize_to_vec(DUMMY.deref())); - -fn serialize_to_vec(r: &impl RmcSerialize) -> Vec{ - let vec = r.to_data(); - - vec.unwrap() -} - -fn read_struct(r: &[u8]) -> T{ - T::deserialize(&mut Cursor::new(r)).unwrap() -} - -fn main(){ - for _ in 0..10000000 { - let v = serialize_to_vec(black_box(DUMMY.deref())); - let u = read_struct::(black_box(DUMMY_SER.deref().as_slice())); - black_box(v); - black_box(u); - } -} \ No newline at end of file diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 0a18f74..8ab6105 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -1,12 +1,12 @@ -use crate::nex::user::User; -use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; use log::info; use rand::random; use rnex_core::PID; use rnex_core::kerberos::KerberosDateTime; +use rnex_core::nex::user::User; use rnex_core::rmc::protocols::notifications::notification_types::{ HOST_CHANGED, OWNERSHIP_CHANGED, }; +use rnex_core::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::response::ErrorCode::{Core_InvalidArgument, RendezVous_SessionVoid}; use rnex_core::rmc::structures::matchmake::gathering_flags::PERSISTENT_GATHERING; @@ -155,28 +155,47 @@ impl ExtendedMatchmakeSession { return Default::default(); }; - let mm_session = MatchmakeSession { - gathering: Gathering { - self_gid: gid, - owner_pid: host.pid, - host_pid: host.pid, - ..session.gathering.clone() - }, - datetime: KerberosDateTime::now(), - session_key: (0..32).map(|_| random()).collect(), - matchmake_param: MatchmakeParam { - params: vec![ - ("@SR".to_owned(), Variant::Bool(true)), - ("@GIR".to_owned(), Variant::SInt64(3)), - ], - }, - system_password_enabled: false, - ..session - }; + cfg_if::cfg_if! { + if #[cfg(feature = "v3-5-0")]{ + let mm_session = MatchmakeSession { + gathering: Gathering { + self_gid: gid, + owner_pid: host.pid, + host_pid: host.pid, + ..session.gathering.clone() + }, + datetime: KerberosDateTime::now(), + session_key: (0..32).map(|_| random()).collect(), + matchmake_param: MatchmakeParam { + params: vec![ + ("@SR".to_owned(), Variant::Bool(true)), + ("@GIR".to_owned(), Variant::SInt64(3)), + ], + }, + system_password_enabled: false, + ..session + }; - Self { - session: mm_session, - connected_players: Default::default(), + return Self { + session: mm_session, + connected_players: Default::default(), + } + } else { + let mm_session = MatchmakeSession { + gathering: Gathering { + self_gid: gid, + owner_pid: host.pid, + host_pid: host.pid, + ..session.gathering.clone() + }, + session_key: (0..32).map(|_| random()).collect(), + ..session + }; + return Self { + session: mm_session, + connected_players: Default::default(), + } + } } } @@ -212,6 +231,7 @@ impl ExtendedMatchmakeSession { param_1: self.session.gathering.self_gid as PID, param_2: other_pid, str_param: "".into(), + #[cfg(feature = "v3-5-0")] param_3: 0, }) .await; @@ -244,6 +264,7 @@ impl ExtendedMatchmakeSession { param_1: self.session.gathering.self_gid as PID, param_2: *pid, str_param: join_msg.clone(), + #[cfg(feature = "v3-5-0")] param_3: self.connected_players.len() as _, }) .await; @@ -266,6 +287,7 @@ impl ExtendedMatchmakeSession { param_1: self.session.gathering.self_gid as PID, param_2: new_conn_pid, str_param: join_msg.clone(), + #[cfg(feature = "v3-5-0")] param_3: self.connected_players.len() as _, }) .await; @@ -318,15 +340,19 @@ impl ExtendedMatchmakeSession { } } - if search_criteria.exclude_system_password_set { - if self.session.system_password_enabled { - return Ok(false); - } - } + cfg_if::cfg_if! { + if #[cfg(feature = "v3-5-0")]{ + if search_criteria.exclude_system_password_set { + if self.session.system_password_enabled { + return Ok(false); + } + } - if search_criteria.exclude_user_password_set { - if self.session.user_password_enabled { - return Ok(false); + if search_criteria.exclude_user_password_set { + if self.session.user_password_enabled { + return Ok(false); + } + } } } diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index e8a50fa..71ffe34 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -1,26 +1,29 @@ -use crate::define_rmc_proto; -use crate::nex::common::get_station_urls; -use crate::nex::matchmake::{ExtendedMatchmakeSession, MatchmakeManager}; -use crate::nex::remote_console::RemoteConsole; -use crate::rmc::protocols::matchmake::{ - Matchmake, RawMatchmake, RawMatchmakeInfo, RemoteMatchmake, -}; -use crate::rmc::protocols::nat_traversal::{ - NatTraversal, RawNatTraversal, RawNatTraversalInfo, RemoteNatTraversal, - RemoteNatTraversalConsole, -}; use rnex_core::PID; +use rnex_core::define_rmc_proto; use rnex_core::kerberos::KerberosDateTime; +use rnex_core::nex::common::get_station_urls; +use rnex_core::nex::matchmake::{ExtendedMatchmakeSession, MatchmakeManager}; +use rnex_core::nex::remote_console::RemoteConsole; use rnex_core::prudp::station_url::StationUrl; use rnex_core::prudp::station_url::UrlOptions::{ Address, NatFiltering, NatMapping, Port, RVConnectionID, }; +use rnex_core::rmc::protocols::matchmake::{ + Matchmake, RawMatchmake, RawMatchmakeInfo, RemoteMatchmake, +}; use rnex_core::rmc::protocols::matchmake_ext::{ MatchmakeExt, RawMatchmakeExt, RawMatchmakeExtInfo, RemoteMatchmakeExt, }; use rnex_core::rmc::protocols::matchmake_extension::{ MatchmakeExtension, RawMatchmakeExtension, RawMatchmakeExtensionInfo, RemoteMatchmakeExtension, }; +use rnex_core::rmc::protocols::nat_traversal::{ + NatTraversal, RawNatTraversal, RawNatTraversalInfo, RemoteNatTraversal, + RemoteNatTraversalConsole, +}; +use rnex_core::rmc::protocols::notifications::notification_types::{ + END_GATHERING, REQUEST_JOIN_GATHERING, +}; use rnex_core::rmc::protocols::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking}; use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; use rnex_core::rmc::response::ErrorCode; @@ -32,11 +35,13 @@ use serde::{Deserialize, Serialize}; use std::env; use std::str::FromStr; -use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; use cfg_if::cfg_if; use log::{error, info}; use macros::rmc_struct; use rnex_core::prudp::socket_addr::PRUDPSockAddr; +use rnex_core::rmc::protocols::notifications::{ + self, Notification, NotificationEvent, RemoteNotification, +}; use rnex_core::rmc::protocols::ranking::{ CompetitionRankingGetParam, CompetitionRankingScoreData, CompetitionRankingScoreInfo, }; @@ -248,6 +253,8 @@ impl MatchmakeExtension for User { .await?; let mut session = session.lock().await; + + #[cfg(feature = "v3-5-0")] if join_session_param.user_password != session.session.user_password { return Err(ErrorCode::RendezVous_InvalidPassword); } @@ -396,6 +403,101 @@ impl MatchmakeExtension for User { Ok(()) } + + async fn create_matchmake_session( + &self, + gathering: Any, + message: String, + ) -> Result<(u32, Vec), ErrorCode> { + let Some(Ok(session)): Option> = gathering.try_get() else { + return Err(ErrorCode::Core_InvalidArgument); + }; + + let session = self + .create_matchmake_session_with_param(CreateMatchmakeSessionParam { + matchmake_session: session, + additional_participants: vec![], + gid_for_participation_check: 0, + create_matchmake_session_option: 0, + join_message: message, + participation_count: 1, + }) + .await?; + + Ok((session.gathering.self_gid, session.session_key)) + } + + async fn get_friend_notification_data( + &self, + ty: i32, + ) -> Result, ErrorCode> { + Ok(vec![]) + } + async fn update_notification_data( + &self, + ty: u32, + param_1: u32, + param_2: u32, + str_param: String, + ) -> Result<(), ErrorCode> { + let recpipent = param_2; + let Some(user) = self + .matchmake_manager + .users + .read() + .await + .get(&recpipent) + .and_then(|v| v.upgrade()) + else { + return Err(ErrorCode::Core_InvalidArgument); + }; + match ty { + REQUEST_JOIN_GATHERING => { + user.remote + .process_notification_event(NotificationEvent { + pid_source: self.pid, + notif_type: REQUEST_JOIN_GATHERING * 1000, + param_1, + param_2, + #[cfg(feature = "v3-5-0")] + param_3: 0, + str_param, + }) + .await; + } + END_GATHERING => { + user.remote + .process_notification_event(NotificationEvent { + pid_source: self.pid, + notif_type: END_GATHERING * 1000, + param_1, + param_2, + #[cfg(feature = "v3-5-0")] + param_3: 0, + str_param, + }) + .await; + } + _ => { + return Err(ErrorCode::Core_InvalidArgument); + } + } + Ok(()) + } + + async fn join_matchmake_session_ex( + &self, + gid: u32, + message: String, + dont_care_block_list: bool, + participation_count: u16, + ) -> Result, ErrorCode> { + let sess = self.matchmake_manager.get_session(gid).await?; + let mut sess = sess.lock().await; + sess.add_players(&[self.this.clone()], message).await; + + Ok(sess.session.session_key.clone()) + } } impl Matchmake for User { @@ -448,6 +550,7 @@ impl Matchmake for User { pid_source: self.pid, param_1: gid as PID, param_2: self.pid, + #[cfg(feature = "v3-5-0")] param_3: 0, str_param: "".to_string(), }) @@ -469,6 +572,7 @@ impl Matchmake for User { pid_source: self.pid, param_1: gid as PID, param_2: self.pid, + #[cfg(feature = "v3-5-0")] param_3: 0, str_param: "".to_string(), }) @@ -504,6 +608,7 @@ impl Matchmake for User { pid_source: self.pid, param_1: gid as PID, param_2: *candidate as PID, + #[cfg(feature = "v3-5-0")] param_3: 0, str_param: "".to_string(), }) diff --git a/rnex-core/src/rmc/protocols/matchmake_extension.rs b/rnex-core/src/rmc/protocols/matchmake_extension.rs index fff5252..7591a48 100644 --- a/rnex-core/src/rmc/protocols/matchmake_extension.rs +++ b/rnex-core/src/rmc/protocols/matchmake_extension.rs @@ -1,17 +1,57 @@ use macros::{method_id, rmc_proto}; use rnex_core::rmc::response::ErrorCode; -use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession}; +use rnex_core::rmc::structures::matchmake::{ + AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession, +}; + +use crate::rmc::protocols::notifications::NotificationEvent; +use crate::rmc::structures::any::Any; #[rmc_proto(109)] -pub trait MatchmakeExtension{ +pub trait MatchmakeExtension { #[method_id(1)] async fn close_participation(&self, gid: u32) -> Result<(), ErrorCode>; #[method_id(2)] async fn open_participation(&self, gid: u32) -> Result<(), ErrorCode>; + #[method_id(6)] + async fn create_matchmake_session( + &self, + gathering: Any, + message: String, + ) -> Result<(u32, Vec), ErrorCode>; + + #[method_id(9)] + async fn update_notification_data( + &self, + ty: u32, + param1: u32, + param2: u32, + str_param: String, + ) -> Result<(), ErrorCode>; + + #[method_id(10)] + async fn get_friend_notification_data( + &self, + ty: i32, + ) -> Result, ErrorCode>; + + #[method_id(30)] + async fn join_matchmake_session_ex( + &self, + gid: u32, + message: String, + dont_care_block_list: bool, + participation_count: u16, + ) -> Result, ErrorCode>; #[method_id(8)] - async fn modify_current_game_attribute(&self, gid: u32, attrib_index: u32, attrib_val: u32) -> Result<(), ErrorCode>; + async fn modify_current_game_attribute( + &self, + gid: u32, + attrib_index: u32, + attrib_val: u32, + ) -> Result<(), ErrorCode>; #[method_id(16)] async fn get_playing_session(&self, pids: Vec) -> Result, ErrorCode>; @@ -19,14 +59,26 @@ pub trait MatchmakeExtension{ #[method_id(34)] async fn update_progress_score(&self, gid: u32, progress: u8) -> Result<(), ErrorCode>; #[method_id(38)] - async fn create_matchmake_session_with_param(&self, session: CreateMatchmakeSessionParam) -> Result; + async fn create_matchmake_session_with_param( + &self, + session: CreateMatchmakeSessionParam, + ) -> Result; #[method_id(39)] - async fn join_matchmake_session_with_param(&self, session: JoinMatchmakeSessionParam) -> Result; + async fn join_matchmake_session_with_param( + &self, + session: JoinMatchmakeSessionParam, + ) -> Result; #[method_id(40)] - async fn auto_matchmake_with_param_postpone(&self, session: AutoMatchmakeParam) -> Result; + async fn auto_matchmake_with_param_postpone( + &self, + session: AutoMatchmakeParam, + ) -> Result; #[method_id(41)] - async fn find_matchmake_session_by_gathering_id_detail(&self, gid: u32) -> Result; -} \ No newline at end of file + async fn find_matchmake_session_by_gathering_id_detail( + &self, + gid: u32, + ) -> Result; +} diff --git a/rnex-core/src/rmc/protocols/notifications.rs b/rnex-core/src/rmc/protocols/notifications.rs index afbebd8..a0aa508 100644 --- a/rnex-core/src/rmc/protocols/notifications.rs +++ b/rnex-core/src/rmc/protocols/notifications.rs @@ -5,8 +5,12 @@ use rnex_core::PID; pub mod notification_types { pub const OWNERSHIP_CHANGED: u32 = 4000; pub const HOST_CHANGED: u32 = 110000; + pub const REQUEST_JOIN_GATHERING: u32 = 101; + pub const END_GATHERING: u32 = 102; } +cfg_if::cfg_if! { + if #[cfg(feature = "v3-5-0")]{ #[derive(RmcSerialize, Debug, Default, Clone)] #[rmc_struct(0)] pub struct NotificationEvent { @@ -17,6 +21,18 @@ pub struct NotificationEvent { pub str_param: String, pub param_3: PID, } + } else { + #[derive(RmcSerialize, Debug, Default, Clone)] + #[rmc_struct(0)] + pub struct NotificationEvent { + pub pid_source: PID, + pub notif_type: u32, + pub param_1: PID, + pub param_2: PID, + pub str_param: String, + } + } +} #[rmc_proto(14, NoReturn)] pub trait Notification { diff --git a/rnex-core/src/rmc/structures/matchmake.rs b/rnex-core/src/rmc/structures/matchmake.rs index a1518d1..ffe4d7f 100644 --- a/rnex-core/src/rmc/structures/matchmake.rs +++ b/rnex-core/src/rmc/structures/matchmake.rs @@ -1,3 +1,4 @@ +use cfg_if::cfg_if; use macros::RmcSerialize; use rnex_core::kerberos::KerberosDateTime; use rnex_core::rmc::structures::variant::Variant; @@ -27,29 +28,49 @@ pub struct MatchmakeParam { pub params: Vec<(String, Variant)>, } -// rmc structure -#[derive(RmcSerialize, Debug, Clone, Default)] -#[rmc_struct(3)] -pub struct MatchmakeSession { - //inherits from - #[extends] - pub gathering: Gathering, +cfg_if! { + if #[cfg(feature = "v3-5-0")]{ + #[derive(RmcSerialize, Debug, Clone, Default)] + #[rmc_struct(3)] + pub struct MatchmakeSession { + //inherits from + #[extends] + pub gathering: Gathering, - pub gamemode: u32, - pub attributes: Vec, - pub open_participation: bool, - pub matchmake_system_type: u32, - pub application_buffer: Vec, - pub participation_count: u32, - pub progress_score: u8, - pub session_key: Vec, - pub option0: u32, - pub matchmake_param: MatchmakeParam, - pub datetime: KerberosDateTime, - pub user_password: String, - pub refer_gid: u32, - pub user_password_enabled: bool, - pub system_password_enabled: bool, + pub gamemode: u32, + pub attributes: Vec, + pub open_participation: bool, + pub matchmake_system_type: u32, + pub application_buffer: Vec, + pub participation_count: u32, + pub progress_score: u8, + pub session_key: Vec, + pub option0: u32, + pub matchmake_param: MatchmakeParam, + pub datetime: KerberosDateTime, + pub user_password: String, + pub refer_gid: u32, + pub user_password_enabled: bool, + pub system_password_enabled: bool, + } + } else { + #[derive(RmcSerialize, Debug, Clone, Default)] + #[rmc_struct(0)] + pub struct MatchmakeSession { + //inherits from + #[extends] + pub gathering: Gathering, + + pub gamemode: u32, + pub attributes: Vec, + pub open_participation: bool, + pub matchmake_system_type: u32, + pub application_buffer: Vec, + pub participation_count: u32, + pub progress_score: u8, + pub session_key: Vec, + } + } } #[derive(RmcSerialize, Debug, Clone)] From e63ad228c1d69d689d350c05d0569e66297a5da3 Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 28 Apr 2026 00:25:50 +0200 Subject: [PATCH 160/203] logging --- rnex-core/src/nex/user.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 71ffe34..b493872 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -451,6 +451,7 @@ impl MatchmakeExtension for User { else { return Err(ErrorCode::Core_InvalidArgument); }; + println!("notif update ty: {}"); match ty { REQUEST_JOIN_GATHERING => { user.remote From c53df3176aff070c36c1c14ee40a842172e9427a Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 28 Apr 2026 00:27:19 +0200 Subject: [PATCH 161/203] logging --- rnex-core/src/nex/user.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index b493872..d7851b6 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -451,7 +451,7 @@ impl MatchmakeExtension for User { else { return Err(ErrorCode::Core_InvalidArgument); }; - println!("notif update ty: {}"); + println!("notif update ty: {}", ty); match ty { REQUEST_JOIN_GATHERING => { user.remote From b467dca52801fff76fa1507ff22f48b19f44c005 Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 28 Apr 2026 00:37:54 +0200 Subject: [PATCH 162/203] different logging --- rnex-core/src/nex/user.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index d7851b6..c1375a3 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -441,6 +441,7 @@ impl MatchmakeExtension for User { str_param: String, ) -> Result<(), ErrorCode> { let recpipent = param_2; + println!("attempt to reach: {}", recpipent); let Some(user) = self .matchmake_manager .users @@ -451,7 +452,6 @@ impl MatchmakeExtension for User { else { return Err(ErrorCode::Core_InvalidArgument); }; - println!("notif update ty: {}", ty); match ty { REQUEST_JOIN_GATHERING => { user.remote From 2cbac0b1e584a3e82cbebf72fb4ab20f5d070e82 Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 28 Apr 2026 00:47:50 +0200 Subject: [PATCH 163/203] hopefully fix things --- rnex-core/src/executables/regular_backend.rs | 1 + rnex-core/src/nex/matchmake.rs | 1 + rnex-core/src/nex/user.rs | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/rnex-core/src/executables/regular_backend.rs b/rnex-core/src/executables/regular_backend.rs index 65cb2ca..7f62864 100644 --- a/rnex-core/src/executables/regular_backend.rs +++ b/rnex-core/src/executables/regular_backend.rs @@ -11,6 +11,7 @@ pub async fn start_regular_backend() { //gid_counter: AtomicU32::new(1), sessions: Default::default(), users: Default::default(), + users_by_pid: Default::default(), rv_cid_counter: AtomicU32::new(1), }); diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 8ab6105..cd172ee 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -28,6 +28,7 @@ pub struct MatchmakeManager { pub sessions: RwLock>>>, pub rv_cid_counter: AtomicU32, pub users: RwLock>>, + pub users_by_pid: RwLock>>, } impl MatchmakeManager { diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index c1375a3..781ca7b 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -102,6 +102,9 @@ impl Secure for User { let mut users = self.matchmake_manager.users.write().await; users.insert(cid, self.this.clone()); drop(users); + let mut users = self.matchmake_manager.users_by_pid.write().await; + users.insert(self.pid, self.this.clone()); + drop(users); let stations = get_station_urls(&station_urls, self.ip, self.pid, cid).await?; @@ -444,7 +447,7 @@ impl MatchmakeExtension for User { println!("attempt to reach: {}", recpipent); let Some(user) = self .matchmake_manager - .users + .users_by_pid .read() .await .get(&recpipent) From 8b53d0f65062404f77ea642f6df260bd9e574fc3 Mon Sep 17 00:00:00 2001 From: Maple Date: Tue, 28 Apr 2026 00:52:44 +0200 Subject: [PATCH 164/203] swap logging arround again --- rnex-core/src/nex/user.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 781ca7b..995d40d 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -444,7 +444,6 @@ impl MatchmakeExtension for User { str_param: String, ) -> Result<(), ErrorCode> { let recpipent = param_2; - println!("attempt to reach: {}", recpipent); let Some(user) = self .matchmake_manager .users_by_pid @@ -455,6 +454,7 @@ impl MatchmakeExtension for User { else { return Err(ErrorCode::Core_InvalidArgument); }; + println!("notif ty : {}", ty); match ty { REQUEST_JOIN_GATHERING => { user.remote From d715fe27e4a01b92867e82efdaa35090eea70213 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 28 Apr 2026 09:39:05 +0200 Subject: [PATCH 165/203] add preference updating --- .vscode/settings.json | 5 +++++ rnex-core/src/nex/friends_handler.rs | 20 ++++++++++++++++++++ rnex-core/src/rmc/protocols/friends.rs | 4 +++- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..908e9e4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "rust-analyzer.cargo.features": [ + "friends" + ] +} \ No newline at end of file diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 897ff38..3af6ff6 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -320,6 +320,26 @@ impl Friends for FriendsUser { async fn check_setting_status(&self) -> Result { Ok(0xFF) } + + async fn update_preference(&self, preference: PrincipalPreference) -> Result<(),ErrorCode> { + info!("user updated preference: {:?}", preference); + let any_presence: Any = Any::new(&preference).expect("out of memory"); + + let users = self.fm.users.read().await; + for u in users.deref().iter().filter_map(|u| u.upgrade()) { + info!("sending preference update"); + u.remote + .process_nintendo_notification_event_2(NintendoNotificationEvent { + event_type: 23, + sender: self.pid, + data: any_presence.clone(), + }) + .await; + } + drop(users); + + Ok(()) + } } type HMacMd5 = hmac::Hmac; diff --git a/rnex-core/src/rmc/protocols/friends.rs b/rnex-core/src/rmc/protocols/friends.rs index 98fa501..d25ea9e 100644 --- a/rnex-core/src/rmc/protocols/friends.rs +++ b/rnex-core/src/rmc/protocols/friends.rs @@ -67,7 +67,7 @@ pub struct NintendoPresenceV2 { pub unk6: u8, pub unk7: u8, } -#[derive(RmcSerialize)] +#[derive(RmcSerialize, Clone, Debug)] #[rmc_struct(0)] pub struct PrincipalPreference { #[extends] @@ -171,6 +171,8 @@ pub trait Friends { >; #[method_id(13)] async fn update_presence(&self, presence: NintendoPresenceV2) -> Result<(), ErrorCode>; + #[method_id(16)] + async fn update_preference(&self, preference: PrincipalPreference) -> Result<(), ErrorCode>; #[method_id(18)] async fn delete_persistent_notification( &self, From b2693d0eea15a5ab2827c815842c631e30ce3f0a Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 28 Apr 2026 10:12:14 +0200 Subject: [PATCH 166/203] Better CI --- .ci-scripts/make-edition.sh | 25 +++++++++++++------------ .dockerignore | 4 +++- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh index cb4a879..e96d7e6 100755 --- a/.ci-scripts/make-edition.sh +++ b/.ci-scripts/make-edition.sh @@ -2,16 +2,17 @@ export EDITION=$1 export BA="--network=host --build-arg EDITION=$1 --build-arg DATABASE_URL="$DATABASE_URL"" +: "${RNEX_CONTAINER_PLATFORM:=podman}" -# podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . -# podman push "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" -podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" --target=node-holder . -podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" --target=proxy-secure . -podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" --target=proxy-insecure . -podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" --target=backend-auth . -podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" --target=backend-secure . -podman push "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" -podman push "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" -podman push "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" -podman push "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" -podman push "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" +# $RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . +# $RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" +$RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" --target=node-holder . +$RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" --target=proxy-secure . +$RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" --target=proxy-insecure . +$RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" --target=backend-auth . +$RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" --target=backend-secure . +$RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" +$RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" +$RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" +$RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" +$RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" diff --git a/.dockerignore b/.dockerignore index 4e09ffe..ab0f8c4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,4 +7,6 @@ CONTRIBUTING.md README.md .gitignore LICENSE -.devcontainer.json \ No newline at end of file +.devcontainer.json +.ci-scripts/make-edition.sh +.forgejo/workflows/build.yml \ No newline at end of file From 4136a768030ef7eb033e74701775c15c1032ad4f Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 28 Apr 2026 10:14:04 +0200 Subject: [PATCH 167/203] Fix CI script --- .ci-scripts/make-edition.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh index e96d7e6..b8c6776 100755 --- a/.ci-scripts/make-edition.sh +++ b/.ci-scripts/make-edition.sh @@ -2,6 +2,7 @@ export EDITION=$1 export BA="--network=host --build-arg EDITION=$1 --build-arg DATABASE_URL="$DATABASE_URL"" +source /etc/environment : "${RNEX_CONTAINER_PLATFORM:=podman}" # $RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . From 678ec565a55b4d37dd62ce539dc81ecf736e5b8f Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 28 Apr 2026 10:31:56 +0200 Subject: [PATCH 168/203] basic buildkit output --- .ci-scripts/make-edition.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh index b8c6776..d03e2f1 100755 --- a/.ci-scripts/make-edition.sh +++ b/.ci-scripts/make-edition.sh @@ -4,6 +4,7 @@ export EDITION=$1 export BA="--network=host --build-arg EDITION=$1 --build-arg DATABASE_URL="$DATABASE_URL"" source /etc/environment : "${RNEX_CONTAINER_PLATFORM:=podman}" +export BUILDKIT_PROGRESS=plain # $RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . # $RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" From 65c364243958ac387c31f15a5818cbfe3939e861 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 11:20:25 +0200 Subject: [PATCH 169/203] enable third notification param on wiiu chat --- editions.yaml | 1 + rnex-core/Cargo.toml | 6 ++++-- rnex-core/src/nex/matchmake.rs | 6 +++--- rnex-core/src/nex/user.rs | 10 ++++----- rnex-core/src/rmc/protocols/notifications.rs | 22 ++++++++++---------- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/editions.yaml b/editions.yaml index b1ae006..ecd0513 100644 --- a/editions.yaml +++ b/editions.yaml @@ -2,6 +2,7 @@ wii-u-chat: include-in-checkall: true features: - prudpv1 + - third-notif-param - v3-3-2 settings: AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 6617a92..66b9f79 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -44,8 +44,10 @@ guest_login = [] friends = ["guest_login", "database-support"] big_pid = [] v3-3-2 = [] -v3-5-0 = ["v3-3-2"] -v3-8-15 = ["rmc_struct_header", "v3-5-0"] +third-notif-param = [] +v3-4-0 = ["v3-3-2", "third-notif-param", "rmc_struct_header"] +v3-5-0 = ["v3-4-0"] +v3-8-15 = ["v3-5-0"] v4-3-11 = ["v3-8-15"] nx = ["big_pid"] datastore = ["database-support", "v3-8-15", "dep:aws-sdk-s3", "dep:aws-config"] diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index cd172ee..fd6632e 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -232,7 +232,7 @@ impl ExtendedMatchmakeSession { param_1: self.session.gathering.self_gid as PID, param_2: other_pid, str_param: "".into(), - #[cfg(feature = "v3-5-0")] + #[cfg(feature = "third-notif-param")] param_3: 0, }) .await; @@ -265,7 +265,7 @@ impl ExtendedMatchmakeSession { param_1: self.session.gathering.self_gid as PID, param_2: *pid, str_param: join_msg.clone(), - #[cfg(feature = "v3-5-0")] + #[cfg(feature = "third-notif-param")] param_3: self.connected_players.len() as _, }) .await; @@ -288,7 +288,7 @@ impl ExtendedMatchmakeSession { param_1: self.session.gathering.self_gid as PID, param_2: new_conn_pid, str_param: join_msg.clone(), - #[cfg(feature = "v3-5-0")] + #[cfg(feature = "third-notif-param")] param_3: self.connected_players.len() as _, }) .await; diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 995d40d..2f87397 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -463,7 +463,7 @@ impl MatchmakeExtension for User { notif_type: REQUEST_JOIN_GATHERING * 1000, param_1, param_2, - #[cfg(feature = "v3-5-0")] + #[cfg(feature = "third-notif-param")] param_3: 0, str_param, }) @@ -476,7 +476,7 @@ impl MatchmakeExtension for User { notif_type: END_GATHERING * 1000, param_1, param_2, - #[cfg(feature = "v3-5-0")] + #[cfg(feature = "third-notif-param")] param_3: 0, str_param, }) @@ -554,7 +554,7 @@ impl Matchmake for User { pid_source: self.pid, param_1: gid as PID, param_2: self.pid, - #[cfg(feature = "v3-5-0")] + #[cfg(feature = "third-notif-param")] param_3: 0, str_param: "".to_string(), }) @@ -576,7 +576,7 @@ impl Matchmake for User { pid_source: self.pid, param_1: gid as PID, param_2: self.pid, - #[cfg(feature = "v3-5-0")] + #[cfg(feature = "third-notif-param")] param_3: 0, str_param: "".to_string(), }) @@ -612,7 +612,7 @@ impl Matchmake for User { pid_source: self.pid, param_1: gid as PID, param_2: *candidate as PID, - #[cfg(feature = "v3-5-0")] + #[cfg(feature = "third-notif-param")] param_3: 0, str_param: "".to_string(), }) diff --git a/rnex-core/src/rmc/protocols/notifications.rs b/rnex-core/src/rmc/protocols/notifications.rs index a0aa508..e66f8fe 100644 --- a/rnex-core/src/rmc/protocols/notifications.rs +++ b/rnex-core/src/rmc/protocols/notifications.rs @@ -10,17 +10,17 @@ pub mod notification_types { } cfg_if::cfg_if! { - if #[cfg(feature = "v3-5-0")]{ -#[derive(RmcSerialize, Debug, Default, Clone)] -#[rmc_struct(0)] -pub struct NotificationEvent { - pub pid_source: PID, - pub notif_type: u32, - pub param_1: PID, - pub param_2: PID, - pub str_param: String, - pub param_3: PID, -} + if #[cfg(feature = "third-notif-param")]{ + #[derive(RmcSerialize, Debug, Default, Clone)] + #[rmc_struct(0)] + pub struct NotificationEvent { + pub pid_source: PID, + pub notif_type: u32, + pub param_1: PID, + pub param_2: PID, + pub str_param: String, + pub param_3: PID, + } } else { #[derive(RmcSerialize, Debug, Default, Clone)] #[rmc_struct(0)] From cbd175229e23eef360da67fa47f83a6617cc8342 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 11:31:43 +0200 Subject: [PATCH 170/203] add logging if an error occurrs in method --- rnex-core/src/rmc/response.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/rnex-core/src/rmc/response.rs b/rnex-core/src/rmc/response.rs index b042877..d401892 100644 --- a/rnex-core/src/rmc/response.rs +++ b/rnex-core/src/rmc/response.rs @@ -6,7 +6,7 @@ use crate::rmc::response::ErrorCode::Core_Exception; use crate::rmc::structures::qresult::ERROR_MASK; use crate::util::SendingBufferConnection; use bytemuck::bytes_of; -use log::error; +use log::{error, warn}; use std::io; use std::io::{Read, Seek, Write}; use std::mem::transmute; @@ -157,10 +157,13 @@ pub async fn send_result( method_id, data: v, }, - Err(e) => RMCResponseResult::Error { - call_id, - error_code: e.into(), - }, + Err(e) => { + warn!("error occurred during call: {:?}", e); + RMCResponseResult::Error { + call_id, + error_code: e.into(), + } + } }; let response = RMCResponse { From 6a70df89ed2e840fb3cc5c3bbe8042682338cfa6 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 11:44:12 +0200 Subject: [PATCH 171/203] debug logging --- rnex-core/Cargo.toml | 1 + rnex-core/src/nex/user.rs | 1 + rnex-core/src/rmc/protocols/mod.rs | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 66b9f79..f338fe3 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -34,6 +34,7 @@ aws-config = { version = "1.8.15", optional = true } base64 = "0.22.1" sha2 = "0.10.9" urlencoding = "2.1.3" +futures = "0.3.32" [dev-dependencies] # criterion = "0.7.0" diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 2f87397..eba80f4 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -412,6 +412,7 @@ impl MatchmakeExtension for User { gathering: Any, message: String, ) -> Result<(u32, Vec), ErrorCode> { + info!("gathering: {:?}", gathering); let Some(Ok(session)): Option> = gathering.try_get() else { return Err(ErrorCode::Core_InvalidArgument); }; diff --git a/rnex-core/src/rmc/protocols/mod.rs b/rnex-core/src/rmc/protocols/mod.rs index a34b265..391ecdf 100644 --- a/rnex-core/src/rmc/protocols/mod.rs +++ b/rnex-core/src/rmc/protocols/mod.rs @@ -2,6 +2,7 @@ pub mod account_management; pub mod auth; +pub mod datastore; pub mod friends; pub mod matchmake; pub mod matchmake_ext; @@ -11,7 +12,6 @@ pub mod nintendo_notification; pub mod notifications; pub mod ranking; pub mod secure; -pub mod datastore; use crate::result::ResultExtension; use crate::rmc::message::RMCMessage; @@ -20,6 +20,7 @@ use crate::rmc::response::{ErrorCode, RMCResponse, RMCResponseResult}; use crate::rmc::structures; use crate::rmc::structures::RmcSerialize; use crate::util::{SendingBufferConnection, SplittableBufferConnection}; +use futures::FutureExt; use log::{error, info}; use std::collections::HashMap; use std::future::Future; From 74061ef3b5ca5d429465f9bf0ea4fdf7f011a357 Mon Sep 17 00:00:00 2001 From: Spacebot Date: Tue, 28 Apr 2026 11:03:27 +0000 Subject: [PATCH 172/203] Add renovate.json --- renovate.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 renovate.json diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..7190a60 --- /dev/null +++ b/renovate.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json" +} From f48e2d232b867295b5116c6d4e74c902aa0409ac Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 13:23:26 +0200 Subject: [PATCH 173/203] change how Any is deserialized --- rnex-core/src/rmc/structures/any.rs | 59 +++++++++++++++++++++-- rnex-core/src/rmc/structures/matchmake.rs | 4 +- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/rnex-core/src/rmc/structures/any.rs b/rnex-core/src/rmc/structures/any.rs index 0f531d8..53e12d5 100644 --- a/rnex-core/src/rmc/structures/any.rs +++ b/rnex-core/src/rmc/structures/any.rs @@ -1,3 +1,4 @@ +use log::warn; use rnex_core::rmc::structures::{Result, RmcSerialize}; use std::io::{Cursor, Read, Write}; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; @@ -21,11 +22,23 @@ impl RmcSerialize for Any { fn deserialize(reader: &mut impl Read) -> Result { let name = String::deserialize(reader)?; - // also length ? - let _len2: u32 = reader.read_struct(IS_BIG_ENDIAN)?; let data = Vec::deserialize(reader)?; + let mut cursor = Cursor::new(&data); + // also length ? + let len2: u32 = cursor.read_struct(IS_BIG_ENDIAN)?; - Ok(Any { name, data }) + if len2 as usize != data.len().overflowing_sub(4).0 { + warn!( + "mismatched sizes on any: {} vs {}", + data.len().overflowing_sub(4).0, + len2 + ); + } + + Ok(Any { + name, + data: (&data[4..]).to_owned(), + }) } } @@ -43,3 +56,43 @@ impl Any { }); } } + +#[cfg(test)] +mod test { + use crate::rmc::structures::{ + any::Any, + matchmake::{Gathering, MatchmakeSession}, + }; + + #[test] + fn test() { + let sess = MatchmakeSession { + gathering: Gathering { + self_gid: 0, + owner_pid: 0, + host_pid: 0, + minimum_participants: 2, + maximum_participants: 2, + participant_policy: 98, + policy_argument: 0, + flags: 32, + state: 0, + description: "Doors Friend Invite".into(), + }, + gamemode: 0, + attributes: [2, 3, 0, 0, 0, 0].into(), + open_participation: false, + matchmake_system_type: 2, + application_buffer: [1, 2, 3].into(), + participation_count: 0, + progress_score: 0, + session_key: [].into(), + }; + + let any = Any::new(&sess).unwrap(); + + let sess2: MatchmakeSession = any.try_get().unwrap().unwrap(); + + assert_eq!(sess, sess2); + } +} diff --git a/rnex-core/src/rmc/structures/matchmake.rs b/rnex-core/src/rmc/structures/matchmake.rs index ffe4d7f..52af790 100644 --- a/rnex-core/src/rmc/structures/matchmake.rs +++ b/rnex-core/src/rmc/structures/matchmake.rs @@ -6,7 +6,7 @@ use rnex_core::rmc::structures::variant::Variant; use rnex_core::PID; // rmc structure -#[derive(RmcSerialize, Debug, Clone, Default)] +#[derive(RmcSerialize, Debug, Clone, Default, PartialEq)] #[rmc_struct(0)] pub struct Gathering { pub self_gid: u32, @@ -54,7 +54,7 @@ cfg_if! { pub system_password_enabled: bool, } } else { - #[derive(RmcSerialize, Debug, Clone, Default)] + #[derive(RmcSerialize, Debug, Clone, Default, PartialEq)] #[rmc_struct(0)] pub struct MatchmakeSession { //inherits from From 340275fd0a230ae62516baa12e573ba4d570e527 Mon Sep 17 00:00:00 2001 From: kitten Date: Tue, 28 Apr 2026 13:41:34 +0200 Subject: [PATCH 174/203] feat(deps): automerge commits that aren't major --- renovate.json | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/renovate.json b/renovate.json index 7190a60..3f918de 100644 --- a/renovate.json +++ b/renovate.json @@ -1,3 +1,14 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json" -} + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended"], + "packageRules": [ + { + "matchUpdateTypes": ["minor", "patch"], + "automerge": true + }, + { + "matchUpdateTypes": ["major"], + "automerge": false + } + ] +} \ No newline at end of file From 368bc2e45ae60c6de91d93b35e545834d8149506 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 13:37:00 +0200 Subject: [PATCH 175/203] change any again and fix not building --- Cargo.lock | 48 +++++++++++++++++++---------- rnex-core/src/rmc/structures/any.rs | 34 +++++++++++--------- 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf83871..3b10ce1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1038,10 +1038,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] -name = "futures-channel" -version = "0.3.31" +name = "futures" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -1049,15 +1064,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -1083,9 +1098,9 @@ checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", @@ -1094,22 +1109,23 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ + "futures-channel", "futures-core", "futures-io", "futures-macro", @@ -1117,7 +1133,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -2206,6 +2221,7 @@ dependencies = [ "cfg-if", "chrono", "dotenv", + "futures", "hex", "hmac", "json", diff --git a/rnex-core/src/rmc/structures/any.rs b/rnex-core/src/rmc/structures/any.rs index 53e12d5..035d425 100644 --- a/rnex-core/src/rmc/structures/any.rs +++ b/rnex-core/src/rmc/structures/any.rs @@ -12,32 +12,29 @@ pub struct Any { impl RmcSerialize for Any { fn serialize(&self, writer: &mut impl Write) -> Result<()> { self.name.serialize(writer)?; - - let u32_len = self.data.len() as u32; + let u32_len = self.data.len() as u32 - 1; (u32_len + 4).serialize(writer)?; - self.data.serialize(writer)?; + u32_len.serialize(writer)?; + writer.write_all(&self.data)?; Ok(()) } fn deserialize(reader: &mut impl Read) -> Result { let name = String::deserialize(reader)?; - let data = Vec::deserialize(reader)?; - let mut cursor = Cursor::new(&data); - // also length ? + let size = u32::deserialize(reader)? as usize + 1; + let mut buf = vec![0; size]; + reader.read_exact(&mut buf[..])?; + let mut cursor = Cursor::new(&buf); let len2: u32 = cursor.read_struct(IS_BIG_ENDIAN)?; - if len2 as usize != data.len().overflowing_sub(4).0 { - warn!( - "mismatched sizes on any: {} vs {}", - data.len().overflowing_sub(4).0, - len2 - ); + if len2 as usize + 1 != size { + warn!("mismatched sizes on any: {} vs {}", size, len2 + 1); } Ok(Any { name, - data: (&data[4..]).to_owned(), + data: (&buf[4..]).to_owned(), }) } } @@ -59,7 +56,10 @@ impl Any { #[cfg(test)] mod test { + use std::io::Cursor; + use crate::rmc::structures::{ + RmcSerialize, any::Any, matchmake::{Gathering, MatchmakeSession}, }; @@ -89,9 +89,13 @@ mod test { session_key: [].into(), }; - let any = Any::new(&sess).unwrap(); + let any = Any::new(&sess).unwrap().to_data().unwrap(); - let sess2: MatchmakeSession = any.try_get().unwrap().unwrap(); + let sess2: MatchmakeSession = Any::deserialize(&mut Cursor::new(any)) + .unwrap() + .try_get() + .unwrap() + .unwrap(); assert_eq!(sess, sess2); } From 62e68d7abb45c027b233a2ad03db46a3c96ffd69 Mon Sep 17 00:00:00 2001 From: Spacebot Date: Tue, 28 Apr 2026 12:03:12 +0000 Subject: [PATCH 176/203] Update aws-sdk-rust monorepo --- Cargo.lock | 312 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 217 insertions(+), 95 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b10ce1..66bccab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,7 +43,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -69,9 +69,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-config" -version = "1.8.15" +version = "1.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11493b0bad143270fb8ad284a096dd529ba91924c5409adeac856cc1bf047dbc" +checksum = "50f156acdd2cf55f5aa53ee416c4ac851cf1222694506c0b1f78c85695e9ca9d" dependencies = [ "aws-credential-types", "aws-runtime", @@ -89,7 +89,7 @@ dependencies = [ "fastrand", "hex", "http 1.3.1", - "sha1", + "sha1 0.10.6", "time", "tokio", "tracing", @@ -133,9 +133,9 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.7.2" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc0651c57e384202e47153c1260b84a9936e19803d747615edf199dc3b98d17" +checksum = "5dcd93c82209ac7413532388067dce79be5a8780c1786e5fae3df22e4dee2864" dependencies = [ "aws-credential-types", "aws-sigv4", @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "aws-sdk-s3" -version = "1.129.0" +version = "1.131.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d4e8410fadbc0ee453145dd77a4958227b18b05bf67c2795d0a8b8596c9aa0f" +checksum = "fe1b8c5282bf859170836045296b3cd710b7573aceb909498366bb508a41058e" dependencies = [ "aws-credential-types", "aws-runtime", @@ -182,23 +182,23 @@ dependencies = [ "bytes", "fastrand", "hex", - "hmac", + "hmac 0.13.0", "http 0.2.12", "http 1.3.1", "http-body 1.0.1", "lru", "percent-encoding", "regex-lite", - "sha2", + "sha2 0.11.0", "tracing", "url", ] [[package]] name = "aws-sdk-sso" -version = "1.97.0" +version = "1.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aadc669e184501caaa6beafb28c6267fc1baef0810fb58f9b205485ca3f2567" +checksum = "d69c77aafa20460c68b6b3213c84f6423b6e76dbf89accd3e1789a686ffd9489" dependencies = [ "aws-credential-types", "aws-runtime", @@ -220,9 +220,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.99.0" +version = "1.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1342a7db8f358d3de0aed2007a0b54e875458e39848d54cc1d46700b2bfcb0a8" +checksum = "1c7e7b09346d5ca22a2a08267555843a6a0127fb20d8964cb6ecfb8fdb190225" dependencies = [ "aws-credential-types", "aws-runtime", @@ -244,9 +244,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.101.0" +version = "1.103.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab41ad64e4051ecabeea802d6a17845a91e83287e1dd249e6963ea1ba78c428a" +checksum = "c2249b81a2e73a8027c41c378463a81ec39b8510f184f2caab87de912af0f49b" dependencies = [ "aws-credential-types", "aws-runtime", @@ -269,9 +269,9 @@ dependencies = [ [[package]] name = "aws-sigv4" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b660013a6683ab23797778e21f1f854744fdf05f68204b4cca4c8c04b5d1f4" +checksum = "68dc0b907359b120170613b5c09ccc61304eac3998ff6274b97d93ee6490115a" dependencies = [ "aws-credential-types", "aws-smithy-eventstream", @@ -282,13 +282,13 @@ dependencies = [ "crypto-bigint 0.5.5", "form_urlencoded", "hex", - "hmac", + "hmac 0.13.0", "http 0.2.12", "http 1.3.1", "p256", "percent-encoding", "ring", - "sha2", + "sha2 0.11.0", "subtle", "time", "tracing", @@ -308,9 +308,9 @@ dependencies = [ [[package]] name = "aws-smithy-checksums" -version = "0.64.6" +version = "0.64.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6750f3dd509b0694a4377f0293ed2f9630d710b1cebe281fa8bac8f099f88bc6" +checksum = "10efbbcec1e044b81600e2fc562a391951d291152d95b482d5b7e7132299d762" dependencies = [ "aws-smithy-http", "aws-smithy-types", @@ -320,10 +320,10 @@ dependencies = [ "http 1.3.1", "http-body 1.0.1", "http-body-util", - "md-5", + "md-5 0.11.0", "pin-project-lite", - "sha1", - "sha2", + "sha1 0.11.0", + "sha2 0.11.0", "tracing", ] @@ -420,9 +420,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.10.3" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028999056d2d2fd58a697232f9eec4a643cf73a71cf327690a7edad1d2af2110" +checksum = "0504b1ab12debb5959e5165ee5fe97dd387e7aa7ea6a477bfd7635dfe769a4f5" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -445,11 +445,12 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.11.6" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876ab3c9c29791ba4ba02b780a3049e21ec63dabda09268b175272c3733a79e6" +checksum = "b71a13df6ada0aafbf21a73bdfcdf9324cfa9df77d96b8446045be3cde61b42e" dependencies = [ "aws-smithy-async", + "aws-smithy-runtime-api-macros", "aws-smithy-types", "bytes", "http 0.2.12", @@ -460,6 +461,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "aws-smithy-runtime-api-macros" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d7396fd9500589e62e460e987ecb671bad374934e55ec3b5f498cc7a8a8a7b7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "aws-smithy-types" version = "1.4.7" @@ -497,9 +509,9 @@ dependencies = [ [[package]] name = "aws-types" -version = "1.3.14" +version = "1.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c8323699dd9b3c8d5b3c13051ae9cdef58fd179957c882f8374dd8725962d9" +checksum = "2f4bbcaa9304ea40902d3d5f42a0428d1bd895a2b0f6999436fb279ffddc58ac" dependencies = [ "aws-credential-types", "aws-smithy-async", @@ -555,6 +567,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + [[package]] name = "bumpalo" version = "3.19.0" @@ -578,7 +599,7 @@ checksum = "441473f2b4b0459a68628c744bc61d23e730fb00128b841d30fa4bb3972257e4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -641,7 +662,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", + "crypto-common 0.1.6", "inout", ] @@ -654,6 +675,12 @@ dependencies = [ "cc", ] +[[package]] +name = "cmov" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -669,6 +696,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "cookie" version = "0.18.1" @@ -723,6 +756,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc" version = "3.3.0" @@ -745,7 +787,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fd92aca2c6001b1bf5ba0ff84ee74ec8501b52bbef0cac80bf25a6c1d87a83d" dependencies = [ "crc", - "digest", + "digest 0.10.7", "rustversion", "spin 0.10.0", ] @@ -806,6 +848,24 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + [[package]] name = "data-encoding" version = "2.10.0" @@ -818,7 +878,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ - "const-oid", + "const-oid 0.9.6", "zeroize", ] @@ -828,7 +888,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "const-oid", + "const-oid 0.9.6", "pem-rfc7468", "zeroize", ] @@ -848,12 +908,24 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", + "block-buffer 0.10.4", + "const-oid 0.9.6", + "crypto-common 0.1.6", "subtle", ] +[[package]] +name = "digest" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +dependencies = [ + "block-buffer 0.12.0", + "const-oid 0.10.2", + "crypto-common 0.2.1", + "ctutils", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -862,7 +934,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -922,7 +994,7 @@ dependencies = [ "base16ct", "crypto-bigint 0.4.9", "der 0.6.1", - "digest", + "digest 0.10.7", "ff", "generic-array", "group", @@ -1104,7 +1176,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -1267,7 +1339,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac", + "hmac 0.12.1", ] [[package]] @@ -1276,7 +1348,16 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", +] + +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.2", ] [[package]] @@ -1356,6 +1437,15 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hybrid-array" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "0.14.32" @@ -1724,7 +1814,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -1744,7 +1834,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ "cfg-if", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "md-5" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" +dependencies = [ + "cfg-if", + "digest 0.11.2", ] [[package]] @@ -1861,7 +1961,7 @@ checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ "ecdsa", "elliptic-curve", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -1995,9 +2095,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -2047,9 +2147,9 @@ version = "0.1.0" dependencies = [ "bytemuck", "cfg-if", - "hmac", + "hmac 0.12.1", "log", - "md-5", + "md-5 0.10.6", "proxy-common", "rc4", "rnex-core", @@ -2064,9 +2164,9 @@ dependencies = [ "async-trait", "bytemuck", "cfg-if", - "hmac", + "hmac 0.12.1", "log", - "md-5", + "md-5 0.10.6", "once_cell", "proxy-common", "rc4", @@ -2079,9 +2179,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -2191,7 +2291,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint 0.4.9", - "hmac", + "hmac 0.12.1", "zeroize", ] @@ -2223,18 +2323,18 @@ dependencies = [ "dotenv", "futures", "hex", - "hmac", + "hmac 0.12.1", "json", "log", "macros 0.0.0", - "md-5", + "md-5 0.10.6", "once_cell", "paste", "rand 0.8.5", "rc4", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "simplelog", "sqlx", "thiserror", @@ -2251,8 +2351,8 @@ version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ - "const-oid", - "digest", + "const-oid 0.9.6", + "digest 0.10.7", "num-bigint-dig", "num-integer", "num-traits", @@ -2452,7 +2552,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -2487,8 +2587,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha1" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.2", ] [[package]] @@ -2498,8 +2609,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.2", ] [[package]] @@ -2523,7 +2645,7 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -2533,7 +2655,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -2663,7 +2785,7 @@ dependencies = [ "percent-encoding", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "thiserror", "time", @@ -2683,7 +2805,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -2701,12 +2823,12 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "sqlx-core", "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.104", + "syn 2.0.117", "tokio", "url", ] @@ -2724,7 +2846,7 @@ dependencies = [ "bytes", "chrono", "crc", - "digest", + "digest 0.10.7", "dotenvy", "either", "futures-channel", @@ -2734,18 +2856,18 @@ dependencies = [ "generic-array", "hex", "hkdf", - "hmac", + "hmac 0.12.1", "itoa", "log", - "md-5", + "md-5 0.10.6", "memchr", "once_cell", "percent-encoding", "rand 0.8.5", "rsa", "serde", - "sha1", - "sha2", + "sha1 0.10.6", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -2774,17 +2896,17 @@ dependencies = [ "futures-util", "hex", "hkdf", - "hmac", + "hmac 0.12.1", "home", "itoa", "log", - "md-5", + "md-5 0.10.6", "memchr", "once_cell", "rand 0.8.5", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -2856,9 +2978,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.104" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -2873,7 +2995,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -2902,7 +3024,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -2988,7 +3110,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -3093,7 +3215,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -3125,7 +3247,7 @@ dependencies = [ "rand 0.9.2", "rustls 0.23.31", "rustls-pki-types", - "sha1", + "sha1 0.10.6", "thiserror", "utf-8", ] @@ -3319,7 +3441,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", "wasm-bindgen-shared", ] @@ -3341,7 +3463,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3404,7 +3526,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -3415,7 +3537,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -3642,7 +3764,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", "synstructure", ] @@ -3663,7 +3785,7 @@ checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] @@ -3683,7 +3805,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", "synstructure", ] @@ -3723,7 +3845,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.117", ] [[package]] From 225b28aa84dd19b391cee6eb9ba1b7bb81a2ed1d Mon Sep 17 00:00:00 2001 From: Spacebot Date: Tue, 28 Apr 2026 12:03:16 +0000 Subject: [PATCH 177/203] Update Rust crate anyhow to v1.0.102 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b10ce1..7467df9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,9 +31,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "async-trait" From 92ba5b1a750f51a38e08331300b7b4b29a50e267 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 14:52:19 +0200 Subject: [PATCH 178/203] add logging --- rnex-core/src/nex/auth_handler.rs | 2 +- rnex-core/src/rmc/structures/any.rs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index 97b1008..a5ffe2b 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -129,7 +129,7 @@ impl AuthHandler { }; let Ok(passwd) = client.get_nex_password(pid).await else { - warn!("unable to get nex password"); + warn!("unable to get nex password for pid: {}:", pid); return Err(ErrorCode::Core_Exception); }; diff --git a/rnex-core/src/rmc/structures/any.rs b/rnex-core/src/rmc/structures/any.rs index 035d425..8f4b569 100644 --- a/rnex-core/src/rmc/structures/any.rs +++ b/rnex-core/src/rmc/structures/any.rs @@ -1,4 +1,4 @@ -use log::warn; +use log::{info, warn}; use rnex_core::rmc::structures::{Result, RmcSerialize}; use std::io::{Cursor, Read, Write}; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; @@ -28,10 +28,12 @@ impl RmcSerialize for Any { let mut cursor = Cursor::new(&buf); let len2: u32 = cursor.read_struct(IS_BIG_ENDIAN)?; - if len2 as usize + 1 != size { + if len2 as usize + 3 != size { warn!("mismatched sizes on any: {} vs {}", size, len2 + 1); } + info!("any data: {}", hex::encode(&buf)); + Ok(Any { name, data: (&buf[4..]).to_owned(), From 48ace5124b418cf1a0832be37431192669466499 Mon Sep 17 00:00:00 2001 From: Spacebot Date: Tue, 28 Apr 2026 13:04:07 +0000 Subject: [PATCH 179/203] Update Rust crate chrono to v0.4.44 --- Cargo.lock | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d2b542a..e666c9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,12 +14,6 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -644,16 +638,15 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-link 0.1.3", + "windows-link 0.2.1", ] [[package]] From 747e37409facc1f5cb8ddb47383a1ea5928acdbe Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 15:07:33 +0200 Subject: [PATCH 180/203] fix issues --- rnex-core/src/nex/user.rs | 9 ++-- rnex-core/src/rmc/structures/any.rs | 54 +++++++++++------------ rnex-core/src/rmc/structures/matchmake.rs | 1 - 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index eba80f4..7b56fdf 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -180,11 +180,14 @@ impl MatchmakeExtension for User { } async fn update_progress_score(&self, gid: u32, progress: u8) -> Result<(), ErrorCode> { - let session = self.matchmake_manager.get_session(gid).await?; + #[cfg(feature = "v3-5-0")] + { + let session = self.matchmake_manager.get_session(gid).await?; - let mut session = session.lock().await; + let mut session = session.lock().await; - session.session.progress_score = progress; + session.session.progress_score = progress; + } Ok(()) } diff --git a/rnex-core/src/rmc/structures/any.rs b/rnex-core/src/rmc/structures/any.rs index 8f4b569..98feb86 100644 --- a/rnex-core/src/rmc/structures/any.rs +++ b/rnex-core/src/rmc/structures/any.rs @@ -1,4 +1,3 @@ -use log::{info, warn}; use rnex_core::rmc::structures::{Result, RmcSerialize}; use std::io::{Cursor, Read, Write}; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; @@ -12,32 +11,21 @@ pub struct Any { impl RmcSerialize for Any { fn serialize(&self, writer: &mut impl Write) -> Result<()> { self.name.serialize(writer)?; - let u32_len = self.data.len() as u32 - 1; + + let u32_len = self.data.len() as u32; (u32_len + 4).serialize(writer)?; - u32_len.serialize(writer)?; - writer.write_all(&self.data)?; + self.data.serialize(writer)?; Ok(()) } fn deserialize(reader: &mut impl Read) -> Result { let name = String::deserialize(reader)?; - let size = u32::deserialize(reader)? as usize + 1; - let mut buf = vec![0; size]; - reader.read_exact(&mut buf[..])?; - let mut cursor = Cursor::new(&buf); - let len2: u32 = cursor.read_struct(IS_BIG_ENDIAN)?; + // also length ? + let _len2: u32 = reader.read_struct(IS_BIG_ENDIAN)?; + let data = Vec::deserialize(reader)?; - if len2 as usize + 3 != size { - warn!("mismatched sizes on any: {} vs {}", size, len2 + 1); - } - - info!("any data: {}", hex::encode(&buf)); - - Ok(Any { - name, - data: (&buf[4..]).to_owned(), - }) + Ok(Any { name, data }) } } @@ -58,8 +46,6 @@ impl Any { #[cfg(test)] mod test { - use std::io::Cursor; - use crate::rmc::structures::{ RmcSerialize, any::Any, @@ -68,6 +54,21 @@ mod test { #[test] fn test() { + let any = Any { + name: "MatchmakeSession".into(), + data: [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 98, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 0, 0, 0, 0, 0, 20, 0, 68, 111, 111, 114, 115, 32, 70, 114, 105, 101, 110, 100, 32, + 73, 110, 118, 105, 116, 101, 0, 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 2, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + ] + .into(), + }; + + println!("{}", hex::encode(&any.data)); + + let _: MatchmakeSession = any.try_get().unwrap().unwrap(); let sess = MatchmakeSession { gathering: Gathering { self_gid: 0, @@ -87,18 +88,15 @@ mod test { matchmake_system_type: 2, application_buffer: [1, 2, 3].into(), participation_count: 0, + #[cfg(feature = "v3-5-0")] progress_score: 0, session_key: [].into(), }; - let any = Any::new(&sess).unwrap().to_data().unwrap(); + let any = Any::new(&sess).unwrap(); - let sess2: MatchmakeSession = Any::deserialize(&mut Cursor::new(any)) - .unwrap() - .try_get() - .unwrap() - .unwrap(); + let sess2: MatchmakeSession = any.try_get().unwrap().unwrap(); - assert_eq!(sess, sess2); + assert_eq!(sess, sess2) } } diff --git a/rnex-core/src/rmc/structures/matchmake.rs b/rnex-core/src/rmc/structures/matchmake.rs index 52af790..2e8a2ef 100644 --- a/rnex-core/src/rmc/structures/matchmake.rs +++ b/rnex-core/src/rmc/structures/matchmake.rs @@ -67,7 +67,6 @@ cfg_if! { pub matchmake_system_type: u32, pub application_buffer: Vec, pub participation_count: u32, - pub progress_score: u8, pub session_key: Vec, } } From b9bfac8c70ff43485a4593d19300591987558754 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 15:22:42 +0200 Subject: [PATCH 181/203] implement find by single id --- rnex-core/src/nex/user.rs | 11 +++++++++++ rnex-core/src/rmc/protocols/matchmake.rs | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 7b56fdf..7f0bf41 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -52,6 +52,8 @@ use rnex_core::rmc::structures::ranking::UploadCompetitionData; use std::sync::{Arc, Weak}; use tokio::sync::{Mutex, RwLock}; +use crate::rmc::structures::Error; + cfg_if! { if #[cfg(feature = "datastore")] { use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore}; @@ -509,6 +511,15 @@ impl MatchmakeExtension for User { } impl Matchmake for User { + async fn find_by_single_id(&self, gid: u32) -> Result<(bool, Any), ErrorCode> { + let s = self.matchmake_manager.get_session(gid).await?; + let s = s.lock().await; + Ok(( + true, + Any::new(&s.session).map_err(|_| ErrorCode::Custom_Unknown)?, + )) + } + async fn unregister_gathering(&self, _gid: u32) -> Result { Ok(true) } diff --git a/rnex-core/src/rmc/protocols/matchmake.rs b/rnex-core/src/rmc/protocols/matchmake.rs index 94edce3..d1c43b9 100644 --- a/rnex-core/src/rmc/protocols/matchmake.rs +++ b/rnex-core/src/rmc/protocols/matchmake.rs @@ -4,10 +4,14 @@ use rnex_core::rmc::response::ErrorCode; use rnex_core::PID; +use crate::rmc::structures::any::Any; + #[rmc_proto(21)] pub trait Matchmake { #[method_id(2)] async fn unregister_gathering(&self, gid: u32) -> Result; + #[method_id(21)] + async fn find_by_single_id(&self, gid: u32) -> Result<(bool, Any), ErrorCode>; #[method_id(41)] async fn get_session_urls(&self, gid: u32) -> Result, ErrorCode>; #[method_id(42)] From 6daf271cbdc6ee19ac3c5d282c839b49d7532bc9 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 15:30:42 +0200 Subject: [PATCH 182/203] add more 3.3.0 support --- rnex-core/src/nex/user.rs | 2 +- rnex-core/src/rmc/protocols/matchmake_extension.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 7f0bf41..dbbac7b 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -500,7 +500,7 @@ impl MatchmakeExtension for User { gid: u32, message: String, dont_care_block_list: bool, - participation_count: u16, + //participation_count: u16, ) -> Result, ErrorCode> { let sess = self.matchmake_manager.get_session(gid).await?; let mut sess = sess.lock().await; diff --git a/rnex-core/src/rmc/protocols/matchmake_extension.rs b/rnex-core/src/rmc/protocols/matchmake_extension.rs index 7591a48..6bc8ac5 100644 --- a/rnex-core/src/rmc/protocols/matchmake_extension.rs +++ b/rnex-core/src/rmc/protocols/matchmake_extension.rs @@ -42,7 +42,8 @@ pub trait MatchmakeExtension { gid: u32, message: String, dont_care_block_list: bool, - participation_count: u16, + // this is to cheat support for v3-3-0 + //participation_count: u16, ) -> Result, ErrorCode>; #[method_id(8)] From 28670c09ef89629b72102aa57b95ed41776d1247 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 28 Apr 2026 21:53:40 +0200 Subject: [PATCH 183/203] torture, get outta here bucko --- renovate.json | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 renovate.json diff --git a/renovate.json b/renovate.json deleted file mode 100644 index 3f918de..0000000 --- a/renovate.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["config:recommended"], - "packageRules": [ - { - "matchUpdateTypes": ["minor", "patch"], - "automerge": true - }, - { - "matchUpdateTypes": ["major"], - "automerge": false - } - ] -} \ No newline at end of file From 5972833136f942144ac3de0aca65c33eee0cd06d Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 22:56:36 +0200 Subject: [PATCH 184/203] add utility protocol --- rnex-core/src/nex/user.rs | 11 +++++++++++ rnex-core/src/rmc/protocols/mod.rs | 1 + rnex-core/src/rmc/protocols/util.rs | 14 ++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 rnex-core/src/rmc/protocols/util.rs diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index dbbac7b..44721ed 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -11,6 +11,9 @@ use rnex_core::prudp::station_url::UrlOptions::{ use rnex_core::rmc::protocols::matchmake::{ Matchmake, RawMatchmake, RawMatchmakeInfo, RemoteMatchmake, }; +use rnex_core::rmc::protocols::util::{ + Utility, RawUtility, RawUtilityInfo, RemoteUtility, +}; use rnex_core::rmc::protocols::matchmake_ext::{ MatchmakeExt, RawMatchmakeExt, RawMatchmakeExtInfo, RemoteMatchmakeExt, }; @@ -65,6 +68,7 @@ cfg_if! { Matchmake, NatTraversal, Ranking, + Utility, DataStore } ); @@ -76,6 +80,7 @@ cfg_if! { MatchmakeExt, Matchmake, NatTraversal, + Utility, Ranking } ); @@ -767,6 +772,12 @@ fn fetch_team_votes(fest_id: u32) -> Result, ErrorCode> { }) } +impl Utility for User{ + async fn acquire_nex_unique_id(&self) -> Result{ + return Ok(rand::random()) + } +} + impl Ranking for User { async fn competition_ranking_get_param( &self, diff --git a/rnex-core/src/rmc/protocols/mod.rs b/rnex-core/src/rmc/protocols/mod.rs index 391ecdf..4b00e29 100644 --- a/rnex-core/src/rmc/protocols/mod.rs +++ b/rnex-core/src/rmc/protocols/mod.rs @@ -12,6 +12,7 @@ pub mod nintendo_notification; pub mod notifications; pub mod ranking; pub mod secure; +pub mod util; use crate::result::ResultExtension; use crate::rmc::message::RMCMessage; diff --git a/rnex-core/src/rmc/protocols/util.rs b/rnex-core/src/rmc/protocols/util.rs new file mode 100644 index 0000000..8da6a5f --- /dev/null +++ b/rnex-core/src/rmc/protocols/util.rs @@ -0,0 +1,14 @@ +use macros::{RmcSerialize, method_id, rmc_proto}; + +use rnex_core::{ + PID, + rmc::{response::ErrorCode, structures::any::Any}, +}; + +use crate::{kerberos::KerberosDateTime, rmc::protocols::friends::NNAInfo}; + +#[rmc_proto(110)] +pub trait Utility { + #[method_id(1)] + async fn acquire_nex_unique_id(&self) -> Result; +} From e6ec245b87c0798ef6d7dbdaa7052462224bb874 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 23:31:29 +0200 Subject: [PATCH 185/203] add auto_matchmake_with_search_criteria_postpone --- rnex-core/src/nex/user.rs | 40 ++++++++++++++++--- .../src/rmc/protocols/matchmake_extension.rs | 8 ++++ rnex-core/src/rmc/structures/matchmake.rs | 2 +- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 44721ed..9670c78 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -11,9 +11,6 @@ use rnex_core::prudp::station_url::UrlOptions::{ use rnex_core::rmc::protocols::matchmake::{ Matchmake, RawMatchmake, RawMatchmakeInfo, RemoteMatchmake, }; -use rnex_core::rmc::protocols::util::{ - Utility, RawUtility, RawUtilityInfo, RemoteUtility, -}; use rnex_core::rmc::protocols::matchmake_ext::{ MatchmakeExt, RawMatchmakeExt, RawMatchmakeExtInfo, RemoteMatchmakeExt, }; @@ -29,6 +26,7 @@ use rnex_core::rmc::protocols::notifications::notification_types::{ }; use rnex_core::rmc::protocols::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking}; use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; +use rnex_core::rmc::protocols::util::{RawUtility, RawUtilityInfo, RemoteUtility, Utility}; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::any::Any; use rnex_core::rmc::structures::matchmake::{ @@ -513,6 +511,36 @@ impl MatchmakeExtension for User { Ok(sess.session.session_key.clone()) } + + async fn auto_matchmake_with_search_criteria_postpone( + &self, + criteria: Vec, + gathering: Any, + join_message: String, + ) -> Result { + let session: MatchmakeSession = gathering + .try_get() + .map(|v| v.ok()) + .flatten() + .ok_or(ErrorCode::Core_InvalidArgument)?; + + let session = self + .auto_matchmake_with_param_postpone(AutoMatchmakeParam { + matchmake_session: session, + additional_participants: vec![], + gid_for_participation_check: 0, + auto_matchmake_option: 0, + join_message, + participation_count: 0, + search_criteria: criteria, + target_gids: vec![], + }) + .await?; + + let any = Any::new(&session).map_err(|_| ErrorCode::Core_SystemError)?; + + Ok(any) + } } impl Matchmake for User { @@ -772,9 +800,9 @@ fn fetch_team_votes(fest_id: u32) -> Result, ErrorCode> { }) } -impl Utility for User{ - async fn acquire_nex_unique_id(&self) -> Result{ - return Ok(rand::random()) +impl Utility for User { + async fn acquire_nex_unique_id(&self) -> Result { + return Ok(rand::random()); } } diff --git a/rnex-core/src/rmc/protocols/matchmake_extension.rs b/rnex-core/src/rmc/protocols/matchmake_extension.rs index 6bc8ac5..190dd94 100644 --- a/rnex-core/src/rmc/protocols/matchmake_extension.rs +++ b/rnex-core/src/rmc/protocols/matchmake_extension.rs @@ -6,6 +6,7 @@ use rnex_core::rmc::structures::matchmake::{ use crate::rmc::protocols::notifications::NotificationEvent; use crate::rmc::structures::any::Any; +use crate::rmc::structures::matchmake::MatchmakeSessionSearchCriteria; #[rmc_proto(109)] pub trait MatchmakeExtension { @@ -35,6 +36,13 @@ pub trait MatchmakeExtension { &self, ty: i32, ) -> Result, ErrorCode>; + #[method_id(15)] + async fn auto_matchmake_with_search_criteria_postpone( + &self, + criteria: Vec, + gathering: Any, + join_msg: String, + ) -> Result; #[method_id(30)] async fn join_matchmake_session_ex( diff --git a/rnex-core/src/rmc/structures/matchmake.rs b/rnex-core/src/rmc/structures/matchmake.rs index 2e8a2ef..b4d3c5c 100644 --- a/rnex-core/src/rmc/structures/matchmake.rs +++ b/rnex-core/src/rmc/structures/matchmake.rs @@ -30,7 +30,7 @@ pub struct MatchmakeParam { cfg_if! { if #[cfg(feature = "v3-5-0")]{ - #[derive(RmcSerialize, Debug, Clone, Default)] + #[derive(RmcSerialize, Debug, Clone, Default, PartialEq)] #[rmc_struct(3)] pub struct MatchmakeSession { //inherits from From 9d3a25fd950ada62fb99a6abc53300a5a1debb8c Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 23:33:12 +0200 Subject: [PATCH 186/203] remove one test --- rnex-core/src/rmc/structures/any.rs | 57 ----------------------- rnex-core/src/rmc/structures/matchmake.rs | 2 +- rnex-core/src/rmc/structures/variant.rs | 2 +- 3 files changed, 2 insertions(+), 59 deletions(-) diff --git a/rnex-core/src/rmc/structures/any.rs b/rnex-core/src/rmc/structures/any.rs index 98feb86..0f531d8 100644 --- a/rnex-core/src/rmc/structures/any.rs +++ b/rnex-core/src/rmc/structures/any.rs @@ -43,60 +43,3 @@ impl Any { }); } } - -#[cfg(test)] -mod test { - use crate::rmc::structures::{ - RmcSerialize, - any::Any, - matchmake::{Gathering, MatchmakeSession}, - }; - - #[test] - fn test() { - let any = Any { - name: "MatchmakeSession".into(), - data: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 98, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, - 0, 0, 0, 0, 0, 20, 0, 68, 111, 111, 114, 115, 32, 70, 114, 105, 101, 110, 100, 32, - 73, 110, 118, 105, 116, 101, 0, 0, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 2, 3, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - ] - .into(), - }; - - println!("{}", hex::encode(&any.data)); - - let _: MatchmakeSession = any.try_get().unwrap().unwrap(); - let sess = MatchmakeSession { - gathering: Gathering { - self_gid: 0, - owner_pid: 0, - host_pid: 0, - minimum_participants: 2, - maximum_participants: 2, - participant_policy: 98, - policy_argument: 0, - flags: 32, - state: 0, - description: "Doors Friend Invite".into(), - }, - gamemode: 0, - attributes: [2, 3, 0, 0, 0, 0].into(), - open_participation: false, - matchmake_system_type: 2, - application_buffer: [1, 2, 3].into(), - participation_count: 0, - #[cfg(feature = "v3-5-0")] - progress_score: 0, - session_key: [].into(), - }; - - let any = Any::new(&sess).unwrap(); - - let sess2: MatchmakeSession = any.try_get().unwrap().unwrap(); - - assert_eq!(sess, sess2) - } -} diff --git a/rnex-core/src/rmc/structures/matchmake.rs b/rnex-core/src/rmc/structures/matchmake.rs index b4d3c5c..7753f03 100644 --- a/rnex-core/src/rmc/structures/matchmake.rs +++ b/rnex-core/src/rmc/structures/matchmake.rs @@ -22,7 +22,7 @@ pub struct Gathering { } // rmc structure -#[derive(RmcSerialize, Debug, Clone, Default)] +#[derive(RmcSerialize, Debug, Clone, Default, PartialEq)] #[rmc_struct(0)] pub struct MatchmakeParam { pub params: Vec<(String, Variant)>, diff --git a/rnex-core/src/rmc/structures/variant.rs b/rnex-core/src/rmc/structures/variant.rs index 9f705d0..c5c41b0 100644 --- a/rnex-core/src/rmc/structures/variant.rs +++ b/rnex-core/src/rmc/structures/variant.rs @@ -3,7 +3,7 @@ use rnex_core::rmc::structures; use rnex_core::rmc::structures::{Result, RmcSerialize}; use std::io::{Read, Write}; -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, PartialEq)] pub enum Variant { #[default] None, From e06ea4c0cb84c320d4d6970b699950131768e794 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 23:44:43 +0200 Subject: [PATCH 187/203] add logging --- rnex-core/src/nex/user.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 9670c78..3917b72 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -54,6 +54,7 @@ use std::sync::{Arc, Weak}; use tokio::sync::{Mutex, RwLock}; use crate::rmc::structures::Error; +use crate::rmc::structures::matchmake::MatchmakeSessionSearchCriteria; cfg_if! { if #[cfg(feature = "datastore")] { @@ -514,7 +515,7 @@ impl MatchmakeExtension for User { async fn auto_matchmake_with_search_criteria_postpone( &self, - criteria: Vec, + criteria: Vec, gathering: Any, join_message: String, ) -> Result { @@ -524,6 +525,8 @@ impl MatchmakeExtension for User { .flatten() .ok_or(ErrorCode::Core_InvalidArgument)?; + println!("{:?}", criteria); + let session = self .auto_matchmake_with_param_postpone(AutoMatchmakeParam { matchmake_session: session, From 5a69d2acf5a8e4bc8765ed486593a33f66c41379 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 28 Apr 2026 23:54:34 +0200 Subject: [PATCH 188/203] add singular values for bounds values --- rnex-core/src/nex/matchmake.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index fd6632e..cb96c91 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -115,9 +115,13 @@ fn read_bounds_string(str: &str) -> Option<(T, T)> { } fn check_bounds_str(compare: T, str: &str) -> Option { - let bounds: (T, T) = read_bounds_string(str)?; - - Some(bounds.0 <= compare && compare <= bounds.1) + if let Some(bounds) = read_bounds_string::(str) { + return Some(bounds.0 <= compare && compare <= bounds.1); + } + if let Ok(val) = T::from_str(str) { + return Some(val == compare); + } + None } pub async fn broadcast_notification>( From 7565501c19f9a22fb7c4814abd1fec71fb1dd95b Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Wed, 29 Apr 2026 00:03:53 +0200 Subject: [PATCH 189/203] make attrib matching game specific --- editions.yaml | 1 + rnex-core/Cargo.toml | 1 + rnex-core/src/nex/matchmake.rs | 53 ++++++++++++++++++---------------- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/editions.yaml b/editions.yaml index ecd0513..8a636ad 100644 --- a/editions.yaml +++ b/editions.yaml @@ -15,6 +15,7 @@ splatoon: features: - prudpv1 - v3-8-15 + - splatoon settings: AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" RNEX_VIRTUAL_PORT_INSECURE: "1:10" diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index f338fe3..b48999f 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -51,6 +51,7 @@ v3-5-0 = ["v3-4-0"] v3-8-15 = ["v3-5-0"] v4-3-11 = ["v3-8-15"] nx = ["big_pid"] +splatoon = [] datastore = ["database-support", "v3-8-15", "dep:aws-sdk-s3", "dep:aws-config"] database-support = ["dep:sqlx"] diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index cb96c91..686f3bb 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -397,32 +397,35 @@ impl ExtendedMatchmakeSession { return Ok(false); } - if search_criteria - .attribs - .get(0) - .map(|str| str.parse().ok()) - .flatten() - != self.session.attributes.get(0).map(|v| *v) + #[cfg(feature = "splatoon")] { - return Ok(false); - } - if search_criteria - .attribs - .get(2) - .map(|str| str.parse().ok()) - .flatten() - != self.session.attributes.get(2).map(|v| *v) - { - return Ok(false); - } - if search_criteria - .attribs - .get(3) - .map(|str| str.parse().ok()) - .flatten() - != self.session.attributes.get(3).map(|v| *v) - { - return Ok(false); + if search_criteria + .attribs + .get(0) + .map(|str| str.parse().ok()) + .flatten() + != self.session.attributes.get(0).map(|v| *v) + { + return Ok(false); + } + if search_criteria + .attribs + .get(2) + .map(|str| str.parse().ok()) + .flatten() + != self.session.attributes.get(2).map(|v| *v) + { + return Ok(false); + } + if search_criteria + .attribs + .get(3) + .map(|str| str.parse().ok()) + .flatten() + != self.session.attributes.get(3).map(|v| *v) + { + return Ok(false); + } } Ok(true) From b486e5e5908c8f2986caaef5bab4a54c759996e4 Mon Sep 17 00:00:00 2001 From: red binder Date: Wed, 29 Apr 2026 00:08:00 +0200 Subject: [PATCH 190/203] add Fast Racing NEO edition --- editions.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/editions.yaml b/editions.yaml index 8a636ad..00e5e06 100644 --- a/editions.yaml +++ b/editions.yaml @@ -10,6 +10,17 @@ wii-u-chat: RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 10000 RNEX_ACCESS_KEY: "e7a47214" +fast-racing-neo: + include-in-checkall: true + features: + - prudpv1 + - v3-8-15 + settings: + AUTH_REPORT_VERSION: "branch:origin/release/ngs/3.9.x.200x build:3_9_19_2005_0" + RNEX_VIRTUAL_PORT_INSECURE: "1:10" + RNEX_VIRTUAL_PORT_SECURE: "1:10" + RNEX_DEFAULT_PORT: 10000 + RNEX_ACCESS_KEY: "811aa39f" splatoon: include-in-checkall: true features: From 43e526c834094e1e220ef16ea8463918cb5acb51 Mon Sep 17 00:00:00 2001 From: red binder Date: Wed, 29 Apr 2026 01:23:18 +0200 Subject: [PATCH 191/203] Update CI --- .ci-scripts/make-edition.sh | 25 +++++++----------- Dockerfile | 52 +++++++++++++++++++++++-------------- README.md | 18 +++++-------- 3 files changed, 49 insertions(+), 46 deletions(-) diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh index d03e2f1..2b4bb91 100755 --- a/.ci-scripts/make-edition.sh +++ b/.ci-scripts/make-edition.sh @@ -1,20 +1,15 @@ #!/usr/bin/env bash - export EDITION=$1 -export BA="--network=host --build-arg EDITION=$1 --build-arg DATABASE_URL="$DATABASE_URL"" source /etc/environment : "${RNEX_CONTAINER_PLATFORM:=podman}" -export BUILDKIT_PROGRESS=plain -# $RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . -# $RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" -$RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" --target=node-holder . -$RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" --target=proxy-secure . -$RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" --target=proxy-insecure . -$RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" --target=backend-auth . -$RNEX_CONTAINER_PLATFORM build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" --target=backend-secure . -$RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" -$RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" -$RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" -$RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" -$RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" +for TARGET in node-holder proxy-secure proxy-insecure backend-auth backend-secure; do + $RNEX_CONTAINER_PLATFORM build \ + --network=host \ + --build-arg EDITION="$EDITION" \ + --build-arg DATABASE_URL="$DATABASE_URL" \ + -t "$CI_REGISTRY_IMAGE/$EDITION/$TARGET:$CI_COMMIT_SHORT_SHA" \ + --target="$TARGET" . + + $RNEX_CONTAINER_PLATFORM push "$CI_REGISTRY_IMAGE/$EDITION/$TARGET:$CI_COMMIT_SHORT_SHA" +done \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 059b9e8..44e7ace 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,43 +1,57 @@ -FROM rust:alpine AS build-container - -RUN apk add --no-cache protobuf-dev git musl-dev lld openssl-dev openssl-libs-static yq bash - -FROM build-container AS builder - +# syntax=docker/dockerfile:1 +FROM rust:alpine AS chef +RUN apk add --no-cache musl-dev lld g++ make +RUN cargo install cargo-chef WORKDIR /app +FROM chef AS planner COPY . . +RUN cargo chef prepare --recipe-path recipe.json +FROM chef AS builder +RUN apk add --no-cache protobuf-dev git openssl-dev openssl-libs-static bash yq + +COPY --from=planner /app/recipe.json recipe.json ARG EDITION ARG DATABASE_URL -RUN git submodule update --init --recursive +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/app/target \ + cargo chef cook --release --recipe-path recipe.json --target x86_64-unknown-linux-musl && \ + cargo chef cook --tests --target x86_64-unknown-linux-musl --recipe-path recipe.json + +COPY . . +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/app/target \ + ./test-edition.sh && ./build-edition.sh && \ + mkdir -p /app/dist && \ + cp /app/target/x86_64-unknown-linux-musl/release/edge_node_holder_server /app/dist/ && \ + cp /app/target/x86_64-unknown-linux-musl/release/proxy_insecure /app/dist/ && \ + cp /app/target/x86_64-unknown-linux-musl/release/proxy_secure /app/dist/ && \ + cp /app/target/x86_64-unknown-linux-musl/release/backend_server_insecure /app/dist/ && \ + cp /app/target/x86_64-unknown-linux-musl/release/backend_server_secure /app/dist/ -RUN ./test-edition.sh -RUN ./build-edition.sh FROM scratch AS node-holder -COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/edge_node_holder_server /edge_node_holder_server +COPY --from=builder /app/dist/edge_node_holder_server /edge_node_holder_server ENTRYPOINT ["/edge_node_holder_server"] - FROM scratch AS proxy-insecure -COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_insecure /proxy_insecure +COPY --from=builder /app/dist/proxy_insecure /proxy_insecure ENTRYPOINT ["/proxy_insecure"] FROM scratch AS proxy-secure -COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_secure /proxy_secure +COPY --from=builder /app/dist/proxy_secure /proxy_secure ENTRYPOINT ["/proxy_secure"] - FROM scratch AS backend-auth -COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server_insecure /backend_server_insecure +COPY --from=builder /app/dist/backend_server_insecure /backend_server_insecure ENTRYPOINT ["/backend_server_insecure"] FROM scratch AS backend-secure -COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server_secure /backend_server_secure +COPY --from=builder /app/dist/backend_server_secure /backend_server_secure ENTRYPOINT ["/backend_server_secure"] -# make sure the final output container is the dev container so that we can use it from the devcontainer.json -FROM build-container AS dev-container -RUN apk add openjdk21-jdk gcompat +FROM chef AS dev-container +RUN apk add --no-cache openjdk21-jdk gcompat git bash protobuf-dev +COPY --from=builder /app/dist/* /usr/local/bin/ \ No newline at end of file diff --git a/README.md b/README.md index c5f1ada..b1385b7 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,14 @@ # Splatoon NEX Server in Rust ## Credits: -- Pretendo team for the rest of the Servers and Reverse engineering efforts +- Pretendo team for their reverse engineering efforts - Kinnay for his huge work on reversing nex servers and documentation(https://github.com/Kinnay/NintendoClients/) - Splatfestival testing team for helping us test our messes of code -- The SPFN team(Bloxer, Ceantix and RusticMaple) +- The SPFN team(RusticMaple, BloxerHD, Ceantix, RedBinder0526) -This nex implementation was not created and is not intended to compete with pretendo, -we wholeheartedly support pretendo. +This NEX implementation was not created to rival Pretendo, we don't want any bad blood between anyone. This project would never have been possible without their reverse engineering efforts. -As such if you want to respect the Authors wishes(Maple(Me) is pretty much the sole author of Rust-Nex), do not -use it if you mean any harm to pretendo. If you do show intent to harm them you will be blocked from ever contributing -and will be refused support, as such please also refrain from asking for support if you have been blocked by pretendo. +As such if you want to respect the Authors wishes, do not use it if you mean any harm to Pretendo. (harm falls under e.g. using this software while also sabotaging pretendo) If you do show intent to harm them you will be blocked from ever contributing and will be refused support. - -I felt like this needed to be said as there are far too many pretendo copycats who blatantly copy their code and use -their reversal efforts with no credits in sight in an attempt to harm them for some grudge or stupid reason. -I feel that by working together and not against each other we can reach a better and healthier future for the community, -health of developers and numerous more reasons. +We felt like this needed to be said as there are far too many Pretendo copycats who blatantly copy their code and use their reversal efforts with no credits in sight in an attempt to harm them for some grudge or stupid reason. +We feel that by working together and not against each other we can reach a better and healthier future for the community, health of developers and numerous more reasons. From 96f0e6c652b960cd6e17cd4bcffa138c939f9e80 Mon Sep 17 00:00:00 2001 From: red binder Date: Wed, 29 Apr 2026 07:14:16 +0200 Subject: [PATCH 192/203] Add new games to CI --- .forgejo/workflows/build.yml | 60 ++++++++++++++++++++++++++++++++++++ editions.yaml | 12 ++++++++ 2 files changed, 72 insertions(+) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index f76432e..3a0bf95 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -11,6 +11,66 @@ env: SHORT_SHA: ${{ github.sha }} jobs: + splatoon-testfire: + runs-on: debian-trixie + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Cache container storage + uses: actions/cache@v4 + with: + path: | + /var/lib/containers/storage + /run/containers/storage + ~/.local/share/containers/storage + key: image-cache + + - name: Login to registry + run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net + + - name: Set short SHA + run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV + + - name: Build Splatoon Testfire edition + env: + CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex + CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} + run: ./.ci-scripts/make-edition.sh splatoon-testfire + + fast-racing-neo: + runs-on: debian-trixie + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Cache container storage + uses: actions/cache@v4 + with: + path: | + /var/lib/containers/storage + /run/containers/storage + ~/.local/share/containers/storage + key: image-cache + + - name: Login to registry + run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net + + - name: Set short SHA + run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV + + - name: Build Fast Racing NEO edition + env: + CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex + CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} + run: ./.ci-scripts/make-edition.sh fast-racing-neo + wii-u-chat: runs-on: debian-trixie diff --git a/editions.yaml b/editions.yaml index 00e5e06..30fc57a 100644 --- a/editions.yaml +++ b/editions.yaml @@ -33,6 +33,18 @@ splatoon: RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 6000 RNEX_ACCESS_KEY: "6f599f81" +splatoon-testfire: + include-in-checkall: true + features: + - prudpv1 + - v3-8-15 + - splatoon + settings: + AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" + RNEX_VIRTUAL_PORT_INSECURE: "1:10" + RNEX_VIRTUAL_PORT_SECURE: "1:10" + RNEX_DEFAULT_PORT: 10000 + RNEX_ACCESS_KEY: "da693ee5" friends: include-in-checkall: false features: From 28911c801a3c5a5fcbb08651e5e02dc1185cad82 Mon Sep 17 00:00:00 2001 From: redbinder0526 Date: Wed, 29 Apr 2026 09:59:18 +0200 Subject: [PATCH 193/203] Clarify repo state --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b1385b7..5e64ee4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# Splatoon NEX Server in Rust +# Rust NEX monorepo + +This repo contains the code for all game servers using RNEX. ## Credits: - Pretendo team for their reverse engineering efforts From 0f89601f2ed400a570221eda7c5df869f7848b9f Mon Sep 17 00:00:00 2001 From: red binder Date: Sat, 2 May 2026 12:39:25 +0200 Subject: [PATCH 194/203] Start work on Minecraft Wii U --- editions.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/editions.yaml b/editions.yaml index 30fc57a..47d4867 100644 --- a/editions.yaml +++ b/editions.yaml @@ -1,3 +1,15 @@ +minecraft-wiiu: + include-in-checkall: true + features: + - prudpv1 + - third-notif-param + - v3-8-15 + settings: + AUTH_REPORT_VERSION: "branch:origin/release/ngs/3.10.x.200x build:3_10_22_2006_0" + RNEX_VIRTUAL_PORT_INSECURE: "1:10" + RNEX_VIRTUAL_PORT_SECURE: "1:10" + RNEX_DEFAULT_PORT: 13000 + RNEX_ACCESS_KEY: "f1b61c8e" wii-u-chat: include-in-checkall: true features: From 0df281cd61ddd041ed83d02b548be3a528efee6e Mon Sep 17 00:00:00 2001 From: red binder Date: Sat, 2 May 2026 13:19:06 +0200 Subject: [PATCH 195/203] Add support for NEX v3.10.22 --- editions.yaml | 2 +- rnex-core/Cargo.toml | 1 + rnex-core/src/rmc/structures/matchmake.rs | 48 ++++++++++++++++------- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/editions.yaml b/editions.yaml index 47d4867..8f6ffb5 100644 --- a/editions.yaml +++ b/editions.yaml @@ -3,7 +3,7 @@ minecraft-wiiu: features: - prudpv1 - third-notif-param - - v3-8-15 + - v3-10-22 settings: AUTH_REPORT_VERSION: "branch:origin/release/ngs/3.10.x.200x build:3_10_22_2006_0" RNEX_VIRTUAL_PORT_INSECURE: "1:10" diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index b48999f..f30c47c 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -49,6 +49,7 @@ third-notif-param = [] v3-4-0 = ["v3-3-2", "third-notif-param", "rmc_struct_header"] v3-5-0 = ["v3-4-0"] v3-8-15 = ["v3-5-0"] +v3-10-22 = ["v3-8-15"] v4-3-11 = ["v3-8-15"] nx = ["big_pid"] splatoon = [] diff --git a/rnex-core/src/rmc/structures/matchmake.rs b/rnex-core/src/rmc/structures/matchmake.rs index 7753f03..aeb26ff 100644 --- a/rnex-core/src/rmc/structures/matchmake.rs +++ b/rnex-core/src/rmc/structures/matchmake.rs @@ -121,20 +121,40 @@ pub struct MatchmakeBlockListParam { option_flag: u32, } -#[derive(RmcSerialize, Debug, Clone)] -#[rmc_struct(0)] -pub struct JoinMatchmakeSessionParam { - pub gid: u32, - pub additional_participants: Vec, - pub gid_for_participation_check: u32, - pub join_matchmake_session_open: u32, - pub join_matchmake_session_behavior: u8, - pub user_password: String, - pub system_password: String, - pub join_message: String, - pub participation_count: u16, - //pub extra_participant: u16, - //pub block_list_param: MatchmakeBlockListParam +cfg_if! { + if #[cfg(feature = "v3-10-22")] { + #[derive(RmcSerialize, Debug, Clone)] + #[rmc_struct(1)] + pub struct JoinMatchmakeSessionParam { + pub gid: u32, + pub additional_participants: Vec, + pub gid_for_participation_check: u32, + pub join_matchmake_session_open: u32, + pub join_matchmake_session_behavior: u8, + pub user_password: String, + pub system_password: String, + pub join_message: String, + pub participation_count: u16, + pub extra_participant: u16, + //pub block_list_param: MatchmakeBlockListParam + } + } else { + #[derive(RmcSerialize, Debug, Clone)] + #[rmc_struct(0)] + pub struct JoinMatchmakeSessionParam { + pub gid: u32, + pub additional_participants: Vec, + pub gid_for_participation_check: u32, + pub join_matchmake_session_open: u32, + pub join_matchmake_session_behavior: u8, + pub user_password: String, + pub system_password: String, + pub join_message: String, + pub participation_count: u16, + //pub extra_participant: u16, + //pub block_list_param: MatchmakeBlockListParam + } + } } pub mod gathering_flags { From 9f2ab87f6a1f756caeb7cd35103112100af63d19 Mon Sep 17 00:00:00 2001 From: red binder Date: Sat, 2 May 2026 17:14:50 +0200 Subject: [PATCH 196/203] Update CI --- .forgejo/workflows/build.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 3a0bf95..593145f 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -11,6 +11,36 @@ env: SHORT_SHA: ${{ github.sha }} jobs: + minecraft-wiiu: + runs-on: debian-trixie + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Cache container storage + uses: actions/cache@v4 + with: + path: | + /var/lib/containers/storage + /run/containers/storage + ~/.local/share/containers/storage + key: image-cache + + - name: Login to registry + run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net + + - name: Set short SHA + run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV + + - name: Build Minecraft Wii U edition + env: + CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex + CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} + run: ./.ci-scripts/make-edition.sh minecraft-wiiu + splatoon-testfire: runs-on: debian-trixie From 97d0a1f5535e1e81874b2f2384622d34bbe59bb9 Mon Sep 17 00:00:00 2001 From: red binder Date: Sat, 2 May 2026 22:07:26 +0200 Subject: [PATCH 197/203] Initial support for Puyo Puyo Tetris --- .forgejo/workflows/build.yml | 30 ++++++++++++++++++++++++++++++ editions.yaml | 12 ++++++++++++ 2 files changed, 42 insertions(+) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 593145f..0a329d9 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -11,6 +11,36 @@ env: SHORT_SHA: ${{ github.sha }} jobs: + puyopuyo: + runs-on: debian-trixie + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Cache container storage + uses: actions/cache@v4 + with: + path: | + /var/lib/containers/storage + /run/containers/storage + ~/.local/share/containers/storage + key: image-cache + + - name: Login to registry + run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net + + - name: Set short SHA + run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV + + - name: Build puyo puyo tetris edition + env: + CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex + CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} + run: ./.ci-scripts/make-edition.sh puyopuyo + minecraft-wiiu: runs-on: debian-trixie diff --git a/editions.yaml b/editions.yaml index 8f6ffb5..dca2347 100644 --- a/editions.yaml +++ b/editions.yaml @@ -1,3 +1,15 @@ +puyopuyo: + include-in-checkall: true + features: + - prudpv1 + - third-notif-param + - v3-8-15 + settings: + AUTH_REPORT_VERSION: "branch:origin/release/ngs/3.5.x.1000 build:3_5_16_1000_0" + RNEX_VIRTUAL_PORT_INSECURE: "1:10" + RNEX_VIRTUAL_PORT_SECURE: "1:10" + RNEX_DEFAULT_PORT: 10000 + RNEX_ACCESS_KEY: "4eb0ca36" minecraft-wiiu: include-in-checkall: true features: From d39758d7489a425659d41d3be74a619f6856effb Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Sat, 2 May 2026 22:55:12 +0200 Subject: [PATCH 198/203] disable version mismatch in editions without header --- rnex-core/src/rmc/structures/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rnex-core/src/rmc/structures/mod.rs b/rnex-core/src/rmc/structures/mod.rs index 33de120..ce6cb75 100644 --- a/rnex-core/src/rmc/structures/mod.rs +++ b/rnex-core/src/rmc/structures/mod.rs @@ -13,6 +13,7 @@ pub enum Error { Utf8(#[from] FromUtf8Error), #[error("unexpected value: {0}")] UnexpectedValue(u64), + #[cfg(feature = "rmc_struct_header")] #[error("version mismatch: {0}")] VersionMismatch(u8), #[error("an error occurred reading the station url")] From d10e0cb596bef69418cde4796b62b36b75c781f7 Mon Sep 17 00:00:00 2001 From: red binder Date: Sun, 3 May 2026 23:56:10 +0200 Subject: [PATCH 199/203] Add prelimiary support for Wii Sports Club and MTUS --- .forgejo/workflows/build.yml | 60 ++++++++++++++++++++++++++++++++++++ editions.yaml | 24 +++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index 0a329d9..35e5879 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -11,6 +11,66 @@ env: SHORT_SHA: ${{ github.sha }} jobs: + mario-tennis: + runs-on: debian-trixie + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Cache container storage + uses: actions/cache@v4 + with: + path: | + /var/lib/containers/storage + /run/containers/storage + ~/.local/share/containers/storage + key: image-cache + + - name: Login to registry + run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net + + - name: Set short SHA + run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV + + - name: Build MTUS tetris edition + env: + CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex + CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} + run: ./.ci-scripts/make-edition.sh mario-tennis + + wii-sports-club: + runs-on: debian-trixie + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Cache container storage + uses: actions/cache@v4 + with: + path: | + /var/lib/containers/storage + /run/containers/storage + ~/.local/share/containers/storage + key: image-cache + + - name: Login to registry + run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net + + - name: Set short SHA + run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV + + - name: Build Wii Sports Club edition + env: + CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex + CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} + run: ./.ci-scripts/make-edition.sh wii-sports-club + puyopuyo: runs-on: debian-trixie diff --git a/editions.yaml b/editions.yaml index dca2347..fb635e8 100644 --- a/editions.yaml +++ b/editions.yaml @@ -1,3 +1,15 @@ +wii-sports-club: + include-in-checkall: true + features: + - prudpv1 + - third-notif-param + - v3-8-15 + settings: + AUTH_REPORT_VERSION: "branch:origin/project/appsp build:3_4_24_4_0" + RNEX_VIRTUAL_PORT_INSECURE: "1:10" + RNEX_VIRTUAL_PORT_SECURE: "1:10" + RNEX_DEFAULT_PORT: 10000 + RNEX_ACCESS_KEY: "4d324052" puyopuyo: include-in-checkall: true features: @@ -22,6 +34,18 @@ minecraft-wiiu: RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 13000 RNEX_ACCESS_KEY: "f1b61c8e" +mario-tennis: + include-in-checkall: true + features: + - prudpv1 + - third-notif-param + - v3-8-15 + settings: + AUTH_REPORT_VERSION: "branch:origin/release/ngs/3.9.x.200x build:3_9_19_2005_0" + RNEX_VIRTUAL_PORT_INSECURE: "1:10" + RNEX_VIRTUAL_PORT_SECURE: "1:10" + RNEX_DEFAULT_PORT: 10000 + RNEX_ACCESS_KEY: "c69b92a0" wii-u-chat: include-in-checkall: true features: From de20212d1e758636a3de494ddb4b60a3555af9c7 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Mon, 4 May 2026 16:06:25 +0200 Subject: [PATCH 200/203] redo macros --- Cargo.lock | 531 ++++++++-------- macros/src/lib.rs | 487 ++------------- macros/src/protos.rs | 583 +++++++++++------- macros/src/rmc_struct.rs | 426 +++++++++++++ macros/src/util.rs | 10 + proxy-common/src/lib.rs | 1 + prudpv1/src/prudp/packet.rs | 2 +- rnex-core/src/nex/user.rs | 19 +- .../src/rmc/protocols/matchmake_extension.rs | 1 + rnex-core/src/rmc/protocols/mod.rs | 1 - rnex-core/src/rmc/protocols/util.rs | 9 +- rnex-core/src/rmc/structures/mod.rs | 8 +- rnex-core/src/rmc/structures/string_set.rs | 86 +++ rnex-core/src/rnex_proxy_common.rs | 2 +- test-all.sh | 13 + 15 files changed, 1201 insertions(+), 978 deletions(-) create mode 100644 macros/src/rmc_struct.rs create mode 100644 macros/src/util.rs create mode 100644 rnex-core/src/rmc/structures/string_set.rs create mode 100755 test-all.sh diff --git a/Cargo.lock b/Cargo.lock index e666c9d..186e31d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,9 +31,9 @@ checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "async-trait" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", @@ -82,7 +82,7 @@ dependencies = [ "bytes", "fastrand", "hex", - "http 1.3.1", + "http 1.4.0", "sha1 0.10.6", "time", "tokio", @@ -105,9 +105,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.16.2" +version = "1.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" +checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" dependencies = [ "aws-lc-sys", "zeroize", @@ -115,9 +115,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.39.1" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" +checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" dependencies = [ "cc", "cmake", @@ -144,7 +144,7 @@ dependencies = [ "bytes-utils", "fastrand", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "http-body 0.4.6", "http-body 1.0.1", "percent-encoding", @@ -178,7 +178,7 @@ dependencies = [ "hex", "hmac 0.13.0", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "lru", "percent-encoding", @@ -207,7 +207,7 @@ dependencies = [ "bytes", "fastrand", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "regex-lite", "tracing", ] @@ -231,7 +231,7 @@ dependencies = [ "bytes", "fastrand", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "regex-lite", "tracing", ] @@ -256,7 +256,7 @@ dependencies = [ "aws-types", "fastrand", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "regex-lite", "tracing", ] @@ -278,7 +278,7 @@ dependencies = [ "hex", "hmac 0.13.0", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "p256", "percent-encoding", "ring", @@ -311,7 +311,7 @@ dependencies = [ "bytes", "crc-fast", "hex", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "md-5 0.11.0", @@ -345,7 +345,7 @@ dependencies = [ "bytes-utils", "futures-core", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "percent-encoding", @@ -366,16 +366,16 @@ dependencies = [ "h2 0.3.27", "h2 0.4.13", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "http-body 0.4.6", "hyper 0.14.32", "hyper 1.9.0", "hyper-rustls 0.24.2", - "hyper-rustls 0.27.8", + "hyper-rustls 0.27.9", "hyper-util", "pin-project-lite", "rustls 0.21.12", - "rustls 0.23.31", + "rustls 0.23.40", "rustls-native-certs", "rustls-pki-types", "tokio", @@ -427,7 +427,7 @@ dependencies = [ "bytes", "fastrand", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "http-body 0.4.6", "http-body 1.0.1", "http-body-util", @@ -448,7 +448,7 @@ dependencies = [ "aws-smithy-types", "bytes", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "pin-project-lite", "tokio", "tracing", @@ -477,7 +477,7 @@ dependencies = [ "bytes-utils", "futures-core", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "http-body 0.4.6", "http-body 1.0.1", "http-body-util", @@ -545,11 +545,11 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -572,24 +572,24 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "bytemuck" -version = "1.23.1" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.10.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "441473f2b4b0459a68628c744bc61d23e730fb00128b841d30fa4bb3972257e4" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", @@ -620,9 +620,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.60" +version = "1.2.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" +checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" dependencies = [ "find-msvc-tools", "jobserver", @@ -646,7 +646,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -655,7 +655,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common 0.1.6", + "crypto-common 0.1.7", "inout", ] @@ -708,9 +708,9 @@ dependencies = [ [[package]] name = "cookie_store" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fc4bff745c9b4c7fb1e97b25d13153da2bc7796260141df62378998d070207f" +checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206" dependencies = [ "cookie", "document-features", @@ -769,9 +769,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" [[package]] name = "crc-fast" @@ -833,9 +833,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -861,9 +861,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" [[package]] name = "der" @@ -888,9 +888,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", ] @@ -903,15 +903,15 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "const-oid 0.9.6", - "crypto-common 0.1.6", + "crypto-common 0.1.7", "subtle", ] [[package]] name = "digest" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer 0.12.0", "const-oid 0.10.2", @@ -1004,6 +1004,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "etcetera" version = "0.8.0" @@ -1050,9 +1060,9 @@ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "flate2" -version = "1.1.5" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", @@ -1213,9 +1223,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "libc", @@ -1275,7 +1285,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.3.1", + "http 1.4.0", "indexmap", "slab", "tokio", @@ -1305,6 +1315,12 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + [[package]] name = "hashlink" version = "0.10.0" @@ -1350,7 +1366,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -1375,12 +1391,11 @@ dependencies = [ [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -1402,7 +1417,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.3.1", + "http 1.4.0", ] [[package]] @@ -1413,7 +1428,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "pin-project-lite", ] @@ -1432,9 +1447,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hybrid-array" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" +checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" dependencies = [ "typenum", ] @@ -1474,7 +1489,7 @@ dependencies = [ "futures-channel", "futures-core", "h2 0.4.13", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "httparse", "itoa", @@ -1501,14 +1516,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.8" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2b52f86d1d4bc0d6b4e6826d960b1b333217e07d36b882dca570a5e1c48895b" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ - "http 1.3.1", + "http 1.4.0", "hyper 1.9.0", "hyper-util", - "rustls 0.23.31", + "rustls 0.23.40", "rustls-native-certs", "tokio", "tokio-rustls 0.26.4", @@ -1525,7 +1540,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "hyper 1.9.0", "ipnet", @@ -1540,9 +1555,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1564,12 +1579,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1577,9 +1593,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -1590,9 +1606,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1604,15 +1620,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -1624,15 +1640,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -1656,9 +1672,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1666,12 +1682,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.0", ] [[package]] @@ -1707,10 +1723,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -1732,9 +1750,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.185" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libm" @@ -1778,25 +1796,24 @@ checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" +checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" dependencies = [ "hashbrown 0.16.1", ] @@ -1837,14 +1854,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" dependencies = [ "cfg-if", - "digest 0.11.2", + "digest 0.11.3", ] [[package]] name = "memchr" -version = "2.7.5" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "miniz_oxide" @@ -1878,16 +1895,16 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand 0.8.5", + "rand 0.8.6", "smallvec", "zeroize", ] [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-integer" @@ -1930,15 +1947,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "openssl-probe" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "outref" @@ -1965,9 +1982,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -1975,15 +1992,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.17", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -2003,15 +2020,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pin-utils" @@ -2064,9 +2081,9 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -2187,9 +2204,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -2198,9 +2215,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -2232,7 +2249,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] @@ -2255,9 +2272,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] @@ -2296,7 +2313,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", @@ -2323,7 +2340,7 @@ dependencies = [ "md-5 0.10.6", "once_cell", "paste", - "rand 0.8.5", + "rand 0.8.6", "rc4", "serde", "serde_json", @@ -2381,16 +2398,16 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.31" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.4", + "rustls-webpki 0.103.13", "subtle", "zeroize", ] @@ -2409,9 +2426,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.12.0" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ "zeroize", ] @@ -2428,9 +2445,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "aws-lc-rs", "ring", @@ -2440,9 +2457,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -2452,9 +2469,9 @@ checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -2491,9 +2508,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.5.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags", "core-foundation", @@ -2504,9 +2521,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", @@ -2592,7 +2609,7 @@ checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" dependencies = [ "cfg-if", "cpufeatures 0.3.0", - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -2614,7 +2631,7 @@ checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", "cpufeatures 0.3.0", - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -2625,10 +2642,11 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.5" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -2654,9 +2672,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "simplelog" @@ -2671,9 +2689,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" @@ -2856,7 +2874,7 @@ dependencies = [ "memchr", "once_cell", "percent-encoding", - "rand 0.8.5", + "rand 0.8.6", "rsa", "serde", "sha1 0.10.6", @@ -2896,7 +2914,7 @@ dependencies = [ "md-5 0.10.6", "memchr", "once_cell", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", "sha2 0.10.9", @@ -3002,18 +3020,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -3022,9 +3040,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.41" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", @@ -3032,22 +3050,22 @@ dependencies = [ "num-conv", "num_threads", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -3055,9 +3073,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -3080,9 +3098,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.51.1" +version = "1.52.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" +checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" dependencies = [ "bytes", "libc", @@ -3122,7 +3140,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.31", + "rustls 0.23.40", "tokio", ] @@ -3145,7 +3163,7 @@ checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" dependencies = [ "futures-util", "log", - "rustls 0.23.31", + "rustls 0.23.40", "rustls-native-certs", "rustls-pki-types", "tokio", @@ -3234,11 +3252,11 @@ checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ "bytes", "data-encoding", - "http 1.3.1", + "http 1.4.0", "httparse", "log", - "rand 0.9.2", - "rustls 0.23.31", + "rand 0.9.4", + "rustls 0.23.40", "rustls-pki-types", "sha1 0.10.6", "thiserror", @@ -3247,9 +3265,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.18.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "unicode-bidi" @@ -3259,9 +3277,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-normalization" @@ -3286,45 +3304,46 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "3.1.4" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cb1dbab692d82a977c0392ffac19e188bd9186a9f32806f0aaa859d75585a" +checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" dependencies = [ "base64", "cookie_store", "flate2", "log", "percent-encoding", - "rustls 0.23.31", + "rustls 0.23.40", "rustls-pki-types", "serde", "serde_json", "ureq-proto", - "utf-8", + "utf8-zero", "webpki-roots", ] [[package]] name = "ureq-proto" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2" +checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" dependencies = [ "base64", - "http 1.3.1", + "http 1.4.0", "httparse", "log", ] [[package]] name = "url" -version = "2.5.4" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -3339,6 +3358,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-zero" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -3347,9 +3372,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.23.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ "js-sys", "wasm-bindgen", @@ -3399,9 +3424,9 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ "wit-bindgen", ] @@ -3414,35 +3439,22 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3450,31 +3462,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn 2.0.117", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" dependencies = [ "unicode-ident", ] [[package]] name = "webpki-roots" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" dependencies = [ "rustls-pki-types", ] @@ -3491,31 +3503,31 @@ dependencies = [ [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "windows-core" -version = "0.61.2" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link 0.1.3", + "windows-link", "windows-result", "windows-strings", ] [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -3524,21 +3536,15 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", "syn 2.0.117", ] -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - [[package]] name = "windows-link" version = "0.2.1" @@ -3547,20 +3553,20 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-result" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] @@ -3581,22 +3587,13 @@ dependencies = [ "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]] name = "windows-sys" version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -3722,9 +3719,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "wit-bindgen" -version = "0.51.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "writeable" @@ -3740,9 +3737,9 @@ checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -3751,9 +3748,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -3763,18 +3760,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", @@ -3792,9 +3789,9 @@ dependencies = [ [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -3804,15 +3801,15 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -3821,9 +3818,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -3832,9 +3829,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 432fc03..d0172c2 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,400 +1,27 @@ +#![allow(dead_code)] mod protos; +mod rmc_struct; +mod util; extern crate proc_macro; -use crate::protos::{ProtoMethodData, RmcProtocolData}; +use crate::protos::{ProtoInputParams, RmcProtocolData}; +use crate::rmc_struct::{rmc_serialize_enum, rmc_serialize_struct}; use proc_macro::TokenStream; -use proc_macro2::{Ident, Literal, Span}; -use quote::{quote, TokenStreamExt}; -use syn::parse::{Parse, ParseStream}; -use syn::punctuated::Punctuated; +use proc_macro2::Ident; +use quote::quote; use syn::spanned::Spanned; -use syn::{ - parse_macro_input, Attribute, Data, DataStruct, DeriveInput, Fields, FnArg, Lit, LitInt, - LitStr, Pat, Token, TraitItem, -}; - -struct ProtoInputParams { - proto_num: LitInt, - properties: Option<(Token![,], Punctuated)>, -} - -impl Parse for ProtoInputParams { - fn parse(input: ParseStream) -> syn::Result { - let proto_num = input.parse()?; - - if let Some(seperator) = input.parse()? { - let mut punctuated = Punctuated::new(); - loop { - punctuated.push_value(input.parse()?); - if let Some(punct) = input.parse()? { - punctuated.push_punct(punct); - } else { - return Ok(Self { - proto_num, - properties: Some((seperator, punctuated)), - }); - } - } - } else { - Ok(Self { - proto_num, - properties: None, - }) - } - } -} - -fn gen_serialize_data_struct( - s: DataStruct, - struct_attr: Option<&Attribute>, -) -> ( - proc_macro2::TokenStream, - proc_macro2::TokenStream, - proc_macro2::TokenStream, -) { - let serialize_base_content = { - let mut serialize_content = quote! {}; - - for f in &s.fields { - if f.attrs.iter().any(|a| { - a.path().segments.len() == 1 - && a.path() - .segments - .first() - .is_some_and(|p| p.ident.to_string() == "extends") - }) { - continue; - } - let ident = f.ident.as_ref().unwrap(); - - serialize_content.append_all(quote! { - rnex_core::rmc::structures::RmcSerialize::serialize(&self.#ident, writer)?; - }) - } - - quote! { - #serialize_content - - Ok(()) - } - }; - - let struct_ctor = { - let mut structure_content = quote! {}; - for f in &s.fields { - let ident = f.ident.as_ref().unwrap(); - - structure_content.append_all(quote! {#ident, }); - } - - quote! { - Ok(Self{ - #structure_content - }) - } - }; - - let deserialize_base_content = { - let mut deserialize_content = quote! {}; - - for f in &s.fields { - if f.attrs.iter().any(|a| { - a.path().segments.len() == 1 - && a.path() - .segments - .first() - .is_some_and(|p| p.ident.to_string() == "extends") - }) { - continue; - } - - let ident = f.ident.as_ref().unwrap(); - let ty = &f.ty; - - deserialize_content.append_all(quote! { - let #ident = <#ty> :: deserialize(reader)?; - }) - } - - quote! { - #deserialize_content - #struct_ctor - } - }; - - let write_size = { - let mut size_content = quote! { 0 }; - - for f in &s.fields { - let ident = f.ident.as_ref().unwrap(); - - size_content.append_all(quote! { - + rnex_core::rmc::structures::RmcSerialize::serialize_write_size(&self.#ident)? - }) - } - - size_content - }; - let write_size = if let Some(_) = struct_attr { - quote! { #write_size + if rnex_core::config::FEATURE_HAS_STRUCT_HEADER{ 5 } else { 0 } } - } else { - write_size - }; - - // generate base with extends stuff - - let serialize_base_content = if let Some(attr) = struct_attr { - let version: Literal = attr.parse_args().expect("has to be a literal"); - - let pre_inner = if let Some(f) = s.fields.iter().find(|f| { - f.attrs.iter().any(|a| { - a.path().segments.len() == 1 - && a.path() - .segments - .first() - .is_some_and(|p| p.ident.to_string() == "extends") - }) - }) { - let ident = f.ident.as_ref().unwrap(); - quote! { - self.#ident.serialize(writer)?; - } - } else { - quote! {} - }; - - quote! { - #pre_inner - rnex_core::rmc::structures::rmc_struct::write_struct( - writer, - #version, - rnex_core::rmc::structures::helpers::len_of_write( - |writer|{ - #serialize_base_content - } - ), - |writer|{ - #serialize_base_content - } - )?; - - Ok(()) - } - } else { - serialize_base_content - }; - - let deserialize_base_content = if let Some(attr) = struct_attr { - let version: Literal = attr.parse_args().expect("has to be a literal"); - - let pre_inner = if let Some(f) = s.fields.iter().find(|f| { - f.attrs.iter().any(|a| { - a.path().segments.len() == 1 - && a.path() - .segments - .first() - .is_some_and(|p| p.ident.to_string() == "extends") - }) - }) { - let ident = f.ident.as_ref().unwrap(); - let ty = &f.ty; - quote! { - let #ident = <#ty> :: deserialize(reader)?; - } - } else { - quote! {} - }; - - quote! { - #pre_inner - Ok(rnex_core::rmc::structures::rmc_struct::read_struct(reader, #version, move |mut reader|{ - #deserialize_base_content - })?) - } - } else { - deserialize_base_content - }; - - let write_size = quote! { - fn serialize_write_size(&self) -> rnex_core::rmc::structures::Result{ - Ok(#write_size) - } - }; - - (serialize_base_content, deserialize_base_content, write_size) -} +use syn::{parse_macro_input, Data, DeriveInput, Lit, LitStr}; #[proc_macro_derive(RmcSerialize, attributes(extends, rmc_struct))] pub fn rmc_serialize(input: TokenStream) -> TokenStream { let derive_input = parse_macro_input!(input as DeriveInput); - let struct_attr = derive_input.attrs.iter().find(|a| { - a.path().segments.len() == 1 - && a.path() - .segments - .first() - .is_some_and(|p| p.ident.to_string() == "rmc_struct") - }); - let repr_attr = derive_input.attrs.iter().find(|a| { - a.path().segments.len() == 1 - && a.path() - .segments - .first() - .is_some_and(|p| p.ident.to_string() == "repr") - }); - - /*let Data::Struct(s) = derive_input.data else { - panic!("rmc struct type MUST be a struct"); - };*/ - - let (serialize_base_content, deserialize_base_content, write_size) = match derive_input.data { - Data::Struct(s) => gen_serialize_data_struct(s, struct_attr), - Data::Enum(e) => { - let Some(repr_attr) = repr_attr else { - panic!("missing repr attribute"); - }; - - let ty: Ident = repr_attr.parse_args().unwrap(); - - let mut inner_match_de = quote! {}; - let mut inner_match_se = quote! {}; - //let mut inner_match_len = quote!{}; - - for variant in e.variants { - let Some((_, val)) = variant.discriminant else { - panic!("missing discriminant"); - }; - - let field_data_de = match &variant.fields { - Fields::Named(v) => { - let mut base = quote! {}; - for field in v.named.iter() { - let ty = &field.ty; - let name = &field.ident; - - base.append_all(quote!{ - #name: <#ty as rnex_core::rmc::structures::RmcSerialize>::deserialize(reader)?, - }); - } - - quote! {{#base}} - } - Fields::Unnamed(n) => { - let mut base = quote! {}; - - for field in n.unnamed.iter() { - let ty = &field.ty; - - base.append_all(quote!{ - <#ty as rnex_core::rmc::structures::RmcSerialize>::deserialize(reader)?, - }); - } - - quote! {(#base)} - } - Fields::Unit => { - quote! {} - } - }; - - let mut se_with_fields = quote! { - <#ty as rnex_core::rmc::structures::RmcSerialize>::serialize(&#val, writer)?; - }; - - match &variant.fields { - Fields::Named(v) => { - for field in v.named.iter() { - let ty = &field.ty; - let name = &field.ident; - - se_with_fields.append_all(quote!{ - <#ty as rnex_core::rmc::structures::RmcSerialize>::serialize(#name ,writer)?; - }); - } - } - Fields::Unnamed(n) => { - for (i, field) in n.unnamed.iter().enumerate() { - let ty = &field.ty; - - let ident = Ident::new(&format!("val_{}", i), Span::call_site()); - - se_with_fields.append_all(quote!{ - <#ty as rnex_core::rmc::structures::RmcSerialize>::serialize(#ident, writer)?; - }); - } - } - Fields::Unit => {} - }; - - let field_match_se = match &variant.fields { - Fields::Named(v) => { - let mut base = quote! {}; - - for field in v.named.iter() { - let name = &field.ident; - - base.append_all(quote! { - #name, - }); - } - - quote! {{#base}} - } - Fields::Unnamed(n) => { - let mut base = quote! {}; - - for (i, _field) in n.unnamed.iter().enumerate() { - let ident = Ident::new(&format!("val_{}", i), Span::call_site()); - - base.append_all(quote! { - #ident, - }); - } - - quote! {(#base)} - } - Fields::Unit => { - quote! {} - } - }; - - let name = variant.ident; - - inner_match_de.append_all(quote! { - #val => Self::#name #field_data_de, - }); - - inner_match_se.append_all(quote! { - Self::#name #field_match_se => { - #se_with_fields - }, - }); - } - - let serialize_base_content = quote! { - match self{ - #inner_match_se - }; - - - - Ok(()) - }; - - let deserialize_base_content = quote! { - let val: Self = match <#ty as rnex_core::rmc::structures::RmcSerialize>::deserialize(reader)?{ - #inner_match_de - v => return Err(rnex_core::rmc::structures::Error::UnexpectedValue(v as _)) - }; - - Ok(val) - }; - - (serialize_base_content, deserialize_base_content, quote! {}) - } + let (serialize, deserialize, write_size, version) = match &derive_input.data { + Data::Struct(s) => rmc_serialize_struct(s, &derive_input), + Data::Enum(e) => rmc_serialize_enum(e, &derive_input), Data::Union(_) => { - unimplemented!() + unimplemented!("serialize a union is not allowed"); } }; @@ -406,19 +33,41 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { )); let ident = derive_input.ident; + let write_size = if let Some(v) = write_size { + quote! { + fn serialize_write_size(&self) -> rnex_core::rmc::structures::Result{ + #v + } + } + } else { + quote! {} + }; + + let version = if let Some(v) = version { + quote! { + fn version() -> Option{ + #v + } + } + } else { + quote! {} + }; + let tokens = quote! { impl rnex_core::rmc::structures::RmcSerialize for #ident{ #[inline(always)] fn serialize(&self, writer: &mut impl ::std::io::Write) -> rnex_core::rmc::structures::Result<()>{ - #serialize_base_content + #serialize } #[inline(always)] fn deserialize(reader: &mut impl ::std::io::Read) -> rnex_core::rmc::structures::Result{ - #deserialize_base_content + #deserialize } #write_size + #version + fn name() -> &'static str{ #str_name } @@ -455,71 +104,9 @@ pub fn rmc_serialize(input: TokenStream) -> TokenStream { #[proc_macro_attribute] pub fn rmc_proto(attr: TokenStream, input: TokenStream) -> TokenStream { let params = parse_macro_input!(attr as ProtoInputParams); - - let ProtoInputParams { - proto_num, - properties, - } = params; - - let no_return_data = - properties.is_some_and(|p| p.1.iter().any(|i| i.to_string() == "NoReturn")); - let input = parse_macro_input!(input as syn::ItemTrait); - // gigantic ass struct initializer (to summarize this gets all of the data) - let raw_data = RmcProtocolData { - has_returns: !no_return_data, - name: input.ident.clone(), - id: proto_num, - methods: input - .items - .iter() - .filter_map(|v| match v { - TraitItem::Fn(v) => Some(v), - _ => None, - }) - .map(|func| { - let Some(attr) = func.attrs.iter().find(|a| { - a.path() - .segments - .last() - .is_some_and(|s| s.ident.to_string() == "method_id") - }) else { - panic!("every function inside of an rmc protocol must have a method id"); - }; - - let Ok(id): Result = attr.parse_args() else { - panic!("todo: put a propper error message here"); - }; - - let funcs = func - .sig - .inputs - .iter() - .skip(1) - .map(|f| { - let FnArg::Typed(t) = f else { - panic!("what"); - }; - let Pat::Ident(i) = &*t.pat else { - panic!( - "unable to handle non identifier patterns as parameter bindings" - ); - }; - - (i.ident.clone(), t.ty.as_ref().clone()) - }) - .collect(); - - ProtoMethodData { - id, - name: func.sig.ident.clone(), - parameters: funcs, - ret_val: func.sig.output.clone(), - } - }) - .collect(), - }; + let raw_data = RmcProtocolData::new(params, &input); quote! { #input diff --git a/macros/src/protos.rs b/macros/src/protos.rs index f7e7d0d..3171598 100644 --- a/macros/src/protos.rs +++ b/macros/src/protos.rs @@ -1,12 +1,48 @@ use proc_macro2::{Ident, Span, TokenStream}; use quote::{quote, ToTokens}; -use syn::token::{Brace, Paren, Semi}; -use syn::{LitInt, LitStr, ReturnType, Type}; +use syn::{ + parse::{Parse, ParseStream}, + punctuated::Punctuated, + Attribute, FnArg, ItemTrait, LitInt, LitStr, Meta, Pat, ReturnType, Token, TraitItem, Type, +}; +use crate::util::fold_tokenable; + +pub struct ProtoInputParams { + proto_num: LitInt, + properties: Option<(Token![,], Punctuated)>, +} + +impl Parse for ProtoInputParams { + fn parse(input: ParseStream) -> syn::Result { + let proto_num = input.parse()?; + + if let Some(seperator) = input.parse()? { + let mut punctuated = Punctuated::new(); + loop { + punctuated.push_value(input.parse()?); + if let Some(punct) = input.parse()? { + punctuated.push_punct(punct); + } else { + return Ok(Self { + proto_num, + properties: Some((seperator, punctuated)), + }); + } + } + } else { + Ok(Self { + proto_num, + properties: None, + }) + } + } +} pub struct ProtoMethodData { pub id: LitInt, pub name: Ident, - pub parameters: Vec<(Ident, Type)>, + pub attributes: Vec, + pub parameters: Vec<(Ident, Type, Vec)>, pub ret_val: ReturnType, } @@ -23,108 +59,222 @@ pub struct RmcProtocolData { } impl RmcProtocolData { - fn generate_raw_trait(&self, tokens: &mut TokenStream) { + pub fn new(params: ProtoInputParams, input: &ItemTrait) -> Self { + let ProtoInputParams { + proto_num, + properties, + } = params; + + let no_return_data = + properties.is_some_and(|p| p.1.iter().any(|i| i.to_string() == "NoReturn")); + + // gigantic ass struct initializer (to summarize this gets all of the data) + RmcProtocolData { + has_returns: !no_return_data, + name: input.ident.clone(), + id: proto_num, + methods: input + .items + .iter() + .filter_map(|v| match v { + TraitItem::Fn(v) => Some(v), + _ => None, + }) + .map(|func| { + let Some(attr) = func.attrs.iter().find(|a| { + a.path() + .segments + .last() + .is_some_and(|s| s.ident.to_string() == "method_id") + }) else { + panic!("every function inside of an rmc protocol must have a method id"); + }; + + let Ok(id): Result = attr.parse_args() else { + panic!("todo: put a propper error message here"); + }; + + let funcs = func + .sig + .inputs + .iter() + .skip(1) + .map(|f| { + let FnArg::Typed(t) = f else { + panic!("what"); + }; + let Pat::Ident(i) = &*t.pat else { + panic!( + "unable to handle non identifier patterns as parameter bindings" + ); + }; + + (i.ident.clone(), t.ty.as_ref().clone(), t.attrs.clone()) + }) + .collect(); + + ProtoMethodData { + id, + name: func.sig.ident.clone(), + parameters: funcs, + ret_val: func.sig.output.clone(), + attributes: func + .attrs + .iter() + .filter(|a| match &a.meta { + Meta::NameValue(v) => { + if let Some(i) = v.path.get_ident() { + i.to_string() != "doc" + } else { + true + } + } + Meta::List(l) => { + if let Some(seg) = l.path.segments.last() { + seg.ident.to_string() != "method_id" + } else { + true + } + } + _ => true, + }) + .cloned() + .collect(), + } + }) + .collect(), + } + } + + fn generate_raw_trait(&self) -> TokenStream { let Self { has_returns, name, id, methods, } = self; + let generate_raw_method = |method: &ProtoMethodData| -> TokenStream { + let ProtoMethodData { + name, + parameters, + attributes, + .. + } = method; - // this gives us the name which the identifier of the corresponding Raw trait - let raw_name = Ident::new(&format!("Raw{}", name), name.span()); + let attribs = fold_tokenable(attributes.iter()); - // boilerplate tokens which all raw traits need - quote! { - #[doc(hidden)] - #[allow(unused_must_use)] - pub trait #raw_name: #name - } - .to_tokens(tokens); + let raw_name = Ident::new(&format!("raw_{}", name), name.span()); - // generate the body of the raw protocol trait - Brace::default().surround(tokens, |tokens|{ - //generate each raw method - for method in methods{ - let ProtoMethodData { - name, - parameters, - .. - } = method; + let optional_return = if self.has_returns { + quote! { + -> ::core::result::Result, ::rnex_core::rmc::response::ErrorCode> + } + } else { + quote! {} + } + .into_token_stream(); - let raw_name = Ident::new(&format!("raw_{}", name), name.span()); - quote!{ - #[inline(always)] - async fn #raw_name - }.to_tokens(tokens); - - Paren::default().surround(tokens, |tokens|{ - quote!{ &self, data: ::std::vec::Vec }.to_tokens(tokens); - }); - - if self.has_returns { + let deser_params = + fold_tokenable(parameters.iter().map(|(param_name, param_type, attribs)| { + let error_msg = LitStr::new( + &format!("an error occurred whilest deserializing {}", param_name), + Span::call_site(), + ); + let return_from_deser_error = if self.has_returns { + quote! { + return Err(::rnex_core::rmc::response::ErrorCode::Core_InvalidArgument); + } + } else { + quote! { + return; + } + }; + let attribs = fold_tokenable(attribs.iter()); quote! { - -> ::core::result::Result, ErrorCode> - }.to_tokens(tokens); + #attribs + let Ok(#param_name) = + <#param_type as rnex_core::rmc::structures::RmcSerialize>::deserialize( + &mut cursor + ) else{ + log::error!(#error_msg); + #return_from_deser_error + }; + } + })); + + let call_params = fold_tokenable(parameters.iter().map(|(param_name, _, attribs)| { + let attribs = fold_tokenable(attribs.iter()); + quote! { + #attribs + #param_name, + } + })); + + let optional_method_return = if *has_returns { + quote! { + let retval = retval?; + let mut vec = Vec::new(); + rnex_core::rmc::structures::RmcSerialize::serialize(&retval, &mut vec).ok(); + Ok(vec) + } + } else { + quote! {} + }; + + quote! { + #[inline(always)] + #attribs + async fn #raw_name (&self, data: ::std::vec::Vec) #optional_return{ + let mut cursor = ::std::io::Cursor::new(data); + #deser_params + let retval = self.#name(#call_params).await; + #optional_method_return } - Brace::default().surround(tokens, |tokens|{ - quote! { let mut cursor = ::std::io::Cursor::new(data); }.to_tokens(tokens); - - for (param_name, param_type) in parameters{ - quote!{ - let Ok(#param_name) = - <#param_type as rnex_core::rmc::structures::RmcSerialize>::deserialize( - &mut cursor - ) else - }.to_tokens(tokens); - - let error_msg = LitStr::new(&format!("an error occurred whilest deserializing {}", param_name), Span::call_site()); - - if self.has_returns { - quote! { - { - log::error!(#error_msg); - return Err(rnex_core::rmc::response::ErrorCode::Core_InvalidArgument); - }; - }.to_tokens(tokens) - } else { - quote! { - { - log::error!(#error_msg); - return; - }; - }.to_tokens(tokens) - } - - } - - quote!{ - let retval = self.#name - }.to_tokens(tokens); - - Paren::default().surround(tokens, |tokens|{ - for (paren_name, _) in parameters{ - quote!{#paren_name,}.to_tokens(tokens); - } - }); - - quote!{ - .await; - }.to_tokens(tokens); - - if *has_returns{ - quote!{ - let retval = retval?; - let mut vec = Vec::new(); - rnex_core::rmc::structures::RmcSerialize::serialize(&retval, &mut vec).ok(); - Ok(vec) - }.to_tokens(tokens); - } - }) } + }; - quote!{ + let generate_rmc_call_proto = || { + let method_entries = fold_tokenable(methods.iter().map(|m| { + let ProtoMethodData { + id, + name, + attributes, + .. + } = m; + + let attribs = fold_tokenable(attributes.iter()); + let raw_name = Ident::new(&format!("raw_{}", name), name.span()); + + quote! { + #attribs + #id => self.#raw_name(data).await, + } + })); + + let optional_notimpl_return = if self.has_returns { + quote! { + Err(rnex_core::rmc::response::ErrorCode::Core_NotImplemented) + } + } else { + quote! {} + }; + + let optional_result_sendback = if *has_returns { + quote! { + rnex_core::rmc::response::send_result( + remote_response_connection, + ret, + #id, + method_id, + call_id, + ).await + } + } else { + quote! {} + }; + + quote! { #[inline(always)] async fn rmc_call_proto( &self, @@ -132,71 +282,38 @@ impl RmcProtocolData { method_id: u32, call_id: u32, data: Vec, - ) - }.to_tokens(tokens); - - Brace::default().surround(tokens, |tokens|{ - quote! { - let ret = match method_id - }.to_tokens(tokens); - - Brace::default().surround(tokens, |tokens|{ - for method in methods{ - let ProtoMethodData{ - id, - name, - .. - } = method; - - let raw_name = Ident::new(&format!("raw_{}", name), name.span()); - - - quote!{ - #id => self.#raw_name(data).await, - }.to_tokens(tokens); - } - quote!{ - v => - }.to_tokens(tokens); - - - - Brace::default().surround(tokens, |tokens|{ - quote!{ + ){ + let ret = match method_id{ + #method_entries + v => { log::error!("(protocol {})unimplemented method id called on protocol: {}", #id, v); - }.to_tokens(tokens); - if self.has_returns { - quote! { - Err(rnex_core::rmc::response::ErrorCode::Core_NotImplemented) - }.to_tokens(tokens); + #optional_notimpl_return } - }); - - }); - - Semi::default().to_tokens(tokens); - - if *has_returns{ - quote!{ - rnex_core::rmc::response::send_result( - remote_response_connection, - ret, - #id, - method_id, - call_id, - ).await - }.to_tokens(tokens); + }; + #optional_result_sendback } - }); - }); + } + }; + // this gives us the name which the identifier of the corresponding Raw trait + let raw_name = Ident::new(&format!("Raw{}", name), name.span()); + let proto_raw_methods = fold_tokenable(self.methods.iter().map(|m| generate_raw_method(m))); + let rmc_call_proto = generate_rmc_call_proto(); + + // boilerplate tokens which all raw traits need quote! { + #[doc(hidden)] + #[allow(unused_must_use)] + pub trait #raw_name: #name{ + #proto_raw_methods + #rmc_call_proto + } impl #raw_name for T{} } - .to_tokens(tokens); + .to_token_stream() } - fn generate_raw_remote_trait(&self, tokens: &mut TokenStream) { + fn generate_raw_remote_trait(&self) -> TokenStream { let Self { has_returns, name, @@ -207,101 +324,92 @@ impl RmcProtocolData { // this gives us the name which the identifier of the corresponding Raw trait let remote_name = Ident::new(&format!("Remote{}", name), name.span()); + let generate_remote_method = |m: &ProtoMethodData| -> TokenStream { + let ProtoMethodData { + name, + parameters, + ret_val, + attributes, + id: method_id, + } = m; + + let params = fold_tokenable(parameters.iter().map(|(ident, ty, attr)| { + let attrs = fold_tokenable(attr.iter()); + quote! { #attrs #ident: #ty, } + })); + + let optional_questionmark_operator = if self.has_returns { + quote! { + ? + } + } else { + quote! {} + }; + + let param_serialize = fold_tokenable(parameters.iter().map(|(name, ty, attrs)|{ + let attrs = fold_tokenable(attrs.iter()); + quote!{ + #attrs + rnex_core::result::ResultExtension::display_err_or_some( + <#ty as rnex_core::rmc::structures::RmcSerialize>::serialize( + &#name, + &mut cursor + ) + ).ok_or(rnex_core::rmc::response::ErrorCode::Core_InvalidArgument)#optional_questionmark_operator ; + } + })); + + let make_call = if *has_returns { + quote! { + rnex_core::result::ResultExtension::display_err_or_some( + rmc_conn.make_raw_call(&message).await + ).ok_or(rnex_core::rmc::response::ErrorCode::Core_Exception) + } + } else { + quote! { + rnex_core::result::ResultExtension::display_err_or_some( + rmc_conn.make_raw_call_no_response(&message).await + ); + } + }; + + let attribs = fold_tokenable(attributes.iter()); + + quote! { + #attribs + async fn #name(&self, #params) #ret_val{ + let mut send_data = ::std::vec::Vec::new(); + let mut cursor = ::std::io::Cursor::new(&mut send_data); + #param_serialize + + let call_id = rand::random(); + + let message = rnex_core::rmc::message::RMCMessage{ + call_id, + method_id: #method_id, + protocol_id: #proto_id, + rest_of_data: send_data + }; + + let rmc_conn = ::get_connection(self); + + #make_call + } + } + }; + + let remote_methods = fold_tokenable(methods.iter().map(|m| generate_remote_method(m))); - // boilerplate tokens which all raw traits need quote! { #[doc(hidden)] #[allow(unused_must_use)] - pub trait #remote_name: rnex_core::rmc::protocols::HasRmcConnection - } - .to_tokens(tokens); - - // generate the body of the raw protocol trait - Brace::default().surround(tokens, |tokens|{ - //generate each raw method - for method in methods{ - let ProtoMethodData { - name, - parameters, - ret_val, - id: method_id, - .. - } = method; - - quote!{ - async fn #name - }.to_tokens(tokens); - - Paren::default().surround(tokens, |tokens|{ - quote!{ &self, }.to_tokens(tokens); - for (param_ident, param_type) in parameters{ - quote!{ #param_ident: #param_type, }.to_tokens(tokens); - } - }); - - quote!{ - #ret_val - }.to_tokens(tokens); - - Brace::default().surround(tokens, |tokens|{ - quote! { - let mut send_data = Vec::new(); - let mut cursor = ::std::io::Cursor::new(&mut send_data); - }.to_tokens(tokens); - - for (param_name, param_type) in parameters{ - quote!{ - rnex_core::result::ResultExtension::display_err_or_some( - <#param_type as rnex_core::rmc::structures::RmcSerialize>::serialize( - &#param_name, - &mut cursor - ) - ).ok_or(rnex_core::rmc::response::ErrorCode::Core_InvalidArgument) - }.to_tokens(tokens); - if self.has_returns { - quote! { - ?; - }.to_tokens(tokens) - } else { - quote! { - ; - }.to_tokens(tokens) - } - } - - quote!{ - let call_id = rand::random(); - - let message = rnex_core::rmc::message::RMCMessage{ - call_id, - method_id: #method_id, - protocol_id: #proto_id, - rest_of_data: send_data - }; - - let rmc_conn = ::get_connection(self); - }.to_tokens(tokens); - - if *has_returns{ - quote!{ - rnex_core::result::ResultExtension::display_err_or_some( - rmc_conn.make_raw_call(&message).await - ).ok_or(rnex_core::rmc::response::ErrorCode::Core_Exception) - }.to_tokens(tokens); - } else { - quote!{ - rnex_core::result::ResultExtension::display_err_or_some( - rmc_conn.make_raw_call_no_response(&message).await - ); - }.to_tokens(tokens); - } - - }) + pub trait #remote_name: rnex_core::rmc::protocols::HasRmcConnection{ + #remote_methods } - }); + } } - fn generate_raw_info(&self, tokens: &mut TokenStream) { + fn generate_raw_info(&self) -> TokenStream { let Self { name, id, .. } = self; let raw_info_name = Ident::new(&format!("Raw{}Info", name), Span::call_site()); @@ -314,14 +422,13 @@ impl RmcProtocolData { pub const PROTOCOL_ID: u16 = #id; } } - .to_tokens(tokens); } } impl ToTokens for RmcProtocolData { fn to_tokens(&self, tokens: &mut TokenStream) { - self.generate_raw_trait(tokens); - self.generate_raw_info(tokens); - self.generate_raw_remote_trait(tokens); + self.generate_raw_trait().to_tokens(tokens); + self.generate_raw_info().to_tokens(tokens); + self.generate_raw_remote_trait().to_tokens(tokens); } } diff --git a/macros/src/rmc_struct.rs b/macros/src/rmc_struct.rs new file mode 100644 index 0000000..66f9515 --- /dev/null +++ b/macros/src/rmc_struct.rs @@ -0,0 +1,426 @@ +use proc_macro2::{Literal, Span, TokenStream}; +use quote::quote; +use syn::{ + bracketed, parse::Parse, punctuated::Punctuated, token::Bracket, DataEnum, DataStruct, + DeriveInput, Field, Fields, Ident, Meta, Token, Variant, +}; + +use crate::util::fold_tokenable; + +struct RmcStructAttrVersion { + bracket: Bracket, + delim: Token![,], + feature_name: Literal, + struct_version: Literal, +} + +struct RmcStructAttr { + base_ver: Literal, + versions: Option<(Token![,], Punctuated)>, +} + +impl Parse for RmcStructAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let base_ver = input.parse()?; + + if let Some(seperator) = input.parse()? { + let mut punctuated = Punctuated::new(); + loop { + punctuated.push_value(input.parse()?); + if let Some(punct) = input.parse()? { + punctuated.push_punct(punct); + } else { + return Ok(Self { + base_ver, + versions: Some((seperator, punctuated)), + }); + } + } + } else { + Ok(Self { + base_ver, + versions: None, + }) + } + } +} + +impl RmcStructAttr { + fn versions(&self) -> impl Iterator { + self.versions.iter().flat_map(|v| v.1.iter()) + } +} + +impl Parse for RmcStructAttrVersion { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let content; + let bracket = bracketed!(content in input); + let (feature_name, delim, struct_version) = + content.call(|s| Ok((s.parse()?, s.parse()?, s.parse()?)))?; + + Ok(Self { + bracket, + delim, + feature_name, + struct_version, + }) + } +} + +pub fn generate_write_size_struct( + s: &DataStruct, + with_potential_header: bool, +) -> proc_macro2::TokenStream { + // this is fine and works because of a quirk where the sizes of the structs dont change + // if we ignore wether or not a struct extends the other struct or has it as a field + + let base_size = fold_tokenable(s.fields.iter().map(|f| { + let ident = f.ident.as_ref().unwrap(); + let attrs = fold_tokenable(f.attrs.iter().filter(|a| { + if let Some(i) = a.meta.path().get_ident() { + i.to_string() != "extends" + } else { + true + } + })); + quote! { + #attrs + sum += rnex_core::rmc::structures::RmcSerialize::serialize_write_size(&self.#ident)?; + } + })); + let optional_struct_header_calc = if with_potential_header { + quote! { sum += (if rnex_core::config::FEATURE_HAS_STRUCT_HEADER{ 5 } else { 0 }); } + } else { + quote! {} + }; + quote! { + let mut sum = 0; + #base_size + #optional_struct_header_calc + Ok(sum) + } +} +pub fn generate_serialize_struct( + extended_struct: Option<&Field>, + elems: &[&Field], + with_header: bool, +) -> proc_macro2::TokenStream { + fn gen_elem_serialize(f: &Field) -> TokenStream { + let ident = f.ident.as_ref().unwrap(); + let attrs = fold_tokenable(f.attrs.iter().filter(|a| { + if let Some(i) = a.meta.path().get_ident() { + i.to_string() != "extends" + } else { + true + } + })); + quote! { + #attrs + rnex_core::rmc::structures::RmcSerialize::serialize(&self.#ident, writer)?; + } + } + let optional_extended_struct = if let Some(f) = extended_struct { + gen_elem_serialize(f) + } else { + quote! {} + }; + let elems = fold_tokenable(elems.iter().map(|e| gen_elem_serialize(e))); + let ser_body = if with_header { + quote! { + rnex_core::rmc::structures::rmc_struct::write_struct( + writer, + Self::version().unwrap(), + rnex_core::rmc::structures::helpers::len_of_write( + |writer|{ + #elems + Ok(()) + } + ), + |writer|{ + #elems + Ok(()) + } + )?; + } + } else { + elems + }; + + quote! { + #optional_extended_struct + #ser_body + Ok(()) + } +} +pub fn generate_deserialize_struct( + s: &DataStruct, + extended_struct: Option<&Field>, + elems: &[&Field], + with_header: bool, +) -> proc_macro2::TokenStream { + fn gen_elem_serialize(f: &Field) -> TokenStream { + let ident = f.ident.as_ref().unwrap(); + let ty = &f.ty; + let attrs = fold_tokenable(f.attrs.iter().filter(|a| { + if let Some(i) = a.meta.path().get_ident() { + i.to_string() != "extends" + } else { + true + } + })); + quote! { + #attrs + let #ident: #ty = rnex_core::rmc::structures::RmcSerialize::deserialize(reader)?; + } + } + let optional_extended_struct = if let Some(f) = extended_struct { + gen_elem_serialize(f) + } else { + quote! {} + }; + let elems = fold_tokenable(elems.iter().map(|e| gen_elem_serialize(e))); + let struct_ctor_content = fold_tokenable(s.fields.iter().map(|f| { + let ident = f.ident.as_ref().unwrap(); + let attrs = fold_tokenable(f.attrs.iter().filter(|a| { + if let Some(i) = a.meta.path().get_ident() { + i.to_string() != "extends" + } else { + true + } + })); + quote! { #attrs #ident, } + })); + let de_body_inner = quote! { + #elems + Ok(Self{ + #struct_ctor_content + }) + }; + let de_body = if with_header { + quote! { + Ok(rnex_core::rmc::structures::rmc_struct::read_struct(reader, Self::version().unwrap(), move |mut reader|{ + #de_body_inner + })?) + } + } else { + de_body_inner + }; + + quote! { + #optional_extended_struct + #de_body + } +} + +fn generate_struct_version(attr: Option<&RmcStructAttr>) -> proc_macro2::TokenStream { + if let Some(attr) = attr { + let base_ver = &attr.base_ver; + let if_else_chain = fold_tokenable(attr.versions().map(|v| { + let version_val = &v.struct_version; + let feature = &v.feature_name; + quote! { + if cfg!(feature = #feature){ + #version_val + } else + } + })); + + quote! { + Some(#if_else_chain { + #base_ver + }) + } + } else { + quote! { None } + } +} + +pub fn rmc_serialize_struct( + s: &DataStruct, + derive_input: &DeriveInput, +) -> ( + proc_macro2::TokenStream, + proc_macro2::TokenStream, + Option, + Option, +) { + let struct_attr = derive_input.attrs.iter().find(|a| { + a.path().segments.len() == 1 + && a.path() + .segments + .first() + .is_some_and(|p| p.ident.to_string() == "rmc_struct") + && matches!(a.meta, Meta::List(_)) + }); + + let struct_attr: Option = struct_attr.map(|a| a.parse_args().unwrap()); + let struct_attr = struct_attr.as_ref(); + + let extended_struct = s.fields.iter().find(|f| { + f.attrs.iter().any(|a| { + a.path().segments.len() == 1 + && a.path() + .segments + .first() + .is_some_and(|p| p.ident.to_string() == "extends") + }) + }); + let elements: Vec<_> = s + .fields + .iter() + .filter(|f| { + !f.attrs.iter().any(|a| { + a.path().segments.len() == 1 + && a.path() + .segments + .first() + .is_some_and(|p| p.ident.to_string() == "extends") + }) + }) + .collect(); + let elements = &elements[..]; + + let serialize = generate_serialize_struct(extended_struct, elements, struct_attr.is_some()); + let deserialize = + generate_deserialize_struct(s, extended_struct, elements, struct_attr.is_some()); + let write_size = generate_write_size_struct(s, struct_attr.is_some()); + let version = generate_struct_version(struct_attr); + + (serialize, deserialize, Some(write_size), Some(version)) +} + +fn field_to_ident(field: &Field, idx: usize) -> Ident { + if let Some(i) = &field.ident { + i.clone() + } else { + Ident::new(&format!("field_{}", idx), Span::call_site()) + } +} + +fn variant_to_pattern_and_fields(variant: &Variant) -> (proc_macro2::TokenStream, Vec) { + match &variant.fields { + Fields::Named(n) => { + let inner = n + .named + .iter() + .map(|f| { + let attrs = fold_tokenable(f.attrs.iter()); + let ident = f.ident.as_ref().unwrap(); + + quote! { #attrs #ident } + }) + .reduce(|a, b| quote! {#a, #b}); + + (quote! {{#inner}}, n.named.iter().cloned().collect()) + } + Fields::Unnamed(n) => { + let inner = n + .unnamed + .iter() + .enumerate() + .map(|(i, f)| { + let attrs = fold_tokenable(f.attrs.iter()); + let name = field_to_ident(f, i); + + quote! { #attrs #name } + }) + .reduce(|a, b| quote! {#a, #b}); + + (quote! {(#inner)}, n.unnamed.iter().cloned().collect()) + } + Fields::Unit => (quote! {}, vec![]), + } +} + +pub fn rmc_generate_serialize_enum( + enum_data: &DataEnum, + repr_ty: &Ident, +) -> proc_macro2::TokenStream { + let match_content = fold_tokenable(enum_data.variants.iter().map(|v|{ + let ident = &v.ident; + let descriminant = &v.discriminant.as_ref().expect("every variant must have a descriminant to be a valid rmc struct").1; + let (pattern, fields) = variant_to_pattern_and_fields(v); + let inner = fold_tokenable(fields.iter().enumerate().map(|(i, f)|{ + let ty = &f.ty; + let name = field_to_ident(&f, i); + quote! {<#ty as rnex_core::rmc::structures::RmcSerialize>::serialize(#name, writer)?;} + })); + quote!{ + Self::#ident #pattern => { + <#repr_ty as rnex_core::rmc::structures::RmcSerialize>::serialize(&#descriminant, writer)?; + #inner + } + } + })); + quote! { + match self{ + #match_content + } + Ok(()) + } +} +pub fn rmc_generate_deserialize_enum( + enum_data: &DataEnum, + repr_ty: &Ident, +) -> proc_macro2::TokenStream { + let match_content = fold_tokenable(enum_data.variants.iter().map(|v| { + let ident = &v.ident; + let descriminant = &v + .discriminant + .as_ref() + .expect("every variant must have a descriminant to be a valid rmc struct") + .1; + let (pattern, fields) = variant_to_pattern_and_fields(v); + let inner = fold_tokenable(fields.iter().enumerate().map(|(i, f)| { + let ty = &f.ty; + let name = field_to_ident(&f, i); + quote! {let #name = <#ty as rnex_core::rmc::structures::RmcSerialize>::deserialize(reader)?;} + })); + quote! { + #descriminant => { + #inner + + Self::#ident #pattern + } + } + })); + + quote! { + let discriminant = <#repr_ty as rnex_core::rmc::structures::RmcSerialize>::deserialize(reader)?; + + Ok(match discriminant{ + #match_content + v => { + return Err(rnex_core::rmc::structures::Error::UnexpectedValue(v as u64)) + } + }) + } +} + +pub fn rmc_serialize_enum( + enum_data: &DataEnum, + derive_input: &DeriveInput, +) -> ( + proc_macro2::TokenStream, + proc_macro2::TokenStream, + Option, + Option, +) { + let repr_attr = derive_input.attrs.iter().find(|a| { + a.path().segments.len() == 1 + && a.path() + .segments + .first() + .is_some_and(|p| p.ident.to_string() == "repr") + }); + let Some(repr_attr) = repr_attr else { + panic!("missing repr attribute"); + }; + + let ty: Ident = repr_attr.parse_args().unwrap(); + + let serialize = rmc_generate_serialize_enum(&enum_data, &ty); + let deserialize = rmc_generate_deserialize_enum(&enum_data, &ty); + + (serialize, deserialize, None, None) +} diff --git a/macros/src/util.rs b/macros/src/util.rs new file mode 100644 index 0000000..133f650 --- /dev/null +++ b/macros/src/util.rs @@ -0,0 +1,10 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; + +// todo: return a wrapper struct implementing ToTokens over the iterator instead as to avoid unnescesary allocations with the token stream +pub fn fold_tokenable(list: impl Iterator) -> TokenStream { + list.fold(TokenStream::new(), |mut s, i| { + i.to_tokens(&mut s); + s + }) +} diff --git a/proxy-common/src/lib.rs b/proxy-common/src/lib.rs index d5ef302..f614de1 100644 --- a/proxy-common/src/lib.rs +++ b/proxy-common/src/lib.rs @@ -210,6 +210,7 @@ pub async fn new_backend_connection( mod test { use crate::{VIRTUAL_PORT_INSECURE, VIRTUAL_PORT_SECURE}; + #[test] fn test_virtual_port_correct() { println!("{:?}", VIRTUAL_PORT_INSECURE); println!("{:?}", VIRTUAL_PORT_SECURE); diff --git a/prudpv1/src/prudp/packet.rs b/prudpv1/src/prudp/packet.rs index 60e3feb..027c0b4 100644 --- a/prudpv1/src/prudp/packet.rs +++ b/prudpv1/src/prudp/packet.rs @@ -447,7 +447,7 @@ mod test { let bytes = &bytes[0x6..]; - let header_data: [u8; 8] = bytes.try_into().unwrap(); + let _: [u8; 8] = bytes.try_into().unwrap(); } #[test] diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 3917b72..974c869 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -40,9 +40,7 @@ use cfg_if::cfg_if; use log::{error, info}; use macros::rmc_struct; use rnex_core::prudp::socket_addr::PRUDPSockAddr; -use rnex_core::rmc::protocols::notifications::{ - self, Notification, NotificationEvent, RemoteNotification, -}; +use rnex_core::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; use rnex_core::rmc::protocols::ranking::{ CompetitionRankingGetParam, CompetitionRankingScoreData, CompetitionRankingScoreInfo, }; @@ -53,7 +51,6 @@ use rnex_core::rmc::structures::ranking::UploadCompetitionData; use std::sync::{Arc, Weak}; use tokio::sync::{Mutex, RwLock}; -use crate::rmc::structures::Error; use crate::rmc::structures::matchmake::MatchmakeSessionSearchCriteria; cfg_if! { @@ -185,15 +182,13 @@ impl MatchmakeExtension for User { Ok(Vec::new()) } + #[cfg(feature = "v3-5-0")] async fn update_progress_score(&self, gid: u32, progress: u8) -> Result<(), ErrorCode> { - #[cfg(feature = "v3-5-0")] - { - let session = self.matchmake_manager.get_session(gid).await?; + let session = self.matchmake_manager.get_session(gid).await?; - let mut session = session.lock().await; + let mut session = session.lock().await; - session.session.progress_score = progress; - } + session.session.progress_score = progress; Ok(()) } @@ -442,7 +437,7 @@ impl MatchmakeExtension for User { async fn get_friend_notification_data( &self, - ty: i32, + _ty: i32, ) -> Result, ErrorCode> { Ok(vec![]) } @@ -503,7 +498,7 @@ impl MatchmakeExtension for User { &self, gid: u32, message: String, - dont_care_block_list: bool, + _dont_care_block_list: bool, //participation_count: u16, ) -> Result, ErrorCode> { let sess = self.matchmake_manager.get_session(gid).await?; diff --git a/rnex-core/src/rmc/protocols/matchmake_extension.rs b/rnex-core/src/rmc/protocols/matchmake_extension.rs index 190dd94..7e7a00d 100644 --- a/rnex-core/src/rmc/protocols/matchmake_extension.rs +++ b/rnex-core/src/rmc/protocols/matchmake_extension.rs @@ -66,6 +66,7 @@ pub trait MatchmakeExtension { async fn get_playing_session(&self, pids: Vec) -> Result, ErrorCode>; #[method_id(34)] + #[cfg(feature = "v3-5-0")] async fn update_progress_score(&self, gid: u32, progress: u8) -> Result<(), ErrorCode>; #[method_id(38)] async fn create_matchmake_session_with_param( diff --git a/rnex-core/src/rmc/protocols/mod.rs b/rnex-core/src/rmc/protocols/mod.rs index 4b00e29..411ae28 100644 --- a/rnex-core/src/rmc/protocols/mod.rs +++ b/rnex-core/src/rmc/protocols/mod.rs @@ -21,7 +21,6 @@ use crate::rmc::response::{ErrorCode, RMCResponse, RMCResponseResult}; use crate::rmc::structures; use crate::rmc::structures::RmcSerialize; use crate::util::{SendingBufferConnection, SplittableBufferConnection}; -use futures::FutureExt; use log::{error, info}; use std::collections::HashMap; use std::future::Future; diff --git a/rnex-core/src/rmc/protocols/util.rs b/rnex-core/src/rmc/protocols/util.rs index 8da6a5f..a89c79b 100644 --- a/rnex-core/src/rmc/protocols/util.rs +++ b/rnex-core/src/rmc/protocols/util.rs @@ -1,11 +1,6 @@ -use macros::{RmcSerialize, method_id, rmc_proto}; +use macros::{method_id, rmc_proto}; -use rnex_core::{ - PID, - rmc::{response::ErrorCode, structures::any::Any}, -}; - -use crate::{kerberos::KerberosDateTime, rmc::protocols::friends::NNAInfo}; +use rnex_core::rmc::response::ErrorCode; #[rmc_proto(110)] pub trait Utility { diff --git a/rnex-core/src/rmc/structures/mod.rs b/rnex-core/src/rmc/structures/mod.rs index ce6cb75..63ae484 100644 --- a/rnex-core/src/rmc/structures/mod.rs +++ b/rnex-core/src/rmc/structures/mod.rs @@ -20,6 +20,8 @@ pub enum Error { StationUrlInvalid, #[error("error formatting text: {0}")] FormatError(#[from] fmt::Error), + #[error("uncategorized rmc error occurred: {0}")] + Other(Box), } pub type Result = std::result::Result; @@ -36,10 +38,11 @@ pub mod primitives; pub mod qbuffer; pub mod qresult; pub mod ranking; +pub mod resultsrange; pub mod rmc_struct; pub mod string; +pub mod string_set; pub mod variant; -pub mod resultsrange; pub trait RmcSerialize { fn serialize(&self, writer: &mut impl Write) -> Result<()>; @@ -67,6 +70,9 @@ pub trait RmcSerialize { fn name() -> &'static str { "NoNameSpecified" } + fn version() -> Option { + None + } } impl RmcSerialize for () { diff --git a/rnex-core/src/rmc/structures/string_set.rs b/rnex-core/src/rmc/structures/string_set.rs new file mode 100644 index 0000000..9526a4e --- /dev/null +++ b/rnex-core/src/rmc/structures/string_set.rs @@ -0,0 +1,86 @@ +use std::{collections::HashSet, hash::Hash, str::FromStr, string::ToString}; + +use rnex_core::rmc::structures::RmcSerialize; + +#[derive(Debug)] +struct StringSet(HashSet) +where + ::Err: std::error::Error + Send + Sync + 'static; + +impl PartialEq for StringSet +where + ::Err: std::error::Error + Send + Sync + 'static, +{ + fn eq(&self, other: &Self) -> bool { + self.0.iter().eq(&other.0) + } +} + +impl ToString for StringSet +where + ::Err: std::error::Error + Send + Sync + 'static, +{ + fn to_string(&self) -> String { + self.0 + .iter() + .map(ToString::to_string) + .reduce(|a, b| format!("{}|{}", a, b)) + .unwrap_or(String::new()) + } +} + +impl FromStr for StringSet +where + ::Err: std::error::Error + Send + Sync + 'static, +{ + type Err = Box; + + fn from_str(s: &str) -> Result { + Ok(Self(s.split("|").map(T::from_str).try_fold( + HashSet::new(), + |mut a, b| -> Result, Self::Err> { + a.insert(b.map_err(Box::new)?); + Ok(a) + }, + )?)) + } +} + +impl RmcSerialize for StringSet +where + ::Err: std::error::Error + Send + Sync + 'static, +{ + fn deserialize(reader: &mut impl std::io::prelude::Read) -> super::Result + where + Self: Sized, + { + Self::from_str(&String::deserialize(reader)?).map_err(super::Error::Other) + } + fn serialize(&self, writer: &mut impl std::io::prelude::Write) -> super::Result<()> { + self.to_string().serialize(writer) + } + fn serialize_write_size(&self) -> super::Result { + self.to_string().serialize_write_size() + } +} + +#[cfg(test)] +mod test { + use std::str::FromStr; + + use crate::rmc::structures::string_set::StringSet; + + #[test] + fn test() { + let str_val = "0|100|200|10|110|210|20|120|220|30|130|230"; + let set: StringSet = StringSet::from_str(str_val).unwrap(); + let string_2 = set.to_string(); + let reset: StringSet = StringSet::from_str(&string_2).unwrap(); + + for val in &set.0 { + if !reset.0.contains(&val) { + panic!("sets arent equivalent"); + } + } + } +} diff --git a/rnex-core/src/rnex_proxy_common.rs b/rnex-core/src/rnex_proxy_common.rs index d103e43..54de962 100644 --- a/rnex-core/src/rnex_proxy_common.rs +++ b/rnex-core/src/rnex_proxy_common.rs @@ -12,7 +12,7 @@ pub struct ConnectionInitData { mod test { use std::{ io::Cursor, - net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4}, + net::{Ipv4Addr, SocketAddr, SocketAddrV4}, }; use crate::{ diff --git a/test-all.sh b/test-all.sh new file mode 100755 index 0000000..989b74f --- /dev/null +++ b/test-all.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -euo pipefail + +EDITIONS=$(yq ea "." editions.yaml | yq 'keys[]') +IFS=$'\n' +while IFS=$'\n' read -r EDITION; do + if [[ $(yq ea ".$EDITION.include-in-checkall" editions.yaml) == "true" ]] + then + export EDITION + ./test-edition.sh $EDITION + fi +done <<< "$EDITIONS" From d63fe663de9dc11a86aa7629e147384357451ab8 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 5 May 2026 14:48:25 +0200 Subject: [PATCH 201/203] fix attribs --- rnex-core/src/nex/matchmake.rs | 39 ++++++++++------------ rnex-core/src/rmc/structures/matchmake.rs | 4 ++- rnex-core/src/rmc/structures/string_set.rs | 4 +-- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 686f3bb..42ca97c 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -399,31 +399,28 @@ impl ExtendedMatchmakeSession { #[cfg(feature = "splatoon")] { - if search_criteria - .attribs - .get(0) - .map(|str| str.parse().ok()) - .flatten() - != self.session.attributes.get(0).map(|v| *v) - { + if search_criteria.attribs.get(0).is_some_and(|s| { + self.session + .attributes + .get(0) + .is_some_and(|a| s.0.contains(a)) + }) { return Ok(false); } - if search_criteria - .attribs - .get(2) - .map(|str| str.parse().ok()) - .flatten() - != self.session.attributes.get(2).map(|v| *v) - { + if search_criteria.attribs.get(2).is_some_and(|s| { + self.session + .attributes + .get(2) + .is_some_and(|a| s.0.contains(a)) + }) { return Ok(false); } - if search_criteria - .attribs - .get(3) - .map(|str| str.parse().ok()) - .flatten() - != self.session.attributes.get(3).map(|v| *v) - { + if search_criteria.attribs.get(3).is_some_and(|s| { + self.session + .attributes + .get(3) + .is_some_and(|a| s.0.contains(a)) + }) { return Ok(false); } } diff --git a/rnex-core/src/rmc/structures/matchmake.rs b/rnex-core/src/rmc/structures/matchmake.rs index aeb26ff..88deea0 100644 --- a/rnex-core/src/rmc/structures/matchmake.rs +++ b/rnex-core/src/rmc/structures/matchmake.rs @@ -5,6 +5,8 @@ use rnex_core::rmc::structures::variant::Variant; use rnex_core::PID; +use crate::rmc::structures::string_set::StringSet; + // rmc structure #[derive(RmcSerialize, Debug, Clone, Default, PartialEq)] #[rmc_struct(0)] @@ -75,7 +77,7 @@ cfg_if! { #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(3)] pub struct MatchmakeSessionSearchCriteria { - pub attribs: Vec, + pub attribs: Vec>, pub game_mode: String, pub minimum_participants: String, pub maximum_participants: String, diff --git a/rnex-core/src/rmc/structures/string_set.rs b/rnex-core/src/rmc/structures/string_set.rs index 9526a4e..7c55507 100644 --- a/rnex-core/src/rmc/structures/string_set.rs +++ b/rnex-core/src/rmc/structures/string_set.rs @@ -2,8 +2,8 @@ use std::{collections::HashSet, hash::Hash, str::FromStr, string::ToString}; use rnex_core::rmc::structures::RmcSerialize; -#[derive(Debug)] -struct StringSet(HashSet) +#[derive(Debug, Clone)] +pub struct StringSet(pub HashSet) where ::Err: std::error::Error + Send + Sync + 'static; From e8f5ff3c24652425976a3ebc6a4e080e2e2d41e4 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 5 May 2026 18:03:00 +0200 Subject: [PATCH 202/203] fix stringset --- rnex-core/src/rmc/structures/string_set.rs | 23 +++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/rnex-core/src/rmc/structures/string_set.rs b/rnex-core/src/rmc/structures/string_set.rs index 9526a4e..f1b4884 100644 --- a/rnex-core/src/rmc/structures/string_set.rs +++ b/rnex-core/src/rmc/structures/string_set.rs @@ -36,13 +36,18 @@ where type Err = Box; fn from_str(s: &str) -> Result { - Ok(Self(s.split("|").map(T::from_str).try_fold( - HashSet::new(), - |mut a, b| -> Result, Self::Err> { - a.insert(b.map_err(Box::new)?); - Ok(a) - }, - )?)) + Ok(Self( + s.split("|") + .filter(|v| !v.is_empty()) + .map(T::from_str) + .try_fold( + HashSet::new(), + |mut a, b| -> Result, Self::Err> { + a.insert(b.map_err(Box::new)?); + Ok(a) + }, + )?, + )) } } @@ -82,5 +87,9 @@ mod test { panic!("sets arent equivalent"); } } + + let _: StringSet = StringSet::from_str("").unwrap(); + + let _: StringSet = StringSet::from_str("10").unwrap(); } } From 9ebf88d8eb40a60265350be8392d46ed6dd1bc58 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Tue, 5 May 2026 21:55:55 +0200 Subject: [PATCH 203/203] add handeling for empty bounds string --- rnex-core/src/nex/matchmake.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 42ca97c..70e720d 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -121,6 +121,9 @@ fn check_bounds_str(compare: T, str: &str) -> Option

    %qUhgU}nb3ZP!*C&aFg)vLT#m&)5@W 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

    =q~6cX!&E7%KanvbpweH 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 z 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�Y5uT566IyM{ZR8(uccDvQ|)J2$R4SH&AUrqRj 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

%qUhgU}nb3ZP!*C&aFg)vLT#m&)5@W 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