From 5d54d92e675d34451617358985580c8b2056db25 Mon Sep 17 00:00:00 2001 From: Spacebot Date: Tue, 28 Apr 2026 14:20:31 +0000 Subject: [PATCH 01/31] Update Rust crate log to v0.4.29 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e666c9d..f1d3ba5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1788,9 +1788,9 @@ dependencies = [ [[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" From af0b6d7a3bbf221bdb3bc7bae64659865d6f8435 Mon Sep 17 00:00:00 2001 From: Spacebot Date: Tue, 28 Apr 2026 14:20:41 +0000 Subject: [PATCH 02/31] Update Rust crate once_cell to v1.21.4 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e666c9d..0faa662 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1930,9 +1930,9 @@ 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" From f93168d60e29aa94e3b962bda2ef0caac8c5caa6 Mon Sep 17 00:00:00 2001 From: Spacebot Date: Tue, 28 Apr 2026 15:04:24 +0000 Subject: [PATCH 03/31] Update Rust crate thiserror to v2.0.18 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e28a488..032a92e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3002,18 +3002,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", From 18f5ea93fcac2e7b533f0b0dec9dcf905155dc0f Mon Sep 17 00:00:00 2001 From: Spacebot Date: Tue, 28 Apr 2026 15:04:39 +0000 Subject: [PATCH 04/31] Update Rust crate bytemuck to v1.25.0 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e28a488..1be0d14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -578,18 +578,18 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[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", From 345416471962c91d2b9d2e60165bf422f470d117 Mon Sep 17 00:00:00 2001 From: Spacebot Date: Tue, 28 Apr 2026 16:03:20 +0000 Subject: [PATCH 05/31] Update Rust crate hmac to 0.13.0 --- Cargo.lock | 6 +++--- prudpv0/Cargo.toml | 2 +- prudpv1/Cargo.toml | 2 +- rnex-core/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e28a488..0d2bad2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2140,7 +2140,7 @@ version = "0.1.0" dependencies = [ "bytemuck", "cfg-if", - "hmac 0.12.1", + "hmac 0.13.0", "log", "md-5 0.10.6", "proxy-common", @@ -2157,7 +2157,7 @@ dependencies = [ "async-trait", "bytemuck", "cfg-if", - "hmac 0.12.1", + "hmac 0.13.0", "log", "md-5 0.10.6", "once_cell", @@ -2316,7 +2316,7 @@ dependencies = [ "dotenv", "futures", "hex", - "hmac 0.12.1", + "hmac 0.13.0", "json", "log", "macros 0.0.0", diff --git a/prudpv0/Cargo.toml b/prudpv0/Cargo.toml index 447436d..72c59be 100644 --- a/prudpv0/Cargo.toml +++ b/prudpv0/Cargo.toml @@ -12,7 +12,7 @@ rc4 = "0.1.0" log = "0.4.25" cfg-if = "1.0.4" proxy-common = {path = "../proxy-common"} -hmac = "0.12.1" +hmac = "0.13.0" md-5 = "^0.10.6" [features] diff --git a/prudpv1/Cargo.toml b/prudpv1/Cargo.toml index b8346bf..5b0a7a5 100644 --- a/prudpv1/Cargo.toml +++ b/prudpv1/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [dependencies] bytemuck = { version = "1.23.1", features = ["derive"] } tokio = { version = "1.47.0", features = ["full"] } -hmac = "0.12.1" +hmac = "0.13.0" md-5 = "^0.10.6" rc4 = "0.1.0" v-byte-helpers = { git = "https://github.com/RusticMaple/VByteMacros", version = "0.1.1" } diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index f338fe3..2d35bfe 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -15,7 +15,7 @@ chrono = "0.4.39" log = "0.4.25" rand = "0.8.5" cfg-if = "1.0.4" -hmac = "0.12.1" +hmac = "0.13.0" md-5 = "^0.10.6" tokio = { version = "1.43.0", features = ["full"] } hex = "0.4.3" From 1e25661d815f0d623d6c33481f79910ac8b7ddc5 Mon Sep 17 00:00:00 2001 From: Spacebot Date: Tue, 28 Apr 2026 16:03:36 +0000 Subject: [PATCH 06/31] Update Rust crate md-5 to ^0.11.0 --- Cargo.lock | 6 +++--- prudpv0/Cargo.toml | 2 +- prudpv1/Cargo.toml | 2 +- rnex-core/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e28a488..42f4c68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2142,7 +2142,7 @@ dependencies = [ "cfg-if", "hmac 0.12.1", "log", - "md-5 0.10.6", + "md-5 0.11.0", "proxy-common", "rc4", "rnex-core", @@ -2159,7 +2159,7 @@ dependencies = [ "cfg-if", "hmac 0.12.1", "log", - "md-5 0.10.6", + "md-5 0.11.0", "once_cell", "proxy-common", "rc4", @@ -2320,7 +2320,7 @@ dependencies = [ "json", "log", "macros 0.0.0", - "md-5 0.10.6", + "md-5 0.11.0", "once_cell", "paste", "rand 0.8.5", diff --git a/prudpv0/Cargo.toml b/prudpv0/Cargo.toml index 447436d..fd4d6fa 100644 --- a/prudpv0/Cargo.toml +++ b/prudpv0/Cargo.toml @@ -13,7 +13,7 @@ log = "0.4.25" cfg-if = "1.0.4" proxy-common = {path = "../proxy-common"} hmac = "0.12.1" -md-5 = "^0.10.6" +md-5 = "^0.11.0" [features] prudpv0 = [] diff --git a/prudpv1/Cargo.toml b/prudpv1/Cargo.toml index b8346bf..33082fe 100644 --- a/prudpv1/Cargo.toml +++ b/prudpv1/Cargo.toml @@ -7,7 +7,7 @@ edition = "2024" bytemuck = { version = "1.23.1", features = ["derive"] } tokio = { version = "1.47.0", features = ["full"] } hmac = "0.12.1" -md-5 = "^0.10.6" +md-5 = "^0.11.0" rc4 = "0.1.0" v-byte-helpers = { git = "https://github.com/RusticMaple/VByteMacros", version = "0.1.1" } thiserror = "2.0.12" diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index f338fe3..87d2960 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -16,7 +16,7 @@ log = "0.4.25" rand = "0.8.5" cfg-if = "1.0.4" hmac = "0.12.1" -md-5 = "^0.10.6" +md-5 = "^0.11.0" tokio = { version = "1.43.0", features = ["full"] } hex = "0.4.3" From 45355d340718fe35a5f0cdba3bdb9214f22c523e Mon Sep 17 00:00:00 2001 From: redbinder0526 Date: Tue, 28 Apr 2026 18:15:00 +0200 Subject: [PATCH 07/31] Update .forgejo/workflows/build.yml --- .forgejo/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index f76432e..f548006 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -3,7 +3,6 @@ name: Build and Test on: push: branches: ["**"] - pull_request: env: DOCKER_TLS_CERTDIR: /certs From 3757658fd5e58ece0dda7252d913d146ef434b8c Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 28 Apr 2026 21:30:17 +0200 Subject: [PATCH 08/31] Revert md-5 upgrade --- Cargo.lock | 6 +++--- prudpv0/Cargo.toml | 2 +- prudpv1/Cargo.toml | 2 +- renovate.json | 4 ++-- rnex-core/Cargo.toml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f5f463..925e3c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2142,7 +2142,7 @@ dependencies = [ "cfg-if", "hmac 0.12.1", "log", - "md-5 0.11.0", + "md-5 0.10.6", "proxy-common", "rc4", "rnex-core", @@ -2159,7 +2159,7 @@ dependencies = [ "cfg-if", "hmac 0.12.1", "log", - "md-5 0.11.0", + "md-5 0.10.6", "once_cell", "proxy-common", "rc4", @@ -2320,7 +2320,7 @@ dependencies = [ "json", "log", "macros 0.0.0", - "md-5 0.11.0", + "md-5 0.10.6", "once_cell", "paste", "rand 0.8.5", diff --git a/prudpv0/Cargo.toml b/prudpv0/Cargo.toml index fd4d6fa..447436d 100644 --- a/prudpv0/Cargo.toml +++ b/prudpv0/Cargo.toml @@ -13,7 +13,7 @@ log = "0.4.25" cfg-if = "1.0.4" proxy-common = {path = "../proxy-common"} hmac = "0.12.1" -md-5 = "^0.11.0" +md-5 = "^0.10.6" [features] prudpv0 = [] diff --git a/prudpv1/Cargo.toml b/prudpv1/Cargo.toml index 33082fe..b8346bf 100644 --- a/prudpv1/Cargo.toml +++ b/prudpv1/Cargo.toml @@ -7,7 +7,7 @@ edition = "2024" bytemuck = { version = "1.23.1", features = ["derive"] } tokio = { version = "1.47.0", features = ["full"] } hmac = "0.12.1" -md-5 = "^0.11.0" +md-5 = "^0.10.6" rc4 = "0.1.0" v-byte-helpers = { git = "https://github.com/RusticMaple/VByteMacros", version = "0.1.1" } thiserror = "2.0.12" diff --git a/renovate.json b/renovate.json index 3f918de..be44185 100644 --- a/renovate.json +++ b/renovate.json @@ -4,11 +4,11 @@ "packageRules": [ { "matchUpdateTypes": ["minor", "patch"], - "automerge": true + "automerge": false }, { "matchUpdateTypes": ["major"], "automerge": false } ] -} \ No newline at end of file +} diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 87d2960..f338fe3 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -16,7 +16,7 @@ log = "0.4.25" rand = "0.8.5" cfg-if = "1.0.4" hmac = "0.12.1" -md-5 = "^0.11.0" +md-5 = "^0.10.6" tokio = { version = "1.43.0", features = ["full"] } hex = "0.4.3" From 0b9d9ad2144c162f9b641d6b6cb8832a420ca294 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 28 Apr 2026 21:38:05 +0200 Subject: [PATCH 09/31] Revert "Merge pull request 'Update Rust crate hmac to 0.13.0' (#18) from renovate/hmac-0.x into v0" This reverts commit ca8315da8e3e62d272217164183968e2e5798184, reversing changes made to 3757658fd5e58ece0dda7252d913d146ef434b8c. --- Cargo.lock | 6 +++--- prudpv0/Cargo.toml | 2 +- prudpv1/Cargo.toml | 2 +- rnex-core/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73a949b..925e3c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2140,7 +2140,7 @@ version = "0.1.0" dependencies = [ "bytemuck", "cfg-if", - "hmac 0.13.0", + "hmac 0.12.1", "log", "md-5 0.10.6", "proxy-common", @@ -2157,7 +2157,7 @@ dependencies = [ "async-trait", "bytemuck", "cfg-if", - "hmac 0.13.0", + "hmac 0.12.1", "log", "md-5 0.10.6", "once_cell", @@ -2316,7 +2316,7 @@ dependencies = [ "dotenv", "futures", "hex", - "hmac 0.13.0", + "hmac 0.12.1", "json", "log", "macros 0.0.0", diff --git a/prudpv0/Cargo.toml b/prudpv0/Cargo.toml index 72c59be..447436d 100644 --- a/prudpv0/Cargo.toml +++ b/prudpv0/Cargo.toml @@ -12,7 +12,7 @@ rc4 = "0.1.0" log = "0.4.25" cfg-if = "1.0.4" proxy-common = {path = "../proxy-common"} -hmac = "0.13.0" +hmac = "0.12.1" md-5 = "^0.10.6" [features] diff --git a/prudpv1/Cargo.toml b/prudpv1/Cargo.toml index 5b0a7a5..b8346bf 100644 --- a/prudpv1/Cargo.toml +++ b/prudpv1/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" [dependencies] bytemuck = { version = "1.23.1", features = ["derive"] } tokio = { version = "1.47.0", features = ["full"] } -hmac = "0.13.0" +hmac = "0.12.1" md-5 = "^0.10.6" rc4 = "0.1.0" v-byte-helpers = { git = "https://github.com/RusticMaple/VByteMacros", version = "0.1.1" } diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index 2d35bfe..f338fe3 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -15,7 +15,7 @@ chrono = "0.4.39" log = "0.4.25" rand = "0.8.5" cfg-if = "1.0.4" -hmac = "0.13.0" +hmac = "0.12.1" md-5 = "^0.10.6" tokio = { version = "1.43.0", features = ["full"] } hex = "0.4.3" From 78262f294d85c9dd065350aed895fcd7d5773923 Mon Sep 17 00:00:00 2001 From: Spacebot Date: Tue, 28 Apr 2026 19:53:27 +0000 Subject: [PATCH 10/31] Update Rust crate md-5 to ^0.11.0 --- Cargo.lock | 6 +++--- prudpv0/Cargo.toml | 2 +- prudpv1/Cargo.toml | 2 +- rnex-core/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 925e3c2..0f5f463 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2142,7 +2142,7 @@ dependencies = [ "cfg-if", "hmac 0.12.1", "log", - "md-5 0.10.6", + "md-5 0.11.0", "proxy-common", "rc4", "rnex-core", @@ -2159,7 +2159,7 @@ dependencies = [ "cfg-if", "hmac 0.12.1", "log", - "md-5 0.10.6", + "md-5 0.11.0", "once_cell", "proxy-common", "rc4", @@ -2320,7 +2320,7 @@ dependencies = [ "json", "log", "macros 0.0.0", - "md-5 0.10.6", + "md-5 0.11.0", "once_cell", "paste", "rand 0.8.5", diff --git a/prudpv0/Cargo.toml b/prudpv0/Cargo.toml index 447436d..fd4d6fa 100644 --- a/prudpv0/Cargo.toml +++ b/prudpv0/Cargo.toml @@ -13,7 +13,7 @@ log = "0.4.25" cfg-if = "1.0.4" proxy-common = {path = "../proxy-common"} hmac = "0.12.1" -md-5 = "^0.10.6" +md-5 = "^0.11.0" [features] prudpv0 = [] diff --git a/prudpv1/Cargo.toml b/prudpv1/Cargo.toml index b8346bf..33082fe 100644 --- a/prudpv1/Cargo.toml +++ b/prudpv1/Cargo.toml @@ -7,7 +7,7 @@ edition = "2024" bytemuck = { version = "1.23.1", features = ["derive"] } tokio = { version = "1.47.0", features = ["full"] } hmac = "0.12.1" -md-5 = "^0.10.6" +md-5 = "^0.11.0" rc4 = "0.1.0" v-byte-helpers = { git = "https://github.com/RusticMaple/VByteMacros", version = "0.1.1" } thiserror = "2.0.12" diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index f338fe3..87d2960 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -16,7 +16,7 @@ log = "0.4.25" rand = "0.8.5" cfg-if = "1.0.4" hmac = "0.12.1" -md-5 = "^0.10.6" +md-5 = "^0.11.0" tokio = { version = "1.43.0", features = ["full"] } hex = "0.4.3" From 28670c09ef89629b72102aa57b95ed41776d1247 Mon Sep 17 00:00:00 2001 From: red binder Date: Tue, 28 Apr 2026 21:53:40 +0200 Subject: [PATCH 11/31] 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 12/31] 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 13/31] 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 14/31] 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 15/31] 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 16/31] 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 17/31] 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 18/31] 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 19/31] 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 20/31] 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 21/31] 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 22/31] 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 23/31] 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 24/31] 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 25/31] 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 26/31] 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 27/31] 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 28/31] 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 29/31] 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 30/31] 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 31/31] 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