diff --git a/.ci-scripts/make-edition.sh b/.ci-scripts/make-edition.sh index 2b4bb91..57c857a 100755 --- a/.ci-scripts/make-edition.sh +++ b/.ci-scripts/make-edition.sh @@ -1,15 +1,17 @@ #!/usr/bin/env bash -export EDITION=$1 -source /etc/environment -: "${RNEX_CONTAINER_PLATFORM:=podman}" -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 +export EDITION=$1 +export BA="--build-arg EDITION=$1" + +# podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" --target=dev-container . +# podman push "$CI_REGISTRY_IMAGE/$EDITION/dev-container:latest" +podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" --target=node-holder . +podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" --target=proxy-secure . +podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" --target=proxy-insecure . +podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" --target=backend-auth . +podman build $BA -t "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" --target=backend-secure . +podman push "$CI_REGISTRY_IMAGE/$EDITION/node-holder:$CI_COMMIT_SHORT_SHA" +podman push "$CI_REGISTRY_IMAGE/$EDITION/proxy-secure:$CI_COMMIT_SHORT_SHA" +podman push "$CI_REGISTRY_IMAGE/$EDITION/proxy-insecure:$CI_COMMIT_SHORT_SHA" +podman push "$CI_REGISTRY_IMAGE/$EDITION/backend-auth:$CI_COMMIT_SHORT_SHA" +podman push "$CI_REGISTRY_IMAGE/$EDITION/backend-secure:$CI_COMMIT_SHORT_SHA" diff --git a/.dockerignore b/.dockerignore index ab0f8c4..4e09ffe 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,6 +7,4 @@ CONTRIBUTING.md README.md .gitignore LICENSE -.devcontainer.json -.ci-scripts/make-edition.sh -.forgejo/workflows/build.yml \ No newline at end of file +.devcontainer.json \ No newline at end of file diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml deleted file mode 100644 index 35e5879..0000000 --- a/.forgejo/workflows/build.yml +++ /dev/null @@ -1,314 +0,0 @@ -name: Build and Test - -on: - push: - branches: ["**"] - pull_request: - -env: - DOCKER_TLS_CERTDIR: /certs - IMAGE_TAG: ${{ github.sha }} - 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 - - 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 - - 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 - - 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 - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Cache container storage - uses: actions/cache@v4 - with: - path: | - /var/lib/containers/storage - /run/containers/storage - ~/.local/share/containers/storage - key: image-cache - - - name: Login to registry - run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net - - - name: Set short SHA - run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV - - - name: Build Wii U Chat edition - env: - CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex - CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} - run: ./.ci-scripts/make-edition.sh wii-u-chat - - splatoon: - runs-on: debian-trixie - - 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 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 - - friends: - 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: Set short SHA - run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV - - - name: Login to registry - run: podman login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net - - - name: Build Friends edition - env: - CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex - CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} - DATABASE_URL: ${{ secrets.DATABASE_FRIENDS }} - run: ./.ci-scripts/make-edition.sh friends - - super-mario-maker: - 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: Set short SHA - run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV - - - name: Login to registry - run: podman login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net - - - name: Build Super Mario Maker edition - env: - CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex - CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }} - DATABASE_URL: ${{ secrets.DATABASE_SMM }} - run: ./.ci-scripts/make-edition.sh super-mario-maker diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 908e9e4..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rust-analyzer.cargo.features": [ - "friends" - ] -} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 186e31d..bf83871 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,6 +14,12 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -25,19 +31,19 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "async-trait" -version = "0.1.89" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] @@ -63,9 +69,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-config" -version = "1.8.16" +version = "1.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f156acdd2cf55f5aa53ee416c4ac851cf1222694506c0b1f78c85695e9ca9d" +checksum = "11493b0bad143270fb8ad284a096dd529ba91924c5409adeac856cc1bf047dbc" dependencies = [ "aws-credential-types", "aws-runtime", @@ -82,8 +88,8 @@ dependencies = [ "bytes", "fastrand", "hex", - "http 1.4.0", - "sha1 0.10.6", + "http 1.3.1", + "sha1", "time", "tokio", "tracing", @@ -105,9 +111,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.16.3" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" dependencies = [ "aws-lc-sys", "zeroize", @@ -115,9 +121,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.40.0" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" dependencies = [ "cc", "cmake", @@ -127,9 +133,9 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.7.3" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dcd93c82209ac7413532388067dce79be5a8780c1786e5fae3df22e4dee2864" +checksum = "5fc0651c57e384202e47153c1260b84a9936e19803d747615edf199dc3b98d17" dependencies = [ "aws-credential-types", "aws-sigv4", @@ -144,7 +150,7 @@ dependencies = [ "bytes-utils", "fastrand", "http 0.2.12", - "http 1.4.0", + "http 1.3.1", "http-body 0.4.6", "http-body 1.0.1", "percent-encoding", @@ -155,9 +161,9 @@ dependencies = [ [[package]] name = "aws-sdk-s3" -version = "1.131.0" +version = "1.129.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe1b8c5282bf859170836045296b3cd710b7573aceb909498366bb508a41058e" +checksum = "6d4e8410fadbc0ee453145dd77a4958227b18b05bf67c2795d0a8b8596c9aa0f" dependencies = [ "aws-credential-types", "aws-runtime", @@ -176,23 +182,23 @@ dependencies = [ "bytes", "fastrand", "hex", - "hmac 0.13.0", + "hmac", "http 0.2.12", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "lru", "percent-encoding", "regex-lite", - "sha2 0.11.0", + "sha2", "tracing", "url", ] [[package]] name = "aws-sdk-sso" -version = "1.98.0" +version = "1.97.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d69c77aafa20460c68b6b3213c84f6423b6e76dbf89accd3e1789a686ffd9489" +checksum = "9aadc669e184501caaa6beafb28c6267fc1baef0810fb58f9b205485ca3f2567" dependencies = [ "aws-credential-types", "aws-runtime", @@ -207,16 +213,16 @@ dependencies = [ "bytes", "fastrand", "http 0.2.12", - "http 1.4.0", + "http 1.3.1", "regex-lite", "tracing", ] [[package]] name = "aws-sdk-ssooidc" -version = "1.100.0" +version = "1.99.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c7e7b09346d5ca22a2a08267555843a6a0127fb20d8964cb6ecfb8fdb190225" +checksum = "1342a7db8f358d3de0aed2007a0b54e875458e39848d54cc1d46700b2bfcb0a8" dependencies = [ "aws-credential-types", "aws-runtime", @@ -231,16 +237,16 @@ dependencies = [ "bytes", "fastrand", "http 0.2.12", - "http 1.4.0", + "http 1.3.1", "regex-lite", "tracing", ] [[package]] name = "aws-sdk-sts" -version = "1.103.0" +version = "1.101.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2249b81a2e73a8027c41c378463a81ec39b8510f184f2caab87de912af0f49b" +checksum = "ab41ad64e4051ecabeea802d6a17845a91e83287e1dd249e6963ea1ba78c428a" dependencies = [ "aws-credential-types", "aws-runtime", @@ -256,16 +262,16 @@ dependencies = [ "aws-types", "fastrand", "http 0.2.12", - "http 1.4.0", + "http 1.3.1", "regex-lite", "tracing", ] [[package]] name = "aws-sigv4" -version = "1.4.3" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68dc0b907359b120170613b5c09ccc61304eac3998ff6274b97d93ee6490115a" +checksum = "b0b660013a6683ab23797778e21f1f854744fdf05f68204b4cca4c8c04b5d1f4" dependencies = [ "aws-credential-types", "aws-smithy-eventstream", @@ -276,13 +282,13 @@ dependencies = [ "crypto-bigint 0.5.5", "form_urlencoded", "hex", - "hmac 0.13.0", + "hmac", "http 0.2.12", - "http 1.4.0", + "http 1.3.1", "p256", "percent-encoding", "ring", - "sha2 0.11.0", + "sha2", "subtle", "time", "tracing", @@ -302,22 +308,22 @@ dependencies = [ [[package]] name = "aws-smithy-checksums" -version = "0.64.7" +version = "0.64.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10efbbcec1e044b81600e2fc562a391951d291152d95b482d5b7e7132299d762" +checksum = "6750f3dd509b0694a4377f0293ed2f9630d710b1cebe281fa8bac8f099f88bc6" dependencies = [ "aws-smithy-http", "aws-smithy-types", "bytes", "crc-fast", "hex", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", - "md-5 0.11.0", + "md-5", "pin-project-lite", - "sha1 0.11.0", - "sha2 0.11.0", + "sha1", + "sha2", "tracing", ] @@ -345,7 +351,7 @@ dependencies = [ "bytes-utils", "futures-core", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "percent-encoding", @@ -366,16 +372,16 @@ dependencies = [ "h2 0.3.27", "h2 0.4.13", "http 0.2.12", - "http 1.4.0", + "http 1.3.1", "http-body 0.4.6", "hyper 0.14.32", "hyper 1.9.0", "hyper-rustls 0.24.2", - "hyper-rustls 0.27.9", + "hyper-rustls 0.27.8", "hyper-util", "pin-project-lite", "rustls 0.21.12", - "rustls 0.23.40", + "rustls 0.23.31", "rustls-native-certs", "rustls-pki-types", "tokio", @@ -414,9 +420,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.11.1" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0504b1ab12debb5959e5165ee5fe97dd387e7aa7ea6a477bfd7635dfe769a4f5" +checksum = "028999056d2d2fd58a697232f9eec4a643cf73a71cf327690a7edad1d2af2110" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -427,7 +433,7 @@ dependencies = [ "bytes", "fastrand", "http 0.2.12", - "http 1.4.0", + "http 1.3.1", "http-body 0.4.6", "http-body 1.0.1", "http-body-util", @@ -439,33 +445,21 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.12.0" +version = "1.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71a13df6ada0aafbf21a73bdfcdf9324cfa9df77d96b8446045be3cde61b42e" +checksum = "876ab3c9c29791ba4ba02b780a3049e21ec63dabda09268b175272c3733a79e6" dependencies = [ "aws-smithy-async", - "aws-smithy-runtime-api-macros", "aws-smithy-types", "bytes", "http 0.2.12", - "http 1.4.0", + "http 1.3.1", "pin-project-lite", "tokio", "tracing", "zeroize", ] -[[package]] -name = "aws-smithy-runtime-api-macros" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d7396fd9500589e62e460e987ecb671bad374934e55ec3b5f498cc7a8a8a7b7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "aws-smithy-types" version = "1.4.7" @@ -477,7 +471,7 @@ dependencies = [ "bytes-utils", "futures-core", "http 0.2.12", - "http 1.4.0", + "http 1.3.1", "http-body 0.4.6", "http-body 1.0.1", "http-body-util", @@ -503,9 +497,9 @@ dependencies = [ [[package]] name = "aws-types" -version = "1.3.15" +version = "1.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4bbcaa9304ea40902d3d5f42a0428d1bd895a2b0f6999436fb279ffddc58ac" +checksum = "47c8323699dd9b3c8d5b3c13051ae9cdef58fd179957c882f8374dd8725962d9" dependencies = [ "aws-credential-types", "aws-smithy-async", @@ -545,11 +539,11 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" dependencies = [ - "serde_core", + "serde", ] [[package]] @@ -561,39 +555,30 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-buffer" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" -dependencies = [ - "hybrid-array", -] - [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytemuck" -version = "1.25.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.10.2" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +checksum = "441473f2b4b0459a68628c744bc61d23e730fb00128b841d30fa4bb3972257e4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] @@ -620,9 +605,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.61" +version = "1.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ "find-msvc-tools", "jobserver", @@ -638,15 +623,16 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -655,7 +641,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common 0.1.7", + "crypto-common", "inout", ] @@ -668,12 +654,6 @@ dependencies = [ "cc", ] -[[package]] -name = "cmov" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" - [[package]] name = "concurrent-queue" version = "2.5.0" @@ -689,12 +669,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - [[package]] name = "cookie" version = "0.18.1" @@ -708,9 +682,9 @@ dependencies = [ [[package]] name = "cookie_store" -version = "0.22.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206" +checksum = "3fc4bff745c9b4c7fb1e97b25d13153da2bc7796260141df62378998d070207f" dependencies = [ "cookie", "document-features", @@ -749,15 +723,6 @@ dependencies = [ "libc", ] -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - [[package]] name = "crc" version = "3.3.0" @@ -769,9 +734,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.5.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc-fast" @@ -780,7 +745,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fd92aca2c6001b1bf5ba0ff84ee74ec8501b52bbef0cac80bf25a6c1d87a83d" dependencies = [ "crc", - "digest 0.10.7", + "digest", "rustversion", "spin 0.10.0", ] @@ -833,37 +798,19 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", ] -[[package]] -name = "crypto-common" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "ctutils" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" -dependencies = [ - "cmov", -] - [[package]] name = "data-encoding" -version = "2.11.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" [[package]] name = "der" @@ -871,7 +818,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ - "const-oid 0.9.6", + "const-oid", "zeroize", ] @@ -881,16 +828,16 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "const-oid 0.9.6", + "const-oid", "pem-rfc7468", "zeroize", ] [[package]] name = "deranged" -version = "0.5.8" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -901,24 +848,12 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", - "const-oid 0.9.6", - "crypto-common 0.1.7", + "block-buffer", + "const-oid", + "crypto-common", "subtle", ] -[[package]] -name = "digest" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" -dependencies = [ - "block-buffer 0.12.0", - "const-oid 0.10.2", - "crypto-common 0.2.1", - "ctutils", -] - [[package]] name = "displaydoc" version = "0.2.5" @@ -927,7 +862,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] @@ -987,7 +922,7 @@ dependencies = [ "base16ct", "crypto-bigint 0.4.9", "der 0.6.1", - "digest 0.10.7", + "digest", "ff", "generic-array", "group", @@ -1004,16 +939,6 @@ 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" @@ -1060,9 +985,9 @@ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "flate2" -version = "1.1.9" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "miniz_oxide", @@ -1112,26 +1037,11 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" -[[package]] -name = "futures" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -1139,15 +1049,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -1173,34 +1083,33 @@ checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "futures-channel", "futures-core", "futures-io", "futures-macro", @@ -1208,6 +1117,7 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", + "pin-utils", "slab", ] @@ -1223,9 +1133,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.17" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", @@ -1285,7 +1195,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.4.0", + "http 1.3.1", "indexmap", "slab", "tokio", @@ -1315,12 +1225,6 @@ 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" @@ -1348,7 +1252,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac 0.12.1", + "hmac", ] [[package]] @@ -1357,16 +1261,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "hmac" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" -dependencies = [ - "digest 0.11.3", + "digest", ] [[package]] @@ -1391,11 +1286,12 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", + "fnv", "itoa", ] @@ -1417,7 +1313,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.4.0", + "http 1.3.1", ] [[package]] @@ -1428,7 +1324,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "pin-project-lite", ] @@ -1445,15 +1341,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "hybrid-array" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" -dependencies = [ - "typenum", -] - [[package]] name = "hyper" version = "0.14.32" @@ -1489,7 +1376,7 @@ dependencies = [ "futures-channel", "futures-core", "h2 0.4.13", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "httparse", "itoa", @@ -1516,14 +1403,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.9" +version = "0.27.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +checksum = "c2b52f86d1d4bc0d6b4e6826d960b1b333217e07d36b882dca570a5e1c48895b" dependencies = [ - "http 1.4.0", + "http 1.3.1", "hyper 1.9.0", "hyper-util", - "rustls 0.23.40", + "rustls 0.23.31", "rustls-native-certs", "tokio", "tokio-rustls 0.26.4", @@ -1540,7 +1427,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "hyper 1.9.0", "ipnet", @@ -1555,9 +1442,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.65" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1579,13 +1466,12 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", - "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1593,9 +1479,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -1606,9 +1492,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1620,15 +1506,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -1640,15 +1526,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", @@ -1672,9 +1558,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -1682,12 +1568,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.14.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.16.1", ] [[package]] @@ -1723,12 +1609,10 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.97" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ - "cfg-if", - "futures-util", "once_cell", "wasm-bindgen", ] @@ -1750,9 +1634,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.186" +version = "0.2.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" [[package]] name = "libm" @@ -1796,24 +1680,25 @@ checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "lock_api" -version = "0.4.14" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.29" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "lru" -version = "0.16.4" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" +checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" dependencies = [ "hashbrown 0.16.1", ] @@ -1824,7 +1709,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] @@ -1844,24 +1729,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ "cfg-if", - "digest 0.10.7", -] - -[[package]] -name = "md-5" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" -dependencies = [ - "cfg-if", - "digest 0.11.3", + "digest", ] [[package]] name = "memchr" -version = "2.8.0" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "miniz_oxide" @@ -1895,16 +1770,16 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand 0.8.6", + "rand 0.8.5", "smallvec", "zeroize", ] [[package]] name = "num-conv" -version = "0.2.1" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-integer" @@ -1947,15 +1822,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.4" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openssl-probe" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" +checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" [[package]] name = "outref" @@ -1971,7 +1846,7 @@ checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ "ecdsa", "elliptic-curve", - "sha2 0.10.9", + "sha2", ] [[package]] @@ -1982,9 +1857,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.5" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -1992,15 +1867,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.12" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall 0.5.17", "smallvec", - "windows-link", + "windows-targets 0.52.6", ] [[package]] @@ -2020,15 +1895,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.17" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -2081,9 +1956,9 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "potential_utf" -version = "0.1.5" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -2105,9 +1980,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -2157,9 +2032,9 @@ version = "0.1.0" dependencies = [ "bytemuck", "cfg-if", - "hmac 0.12.1", + "hmac", "log", - "md-5 0.10.6", + "md-5", "proxy-common", "rc4", "rnex-core", @@ -2174,9 +2049,9 @@ dependencies = [ "async-trait", "bytemuck", "cfg-if", - "hmac 0.12.1", + "hmac", "log", - "md-5 0.10.6", + "md-5", "once_cell", "proxy-common", "rc4", @@ -2189,9 +2064,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -2204,9 +2079,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" -version = "0.8.6" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -2215,9 +2090,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.4" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -2249,7 +2124,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", ] [[package]] @@ -2272,9 +2147,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.18" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ "bitflags", ] @@ -2301,7 +2176,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint 0.4.9", - "hmac 0.12.1", + "hmac", "zeroize", ] @@ -2313,7 +2188,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.17", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -2331,20 +2206,19 @@ dependencies = [ "cfg-if", "chrono", "dotenv", - "futures", "hex", - "hmac 0.12.1", + "hmac", "json", "log", "macros 0.0.0", - "md-5 0.10.6", + "md-5", "once_cell", "paste", - "rand 0.8.6", + "rand 0.8.5", "rc4", "serde", "serde_json", - "sha2 0.10.9", + "sha2", "simplelog", "sqlx", "thiserror", @@ -2361,8 +2235,8 @@ version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ - "const-oid 0.9.6", - "digest 0.10.7", + "const-oid", + "digest", "num-bigint-dig", "num-integer", "num-traits", @@ -2398,16 +2272,16 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.13", + "rustls-webpki 0.103.4", "subtle", "zeroize", ] @@ -2426,9 +2300,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ "zeroize", ] @@ -2445,9 +2319,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.13" +version = "0.103.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" dependencies = [ "aws-lc-rs", "ring", @@ -2457,9 +2331,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" [[package]] name = "ryu" @@ -2469,9 +2343,9 @@ checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "schannel" -version = "0.1.29" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ "windows-sys 0.61.2", ] @@ -2508,9 +2382,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.7.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ "bitflags", "core-foundation", @@ -2521,9 +2395,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.17.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -2562,7 +2436,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] @@ -2597,19 +2471,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", - "digest 0.10.7", -] - -[[package]] -name = "sha1" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", - "digest 0.11.3", + "cpufeatures", + "digest", ] [[package]] @@ -2619,19 +2482,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", - "digest 0.11.3", + "cpufeatures", + "digest", ] [[package]] @@ -2642,11 +2494,10 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.8" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ - "errno", "libc", ] @@ -2656,7 +2507,7 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.7", + "digest", "rand_core 0.6.4", ] @@ -2666,15 +2517,15 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest 0.10.7", + "digest", "rand_core 0.6.4", ] [[package]] name = "simd-adler32" -version = "0.3.9" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "simplelog" @@ -2689,9 +2540,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.12" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "smallvec" @@ -2796,7 +2647,7 @@ dependencies = [ "percent-encoding", "serde", "serde_json", - "sha2 0.10.9", + "sha2", "smallvec", "thiserror", "time", @@ -2816,7 +2667,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] @@ -2834,12 +2685,12 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2 0.10.9", + "sha2", "sqlx-core", "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.117", + "syn 2.0.104", "tokio", "url", ] @@ -2857,7 +2708,7 @@ dependencies = [ "bytes", "chrono", "crc", - "digest 0.10.7", + "digest", "dotenvy", "either", "futures-channel", @@ -2867,18 +2718,18 @@ dependencies = [ "generic-array", "hex", "hkdf", - "hmac 0.12.1", + "hmac", "itoa", "log", - "md-5 0.10.6", + "md-5", "memchr", "once_cell", "percent-encoding", - "rand 0.8.6", + "rand 0.8.5", "rsa", "serde", - "sha1 0.10.6", - "sha2 0.10.9", + "sha1", + "sha2", "smallvec", "sqlx-core", "stringprep", @@ -2907,17 +2758,17 @@ dependencies = [ "futures-util", "hex", "hkdf", - "hmac 0.12.1", + "hmac", "home", "itoa", "log", - "md-5 0.10.6", + "md-5", "memchr", "once_cell", - "rand 0.8.6", + "rand 0.8.5", "serde", "serde_json", - "sha2 0.10.9", + "sha2", "smallvec", "sqlx-core", "stringprep", @@ -2989,9 +2840,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -3006,7 +2857,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] @@ -3020,29 +2871,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] name = "time" -version = "0.3.47" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -3050,22 +2901,22 @@ dependencies = [ "num-conv", "num_threads", "powerfmt", - "serde_core", + "serde", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -3073,9 +2924,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -3098,9 +2949,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.52.1" +version = "1.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" dependencies = [ "bytes", "libc", @@ -3121,7 +2972,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] @@ -3140,7 +2991,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.40", + "rustls 0.23.31", "tokio", ] @@ -3163,7 +3014,7 @@ checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" dependencies = [ "futures-util", "log", - "rustls 0.23.40", + "rustls 0.23.31", "rustls-native-certs", "rustls-pki-types", "tokio", @@ -3226,7 +3077,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] @@ -3252,22 +3103,22 @@ checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ "bytes", "data-encoding", - "http 1.4.0", + "http 1.3.1", "httparse", "log", - "rand 0.9.4", - "rustls 0.23.40", + "rand 0.9.2", + "rustls 0.23.31", "rustls-pki-types", - "sha1 0.10.6", + "sha1", "thiserror", "utf-8", ] [[package]] name = "typenum" -version = "1.20.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-bidi" @@ -3277,9 +3128,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.24" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-normalization" @@ -3304,46 +3155,45 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "3.3.0" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" +checksum = "d39cb1dbab692d82a977c0392ffac19e188bd9186a9f32806f0aaa859d75585a" dependencies = [ "base64", "cookie_store", "flate2", "log", "percent-encoding", - "rustls 0.23.40", + "rustls 0.23.31", "rustls-pki-types", "serde", "serde_json", "ureq-proto", - "utf8-zero", + "utf-8", "webpki-roots", ] [[package]] name = "ureq-proto" -version = "0.6.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" +checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2" dependencies = [ "base64", - "http 1.4.0", + "http 1.3.1", "httparse", "log", ] [[package]] name = "url" -version = "2.5.8" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", - "serde", ] [[package]] @@ -3358,12 +3208,6 @@ 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" @@ -3372,9 +3216,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.23.1" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ "js-sys", "wasm-bindgen", @@ -3424,9 +3268,9 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ "wit-bindgen", ] @@ -3439,22 +3283,35 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.120" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.104", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.120" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3462,31 +3319,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.120" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ - "bumpalo", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", + "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.120" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" dependencies = [ "unicode-ident", ] [[package]] name = "webpki-roots" -version = "1.0.7" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" +checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" dependencies = [ "rustls-pki-types", ] @@ -3503,48 +3360,54 @@ dependencies = [ [[package]] name = "winapi-util" -version = "0.1.11" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] name = "windows-core" -version = "0.62.2" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", - "windows-link", + "windows-link 0.1.3", "windows-result", "windows-strings", ] [[package]] name = "windows-implement" -version = "0.60.2" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] name = "windows-interface" -version = "0.59.3" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-link" version = "0.2.1" @@ -3553,20 +3416,20 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-result" -version = "0.4.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] name = "windows-strings" -version = "0.5.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -3587,13 +3450,22 @@ 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", + "windows-link 0.2.1", ] [[package]] @@ -3719,9 +3591,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "wit-bindgen" -version = "0.57.1" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" [[package]] name = "writeable" @@ -3737,9 +3609,9 @@ checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -3748,34 +3620,34 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] @@ -3789,27 +3661,27 @@ dependencies = [ [[package]] name = "zerofrom-derive" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zerotrie" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -3818,9 +3690,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.6" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -3829,13 +3701,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.104", ] [[package]] diff --git a/Dockerfile b/Dockerfile index 44e7ace..e181a93 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,57 +1,42 @@ -# syntax=docker/dockerfile:1 -FROM rust:alpine AS chef -RUN apk add --no-cache musl-dev lld g++ make -RUN cargo install cargo-chef +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 + 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 --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 git submodule update --init --recursive +RUN ./test-edition.sh +RUN ./build-edition.sh FROM scratch AS node-holder -COPY --from=builder /app/dist/edge_node_holder_server /edge_node_holder_server +COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/edge_node_holder_server /edge_node_holder_server ENTRYPOINT ["/edge_node_holder_server"] + FROM scratch AS proxy-insecure -COPY --from=builder /app/dist/proxy_insecure /proxy_insecure +COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_insecure /proxy_insecure ENTRYPOINT ["/proxy_insecure"] FROM scratch AS proxy-secure -COPY --from=builder /app/dist/proxy_secure /proxy_secure +COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/proxy_secure /proxy_secure ENTRYPOINT ["/proxy_secure"] + FROM scratch AS backend-auth -COPY --from=builder /app/dist/backend_server_insecure /backend_server_insecure +COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server_insecure /backend_server_insecure ENTRYPOINT ["/backend_server_insecure"] FROM scratch AS backend-secure -COPY --from=builder /app/dist/backend_server_secure /backend_server_secure +COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/backend_server_secure /backend_server_secure ENTRYPOINT ["/backend_server_secure"] -FROM 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 +# 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 diff --git a/README.md b/README.md index 5e64ee4..c5f1ada 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,20 @@ -# Rust NEX monorepo - -This repo contains the code for all game servers using RNEX. +# Splatoon NEX Server in Rust ## Credits: -- Pretendo team for their reverse engineering efforts +- Pretendo team for the rest of the Servers and Reverse engineering efforts - Kinnay for his huge work on reversing nex servers and documentation(https://github.com/Kinnay/NintendoClients/) - Splatfestival testing team for helping us test our messes of code -- The SPFN team(RusticMaple, BloxerHD, Ceantix, RedBinder0526) +- The SPFN team(Bloxer, Ceantix and RusticMaple) -This NEX implementation was not created to rival Pretendo, we don't want any bad blood between anyone. +This nex implementation was not created and is not intended to compete with pretendo, +we wholeheartedly support pretendo. This project would never have been possible without their reverse engineering efforts. -As such if you want to respect the Authors wishes, 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. +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. -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. + +I felt like this needed to be said as there are far too many pretendo copycats who blatantly copy their code and use +their reversal efforts with no credits in sight in an attempt to harm them for some grudge or stupid reason. +I feel that by working together and not against each other we can reach a better and healthier future for the community, +health of developers and numerous more reasons. diff --git a/build-edition.sh b/build-edition.sh index 6898acf..5d65fc3 100755 --- a/build-edition.sh +++ b/build-edition.sh @@ -1,15 +1,13 @@ #!/usr/bin/env bash - -set -euo pipefail - if [ -z ${EDITION+x} ]; then EDITION=$1 fi # comma seperated list of features for the specified version source ./buildscripts/common.sh -echo building $EDITION echo FEATURES: echo $EDITION_FEATURES +echo ENV SETTINGS: +env OPENSSL_LIB_DIR=/usr/lib OPENSSL_INCLUDE_DIR=/usr/include/openssl OPENSSL_STATIC=1 RUSTFLAGS="-C relocation-model=static -C linker=ld.lld" cargo build --release --features "$EDITION_FEATURES" --target x86_64-unknown-linux-musl diff --git a/buildscripts/common.sh b/buildscripts/common.sh index e4b346c..8c5e67e 100755 --- a/buildscripts/common.sh +++ b/buildscripts/common.sh @@ -1,9 +1,5 @@ #!/usr/bin/env bash - -set -euo pipefail - TMP_FEATURES_TRAILINGCOMMA=$(yq ea ".$EDITION.features" editions.yaml | sed 's/- //g' | tr '\n' ',') -echo "tmpfeatures: $TMP_FEATURES_TRAILINGCOMMA" export EDITION_FEATURES=${TMP_FEATURES_TRAILINGCOMMA::-1} SETTINGS=$(yq ea ".$EDITION.settings" editions.yaml | yq 'keys[]') IFS=$'\n' diff --git a/buildscripts/pre-commit b/buildscripts/pre-commit deleted file mode 100755 index 26c6064..0000000 --- a/buildscripts/pre-commit +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -echo "running cargo check..." - -./check-all.sh -STATUS=$? - -if [ $STATUS -ne 0 ]; then - echo "cargo check failed, aborting" - exit 1 -fi - -echo "cargo check passed" -exit 0 diff --git a/check-all.sh b/check-all.sh deleted file mode 100755 index 1494e10..0000000 --- a/check-all.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/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 - ./check-edition.sh $EDITION - fi -done <<< "$EDITIONS" diff --git a/check-edition.sh b/check-edition.sh deleted file mode 100755 index c734770..0000000 --- a/check-edition.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - - -set -euo pipefail - -if [ -z ${EDITION+x} ]; then - export EDITION=$1 -fi - -# comma seperated list of features for the specified version -source ./buildscripts/common.sh -echo CHECKING $EDITION -echo FEATURES: -echo $EDITION_FEATURES - -cargo check --features "$EDITION_FEATURES" diff --git a/editions.yaml b/editions.yaml index fb635e8..d3c5a54 100644 --- a/editions.yaml +++ b/editions.yaml @@ -1,100 +1,34 @@ -wii-sports-club: - include-in-checkall: true +wiiu-chat: 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: - - 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: - - prudpv1 - - third-notif-param - - 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" - 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: - - prudpv1 - - third-notif-param - - v3-3-2 settings: AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" RNEX_VIRTUAL_PORT_INSECURE: "1:10" RNEX_VIRTUAL_PORT_SECURE: "1:10" RNEX_DEFAULT_PORT: 10000 RNEX_ACCESS_KEY: "e7a47214" -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: - 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: 6000 RNEX_ACCESS_KEY: "6f599f81" -splatoon-testfire: - include-in-checkall: true +splatoon2: features: - - prudpv1 - - v3-8-15 - - splatoon + - v4-3-11 + - prudplite + - nx settings: AUTH_REPORT_VERSION: "branch:origin/project/wup-agmj build:3_8_15_2004_0" RNEX_VIRTUAL_PORT_INSECURE: "1:10" RNEX_VIRTUAL_PORT_SECURE: "1:10" - RNEX_DEFAULT_PORT: 10000 - RNEX_ACCESS_KEY: "da693ee5" + RNEX_DEFAULT_PORT: 6000 friends: - include-in-checkall: false features: - friends settings: @@ -104,7 +38,6 @@ friends: RNEX_DEFAULT_PORT: 6000 RNEX_ACCESS_KEY: "ridfebb9" super-mario-maker: - include-in-checkall: false features: - prudpv1 - v3-8-15 diff --git a/macros/src/lib.rs b/macros/src/lib.rs index d0172c2..432fc03 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,27 +1,400 @@ -#![allow(dead_code)] mod protos; -mod rmc_struct; -mod util; extern crate proc_macro; -use crate::protos::{ProtoInputParams, RmcProtocolData}; -use crate::rmc_struct::{rmc_serialize_enum, rmc_serialize_struct}; +use crate::protos::{ProtoMethodData, RmcProtocolData}; use proc_macro::TokenStream; -use proc_macro2::Ident; -use quote::quote; +use proc_macro2::{Ident, Literal, Span}; +use quote::{quote, TokenStreamExt}; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; use syn::spanned::Spanned; -use syn::{parse_macro_input, Data, DeriveInput, Lit, LitStr}; +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) +} #[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 (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), + 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! {}) + } Data::Union(_) => { - unimplemented!("serialize a union is not allowed"); + unimplemented!() } }; @@ -33,41 +406,19 @@ 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 + #serialize_base_content } #[inline(always)] fn deserialize(reader: &mut impl ::std::io::Read) -> rnex_core::rmc::structures::Result{ - #deserialize + #deserialize_base_content } #write_size - #version - fn name() -> &'static str{ #str_name } @@ -104,9 +455,71 @@ 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); - let raw_data = RmcProtocolData::new(params, &input); + // 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(), + }; quote! { #input diff --git a/macros/src/protos.rs b/macros/src/protos.rs index 3171598..2e95e71 100644 --- a/macros/src/protos.rs +++ b/macros/src/protos.rs @@ -1,48 +1,12 @@ use proc_macro2::{Ident, Span, TokenStream}; use quote::{quote, ToTokens}; -use syn::{ - parse::{Parse, ParseStream}, - punctuated::Punctuated, - Attribute, FnArg, ItemTrait, LitInt, LitStr, Meta, Pat, ReturnType, Token, TraitItem, Type, -}; +use syn::token::{Brace, Paren, Semi}; +use syn::{Attribute, LitInt, LitStr, ReturnType, 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 attributes: Vec, - pub parameters: Vec<(Ident, Type, Vec)>, + pub parameters: Vec<(Ident, Type)>, pub ret_val: ReturnType, } @@ -59,222 +23,108 @@ pub struct RmcProtocolData { } impl RmcProtocolData { - 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 { + fn generate_raw_trait(&self, tokens: &mut TokenStream) { let Self { has_returns, name, id, methods, } = self; - let generate_raw_method = |method: &ProtoMethodData| -> TokenStream { - let ProtoMethodData { - name, - parameters, - attributes, - .. - } = method; - let attribs = fold_tokenable(attributes.iter()); + // this gives us the name which the identifier of the corresponding Raw trait + let raw_name = Ident::new(&format!("Raw{}", name), name.span()); - let raw_name = Ident::new(&format!("raw_{}", name), name.span()); + // boilerplate tokens which all raw traits need + quote! { + #[doc(hidden)] + #[allow(unused_must_use)] + pub trait #raw_name: #name + } + .to_tokens(tokens); - let optional_return = if self.has_returns { - quote! { - -> ::core::result::Result, ::rnex_core::rmc::response::ErrorCode> - } - } else { - quote! {} - } - .into_token_stream(); - - 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! { - #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 - } - - } - }; - - let generate_rmc_call_proto = || { - let method_entries = fold_tokenable(methods.iter().map(|m| { + // generate the body of the raw protocol trait + Brace::default().surround(tokens, |tokens|{ + //generate each raw method + for method in methods{ let ProtoMethodData { - id, name, - attributes, + parameters, .. - } = m; + } = method; - let attribs = fold_tokenable(attributes.iter()); let raw_name = Ident::new(&format!("raw_{}", name), name.span()); + quote!{ + #[inline(always)] + async fn #raw_name + }.to_tokens(tokens); - quote! { - #attribs - #id => self.#raw_name(data).await, + Paren::default().surround(tokens, |tokens|{ + quote!{ &self, data: ::std::vec::Vec }.to_tokens(tokens); + }); + + if self.has_returns { + quote! { + -> ::core::result::Result, ErrorCode> + }.to_tokens(tokens); } - })); - let optional_notimpl_return = if self.has_returns { - quote! { - Err(rnex_core::rmc::response::ErrorCode::Core_NotImplemented) - } - } else { - quote! {} - }; + Brace::default().surround(tokens, |tokens|{ + quote! { let mut cursor = ::std::io::Cursor::new(data); }.to_tokens(tokens); - 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! {} - }; + 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); - quote! { + 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!{ #[inline(always)] async fn rmc_call_proto( &self, @@ -282,38 +132,71 @@ impl RmcProtocolData { method_id: u32, call_id: u32, data: Vec, - ){ - let ret = match method_id{ - #method_entries - v => { + ) + }.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!{ log::error!("(protocol {})unimplemented method id called on protocol: {}", #id, v); - #optional_notimpl_return + }.to_tokens(tokens); + if self.has_returns { + quote! { + Err(rnex_core::rmc::response::ErrorCode::Core_NotImplemented) + }.to_tokens(tokens); } - }; - #optional_result_sendback + }); + + }); + + 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); } - } - }; + }); + }); - // 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_token_stream() + .to_tokens(tokens); } - fn generate_raw_remote_trait(&self) -> TokenStream { + fn generate_raw_remote_trait(&self, tokens: &mut TokenStream) { let Self { has_returns, name, @@ -324,92 +207,101 @@ 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{ - #remote_methods - } + 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); + } + + }) + } + }); } - fn generate_raw_info(&self) -> TokenStream { + fn generate_raw_info(&self, tokens: &mut TokenStream) { let Self { name, id, .. } = self; let raw_info_name = Ident::new(&format!("Raw{}Info", name), Span::call_site()); @@ -422,13 +314,14 @@ 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().to_tokens(tokens); - self.generate_raw_info().to_tokens(tokens); - self.generate_raw_remote_trait().to_tokens(tokens); + self.generate_raw_trait(tokens); + self.generate_raw_info(tokens); + self.generate_raw_remote_trait(tokens); } } diff --git a/macros/src/rmc_struct.rs b/macros/src/rmc_struct.rs deleted file mode 100644 index 66f9515..0000000 --- a/macros/src/rmc_struct.rs +++ /dev/null @@ -1,426 +0,0 @@ -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 deleted file mode 100644 index 133f650..0000000 --- a/macros/src/util.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/out/backend_server_secure b/out/backend_server_secure new file mode 100755 index 0000000..be14059 Binary files /dev/null and b/out/backend_server_secure differ diff --git a/perf.data b/perf.data new file mode 100644 index 0000000..2cf011f Binary files /dev/null and b/perf.data differ diff --git a/proxy-common/src/lib.rs b/proxy-common/src/lib.rs index f614de1..5cc13b7 100644 --- a/proxy-common/src/lib.rs +++ b/proxy-common/src/lib.rs @@ -1,12 +1,12 @@ use log::{error, info}; use rnex_core::{ PID, - executables::common::try_get_ip, + executables::common::{OWN_IP_PUBLIC, try_get_ip}, prudp::{socket_addr::PRUDPSockAddr, virtual_port::VirtualPort}, reggie::{RemoteEdgeNodeHolder, UnitPacketWrite}, rmc::{ protocols::{ - RemoteDisconnectable, RmcCallable, RmcConnection, RmcPureRemoteObject, + OnlyRemote, RemoteDisconnectable, RmcCallable, RmcConnection, RmcPureRemoteObject, new_rmc_gateway_connection, }, structures::RmcSerialize, @@ -17,7 +17,7 @@ use rnex_core::{ use std::{ env::{self, VarError}, error, - net::{AddrParseError, Ipv4Addr, SocketAddr, SocketAddrV4}, + net::{AddrParseError, IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4}, ops::Deref, panic, str::FromStr, @@ -75,7 +75,6 @@ const VIRTUAL_PORT_INSECURE: LazyLock = const VIRTUAL_PORT_SECURE: LazyLock = LazyLock::new(|| VirtualPort::parse(env!("RNEX_VIRTUAL_PORT_SECURE")).unwrap()); impl ProxyStartupParam { - #[inline(always)] pub fn new(prox_ty: ProxyType) -> Result { let port = RNEX_DEFAULT_PORT + match prox_ty { @@ -83,7 +82,7 @@ impl ProxyStartupParam { ProxyType::Secure => 1, }; let self_private = try_get_env("SERVER_IP_PRIVATE") - .unwrap_or(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, port)); + .unwrap_or(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, RNEX_DEFAULT_PORT)); let self_public: SocketAddrV4 = match try_get_env("SERVER_IP_PUBLIC") { Ok(v) => v, Err(e) => try_get_ip() @@ -122,7 +121,6 @@ impl Option<(PID, Vec)> { + fn new_connection(&self, data: &[u8]) -> Option<(PID, Vec)> { Some((100, vec![])) } fn new() -> Self { diff --git a/prudplite/src/lib.rs b/prudplite/src/lib.rs index 0df7b2e..05938d7 100644 --- a/prudplite/src/lib.rs +++ b/prudplite/src/lib.rs @@ -17,7 +17,7 @@ use rnex_core::{ types_flags::{ TypesFlags, flags::{ACK, NEED_ACK, RELIABLE}, - types::{CONNECT, DATA, DISCONNECT, PING, SYN}, + types::{CONNECT, DATA, DISCONNECT, SYN}, }, virtual_port::VirtualPort, }, @@ -26,20 +26,20 @@ use rnex_core::{ use tokio::net::{TcpListener, TcpStream}; use tokio_tungstenite::{ WebSocketStream, - tungstenite::{Bytes, Message}, + tungstenite::{ + Bytes, Message, client::IntoClientRequest, http::header::ACCESS_CONTROL_REQUEST_METHOD, + }, }; struct ConnectionState { param: Arc, active: bool, websocket: WebSocketStream, - #[allow(dead_code)] pid: PID, backend_conn: SplittableBufferConnection, addr: PRUDPSockAddr, incoming_reliable: HashMap>, client_reliable_counter: u16, - #[allow(dead_code)] server_reliable_counter: u16, } @@ -71,16 +71,10 @@ impl ConnectionState { ); let data: Bytes = data.into(); if header.types_flags.get_types() == DISCONNECT { - self.websocket - .send(Message::Binary(data.clone())) - .await - .ok(); - self.websocket - .send(Message::Binary(data.clone())) - .await - .ok(); + self.websocket.send(Message::Binary(data.clone())).await; + self.websocket.send(Message::Binary(data.clone())).await; } - self.websocket.send(Message::Binary(data)).await.ok(); + self.websocket.send(Message::Binary(data)).await; } if (header.types_flags.get_flags() & ACK) != 0 { @@ -117,7 +111,6 @@ impl ConnectionState { } } } - #[allow(dead_code)] pub async fn process_reliable(&mut self) { while let Some(v) = self.incoming_reliable.remove(&self.client_reliable_counter) { self.handle_incoming_prudp(v, true).await; @@ -138,7 +131,7 @@ impl ConnectionState { } } } - _ = self.backend_conn.recv() => { + v = self.backend_conn.recv() => { } } @@ -204,7 +197,7 @@ pub async fn websocket_thread_unconnected( ], &[], ); - websocket.send(Message::Binary(data.into())).await.ok(); + websocket.send(Message::Binary(data.into())).await; } CONNECT => { let Some(supported) = packet.packet_specific_iter() else { @@ -249,7 +242,7 @@ pub async fn websocket_thread_unconnected( ], &data, ); - websocket.send(Message::Binary(data.into())).await.ok(); + websocket.send(Message::Binary(data.into())).await; let addr = PRUDPSockAddr::new( addr, diff --git a/prudplite/src/executable.rs b/prudplite/src/main.rs similarity index 100% rename from prudplite/src/executable.rs rename to prudplite/src/main.rs diff --git a/prudplite/src/packet.rs b/prudplite/src/packet.rs index e75750b..bd8d87c 100644 --- a/prudplite/src/packet.rs +++ b/prudplite/src/packet.rs @@ -3,7 +3,8 @@ use std::{ io::{self, Cursor, Read, Write}, }; -use bytemuck::{Pod, Zeroable, bytes_of_mut}; +use bytemuck::{Pod, Zeroable, bytes_of}; +use futures_util::Stream; use rnex_core::prudp::types_flags::TypesFlags; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; @@ -29,10 +30,10 @@ pub enum PacketSpecificData { impl PacketSpecificData { fn consume(reader: &mut impl Read) -> io::Result { - let mut option_id = 0u8; - reader.read_exact(bytes_of_mut(&mut option_id))?; - let mut size = 0u8; - reader.read_exact(bytes_of_mut(&mut size))?; + let mut option_id = 0; + reader.read_exact(&mut [option_id])?; + let mut size = 0; + reader.read_exact(&mut [size])?; match option_id { 0 => { @@ -155,7 +156,7 @@ impl> LitePacket { .get_mut(size_of::()..size_of::() + len as usize) } - pub fn packet_specific_iter<'a>(&'a self) -> Option> { + pub fn packet_specific_iter(&self) -> Option { self.packet_specific_raw() .map(Cursor::new) .map(PacketSpecificIter) diff --git a/prudpv0/src/crypto/friends_insecure.rs b/prudpv0/src/crypto/friends_insecure.rs index ead738a..1f05681 100644 --- a/prudpv0/src/crypto/friends_insecure.rs +++ b/prudpv0/src/crypto/friends_insecure.rs @@ -1,4 +1,4 @@ -use std::io::Write; +use std::{io::Write, rc::Rc}; use hmac::Mac; use md5::{Digest, Md5}; @@ -18,7 +18,6 @@ use crate::crypto::{ pub struct InsecureInstance { pair: EncryptionPair>, self_signat: [u8; 4], - #[allow(dead_code)] remote_signat: [u8; 4], } @@ -63,7 +62,7 @@ impl Crypto for Insecure { fn instantiate( &self, - _packet_data: &[u8], + packet_data: &[u8], self_signat: [u8; 4], remote_signat: [u8; 4], ) -> Option<(Self::Instance, Vec)> { diff --git a/prudpv0/src/crypto/friends_secure.rs b/prudpv0/src/crypto/friends_secure.rs index 14bdf7c..acfa3bc 100644 --- a/prudpv0/src/crypto/friends_secure.rs +++ b/prudpv0/src/crypto/friends_secure.rs @@ -24,7 +24,6 @@ pub struct SecureInstance { pair: EncryptionPair>, uid: u32, self_signat: [u8; 4], - #[allow(dead_code)] remote_signat: [u8; 4], } diff --git a/prudpv0/src/lib.rs b/prudpv0/src/lib.rs index 86afe42..444899a 100644 --- a/prudpv0/src/lib.rs +++ b/prudpv0/src/lib.rs @@ -1,13 +1,26 @@ -use cfg_if::cfg_if; -cfg_if! { +cfg_if::cfg_if! { if #[cfg(feature = "prudpv0")] { - use log::info; - use proxy_common::ProxyStartupParam; + use bytemuck::{Pod, Zeroable}; + use cfg_if::cfg_if; + use log::{error, info, warn}; + use proxy_common::{ProxyStartupParam, setup_edge_node_connection}; + use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT}; + use rnex_core::prudp::types_flags::TypesFlags; + use rnex_core::prudp::types_flags::types::SYN; + use rnex_core::prudp::virtual_port::VirtualPort; + use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; + use rnex_core::reggie::RemoteEdgeNodeHolder; + use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; + use rnex_core::rmc::structures::RmcSerialize; + use rnex_core::util::SplittableBufferConnection; use std::env; use std::net::SocketAddrV4; + use std::process::abort; use std::sync::{Arc, LazyLock}; + use tokio::net::UdpSocket; use crate::crypto::{Crypto, Insecure, Secure}; + use crate::packet::PRUDPV0Packet; use crate::server::Server; mod crypto; @@ -31,6 +44,8 @@ cfg_if! { //implementations, e.g. secure and insecure(this also includes special cases like friends) async fn start_proxy(param: ProxyStartupParam) { + info!("creating cryptography instance"); + let mut crypto = Arc::new(T::new()); info!("binding to socket"); let server: Arc> = Arc::new(Server::new(param).await); diff --git a/prudpv0/src/packet.rs b/prudpv0/src/packet.rs index b78102f..50bfe55 100644 --- a/prudpv0/src/packet.rs +++ b/prudpv0/src/packet.rs @@ -1,9 +1,11 @@ +use std::mem::transmute; + use bytemuck::{Pod, Zeroable, try_from_bytes, try_from_bytes_mut}; -use log::{info, warn}; +use log::{error, info, warn}; use rnex_core::prudp::{ types_flags::{ - TypesFlags, - flags::HAS_SIZE, + self, TypesFlags, + flags::{HAS_SIZE, NEED_ACK}, types::{CONNECT, DATA, DISCONNECT, PING, SYN}, }, virtual_port::VirtualPort, @@ -163,7 +165,6 @@ impl> PRUDPV0Packet { const DEFAULT_SIGNAT: [u8; 4] = [0x12, 0x34, 0x56, 0x78]; #[inline(always)] -#[allow(dead_code)] const fn get_size_offset(tf: TypesFlags) -> usize { size_of::() + (if tf.get_types() & (SYN | CONNECT) != 0 { diff --git a/prudpv0/src/server.rs b/prudpv0/src/server.rs index 96b6416..899bbd6 100644 --- a/prudpv0/src/server.rs +++ b/prudpv0/src/server.rs @@ -1,24 +1,32 @@ use std::{ collections::HashMap, - net::{SocketAddr, SocketAddrV4}, - sync::{Arc, Weak}, + hash::Hash, + net::{Ipv4Addr, SocketAddr, SocketAddrV4}, + sync::{ + Arc, LazyLock, Weak, + atomic::{AtomicBool, AtomicU32}, + }, time::Duration, }; use log::{error, info, warn}; use proxy_common::{ProxyStartupParam, new_backend_connection}; use rnex_core::{ + executables::common::{OWN_IP_PRIVATE, SERVER_PORT}, prudp::{ socket_addr::PRUDPSockAddr, types_flags::{ - flags::{ACK, NEED_ACK, RELIABLE}, + TypesFlags, + flags::{ACK, HAS_SIZE, NEED_ACK, RELIABLE}, types::{CONNECT, DATA, DISCONNECT, PING, SYN}, }, + virtual_port::VirtualPort, }, + rnex_proxy_common::ConnectionInitData, util::{SendingBufferConnection, SplittableBufferConnection}, }; use tokio::{ - net::UdpSocket, + net::{TcpSocket, UdpSocket}, spawn, sync::{Mutex, RwLock}, time::{Instant, sleep}, @@ -27,8 +35,8 @@ use tokio::{ use crate::{ crypto::{Crypto, CryptoInstance}, packet::{ - PRUDPV0Packet, new_connect_packet, new_data_packet, new_disconnect_packet, new_ping_packet, - new_syn_packet, + PRUDPV0Header, PRUDPV0Packet, new_connect_packet, new_data_packet, new_disconnect_packet, + new_ping_packet, new_syn_packet, precalc_size, }, }; @@ -41,14 +49,16 @@ pub struct InternalConnection { packet_queue: HashMap>)>, } pub struct Connection { + alive: AtomicBool, session_id: u8, target: SendingBufferConnection, + self_signat: [u8; 4], + remote_signat: [u8; 4], addr: PRUDPSockAddr, inner: Mutex>, } impl InternalConnection { - #[allow(dead_code)] fn next_server_count(&mut self) -> u16 { let prev_val = self.server_packet_counter; let (val, _) = self.server_packet_counter.overflowing_add(1); @@ -138,8 +148,7 @@ impl Server { this.socket .send_to(&data, conn.addr.regular_socket_addr) - .await - .ok(); + .await; break; } @@ -183,8 +192,7 @@ impl Server { self.socket .send_to(&packet, conn.addr.regular_socket_addr) - .await - .ok(); + .await; } if (Instant::now() - inner.last_action).as_secs() > 15 { @@ -202,16 +210,13 @@ impl Server { self.socket .send_to(&packet, conn.addr.regular_socket_addr) - .await - .ok(); + .await; self.socket .send_to(&packet, conn.addr.regular_socket_addr) - .await - .ok(); + .await; self.socket .send_to(&packet, conn.addr.regular_socket_addr) - .await - .ok(); + .await; drop(inner); let mut conns = self.connections.write().await; @@ -231,10 +236,7 @@ impl Server { let signat = [signat[0], signat[1], signat[2], signat[3]]; let packet = new_syn_packet(ACK, header.destination, header.source, signat, &self.crypto); - self.socket - .send_to(&packet, addr.regular_socket_addr) - .await - .ok(); + self.socket.send_to(&packet, addr.regular_socket_addr).await; } async fn handle_connect(self: Arc, packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { let Some(data) = packet.payload() else { @@ -273,8 +275,11 @@ impl Server { let conn = Arc::new(Connection { target: buf_conn.duplicate_sender(), + remote_signat, + self_signat, addr, session_id: header.session_id, + alive: AtomicBool::new(true), inner: Mutex::new(InternalConnection { last_action: Instant::now(), crypto_instance: ci, @@ -315,12 +320,9 @@ impl Server { ); info!("sending back connection accept"); - self.socket - .send_to(&packet, addr.regular_socket_addr) - .await - .ok(); + self.socket.send_to(&packet, addr.regular_socket_addr).await; } - async fn handle_data(self: Arc, packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { + async fn handle_data(self: Arc, mut packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { let Some(frag_id) = packet.fragment_id() else { warn!("invalid packet from: {:?}", addr); return; @@ -347,10 +349,7 @@ impl Server { &mut conn.crypto_instance, &self.crypto, ); - self.socket - .send_to(&ack, addr.regular_socket_addr) - .await - .ok(); + self.socket.send_to(&ack, addr.regular_socket_addr).await; conn.packet_queue.insert( packet.header().unwrap().sequence_id, (Instant::now(), packet), @@ -376,7 +375,7 @@ impl Server { drop(conn); } - async fn handle_ping(self: Arc, packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { + async fn handle_ping(self: Arc, mut packet: PRUDPV0Packet>, addr: PRUDPSockAddr) { info!("got ping"); let header = packet.header().unwrap(); @@ -396,14 +395,11 @@ impl Server { ); drop(inner); - self.socket - .send_to(&packet, addr.regular_socket_addr) - .await - .ok(); + self.socket.send_to(&packet, addr.regular_socket_addr).await; } async fn handle_disconnect( self: Arc, - packet: PRUDPV0Packet>, + mut packet: PRUDPV0Packet>, addr: PRUDPSockAddr, ) { info!("got disconnect"); @@ -429,18 +425,9 @@ impl Server { conns.remove(&(addr, header.session_id)); drop(conns); - self.socket - .send_to(&packet, addr.regular_socket_addr) - .await - .ok(); - self.socket - .send_to(&packet, addr.regular_socket_addr) - .await - .ok(); - self.socket - .send_to(&packet, addr.regular_socket_addr) - .await - .ok(); + self.socket.send_to(&packet, addr.regular_socket_addr).await; + self.socket.send_to(&packet, addr.regular_socket_addr).await; + self.socket.send_to(&packet, addr.regular_socket_addr).await; } async fn get_connection( &self, diff --git a/prudpv1/src/executables/common.rs b/prudpv1/src/executables/common.rs new file mode 100644 index 0000000..8d6f4c1 --- /dev/null +++ b/prudpv1/src/executables/common.rs @@ -0,0 +1,17 @@ +use once_cell::sync::Lazy; +use std::env; +use std::net::SocketAddrV4; + +pub static EDGE_NODE_HOLDER: Lazy = Lazy::new(|| { + env::var("EDGE_NODE_HOLDER") + .ok() + .and_then(|s| s.parse().ok()) + .expect("EDGE_NODE_HOLDER not set") +}); + +pub static FORWARD_DESTINATION: Lazy = Lazy::new(|| { + env::var("FORWARD_DESTINATION") + .ok() + .and_then(|s| s.parse().ok()) + .expect("FORWARD_DESTINATION not set") +}); diff --git a/prudpv1/src/executables/mod.rs b/prudpv1/src/executables/mod.rs index dbcfdd7..2c0d6cf 100644 --- a/prudpv1/src/executables/mod.rs +++ b/prudpv1/src/executables/mod.rs @@ -1,2 +1,3 @@ +pub mod common; pub mod proxy_insecure; pub mod proxy_secure; diff --git a/prudpv1/src/executables/proxy_insecure.rs b/prudpv1/src/executables/proxy_insecure.rs index b9b974c..06299d1 100644 --- a/prudpv1/src/executables/proxy_insecure.rs +++ b/prudpv1/src/executables/proxy_insecure.rs @@ -1,19 +1,45 @@ +use crate::executables::common::{EDGE_NODE_HOLDER, FORWARD_DESTINATION}; use crate::prudp::router::Router; use crate::prudp::unsecure::Unsecure; use log::error; -use proxy_common::{ProxyStartupParam, RNEX_ACCESS_KEY}; +use rnex_core::common::setup; +use rnex_core::executables::common::{OWN_IP_PRIVATE, OWN_IP_PUBLIC, SERVER_PORT}; use rnex_core::prudp::virtual_port::VirtualPort; +use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; +use rnex_core::reggie::RemoteEdgeNodeHolder; use rnex_core::reggie::UnitPacketRead; use rnex_core::reggie::UnitPacketWrite; +use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; use rnex_core::rmc::structures::RmcSerialize; use rnex_core::rnex_proxy_common::ConnectionInitData; +use rnex_core::util::SplittableBufferConnection; +use std::net::SocketAddrV4; +use std::sync::Arc; use std::time::Duration; use tokio::net::TcpStream; use tokio::task; use tokio::time::sleep; +use proxy_common::RNEX_ACCESS_KEY; -pub async fn start(param: ProxyStartupParam) { - let (router_secure, _) = Router::new(param.self_private) +pub async fn start() { + /*let conn = tokio::net::TcpStream::connect(&*EDGE_NODE_HOLDER) + .await + .unwrap(); + + let conn: SplittableBufferConnection = conn.into(); + + conn.send( + Register(SocketAddrV4::new(*OWN_IP_PUBLIC, *SERVER_PORT)) + .to_data() + .unwrap(), + ) + .await; + + let conn = new_rmc_gateway_connection(conn, |r| { + Arc::new(OnlyRemote::::new(r)) + });*/ + + let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) .await .expect("unable to start router"); @@ -22,6 +48,8 @@ pub async fn start(param: ProxyStartupParam) { .await .expect("unable to add socket"); + // let conn = socket_secure.connect(auth_sockaddr).await.unwrap(); + loop { let Some(mut conn) = socket_secure.accept().await else { error!("server crashed"); @@ -29,7 +57,7 @@ pub async fn start(param: ProxyStartupParam) { }; task::spawn(async move { - let mut stream = match TcpStream::connect(param.forward_destination).await { + let mut stream = match TcpStream::connect(*FORWARD_DESTINATION).await { Ok(v) => v, Err(e) => { error!("unable to connect: {}", e); diff --git a/prudpv1/src/executables/proxy_secure.rs b/prudpv1/src/executables/proxy_secure.rs index c338ef9..6bf3434 100644 --- a/prudpv1/src/executables/proxy_secure.rs +++ b/prudpv1/src/executables/proxy_secure.rs @@ -1,21 +1,30 @@ +use crate::executables::common::{EDGE_NODE_HOLDER, FORWARD_DESTINATION}; use crate::prudp::router::Router; use crate::prudp::secure::Secure; use log::error; -use log::warn; -use proxy_common::{ProxyStartupParam, RNEX_ACCESS_KEY}; -use rnex_core::executables::common::SECURE_SERVER_ACCOUNT; +use rnex_core::common::setup; +use rnex_core::executables::common::{ + OWN_IP_PRIVATE, OWN_IP_PUBLIC, SECURE_SERVER_ACCOUNT, SERVER_PORT, +}; use rnex_core::prudp::virtual_port::VirtualPort; +use rnex_core::reggie::EdgeNodeHolderConnectOption::Register; +use rnex_core::reggie::RemoteEdgeNodeHolder; use rnex_core::reggie::UnitPacketRead; use rnex_core::reggie::UnitPacketWrite; +use rnex_core::rmc::protocols::{OnlyRemote, new_rmc_gateway_connection}; use rnex_core::rmc::structures::RmcSerialize; use rnex_core::rnex_proxy_common::ConnectionInitData; +use rnex_core::util::SplittableBufferConnection; +use std::net::SocketAddrV4; +use std::sync::Arc; use std::time::Duration; use tokio::net::TcpStream; use tokio::task; use tokio::time::sleep; +use proxy_common::RNEX_ACCESS_KEY; -pub async fn start(param: ProxyStartupParam) { - let (router_secure, _) = Router::new(param.self_private) +pub async fn start() { + let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SERVER_PORT)) .await .expect("unable to start router"); @@ -27,6 +36,8 @@ pub async fn start(param: ProxyStartupParam) { .await .expect("unable to add socket"); + // let conn = socket_secure.connect(auth_sockaddr).await.unwrap(); + loop { let Some(mut conn) = socket_secure.accept().await else { error!("server crashed"); @@ -34,25 +45,7 @@ pub async fn start(param: ProxyStartupParam) { }; task::spawn(async move { - let Ok(mut c) = rnex_core::grpc::account::Client::new().await else { - error!("failed to initialize gql client"); - return; - }; - - let v = match c.get_user_level(conn.user_id).await { - Ok(v) => v, - Err(e) => { - error!("failed to get user level: {}", e); - return; - } - }; - - if v < 0 { - warn!("person with too low account level joined"); - return; - } - - let mut stream = match TcpStream::connect(param.forward_destination).await { + let mut stream = match TcpStream::connect(*FORWARD_DESTINATION).await { Ok(v) => v, Err(e) => { error!("unable to connect: {}", e); diff --git a/prudpv1/src/lib.rs b/prudpv1/src/lib.rs index a24f714..0660a4b 100644 --- a/prudpv1/src/lib.rs +++ b/prudpv1/src/lib.rs @@ -1,14 +1,14 @@ cfg_if::cfg_if! { if #[cfg(feature = "prudpv1")]{ - use proxy_common::ProxyStartupParam; + use proxy_common::{ProxyStartupParam, setup_edge_node_connection}; pub mod executables; pub mod prudp; pub async fn start_secure(param: ProxyStartupParam) { - executables::proxy_secure::start(param).await; + executables::proxy_secure::start().await; } pub async fn start_insecure(param: ProxyStartupParam) { - executables::proxy_insecure::start(param).await; + executables::proxy_insecure::start().await; } } } diff --git a/prudpv1/src/prudp/packet.rs b/prudpv1/src/prudp/packet.rs index 027c0b4..5a27d33 100644 --- a/prudpv1/src/prudp/packet.rs +++ b/prudpv1/src/prudp/packet.rs @@ -14,7 +14,7 @@ use rnex_core::prudp::socket_addr::PRUDPSockAddr; use rnex_core::prudp::types_flags::TypesFlags; use rnex_core::prudp::types_flags::flags::ACK; use rnex_core::prudp::virtual_port::VirtualPort; -use std::fmt::Debug; +use std::fmt::{Debug, Formatter}; use std::io; use std::io::{Cursor, Read, Seek, Write}; use std::net::SocketAddr; @@ -447,7 +447,7 @@ mod test { let bytes = &bytes[0x6..]; - let _: [u8; 8] = bytes.try_into().unwrap(); + let header_data: [u8; 8] = bytes.try_into().unwrap(); } #[test] diff --git a/prudpv1/src/prudp/secure.rs b/prudpv1/src/prudp/secure.rs index c7d312f..9bd441b 100644 --- a/prudpv1/src/prudp/secure.rs +++ b/prudpv1/src/prudp/secure.rs @@ -1,13 +1,18 @@ use crate::prudp::packet::PRUDPV1Packet; use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance}; use hmac::digest::consts::U32; +use log::error; use rc4::cipher::StreamCipherCoreWrapper; +use rc4::consts::U16; use rc4::{KeyInit, Rc4, Rc4Core, StreamCipher}; +use rnex_core::kerberos::{TicketInternalData, derive_key}; use rnex_core::nex::account::Account; use rnex_core::prudp::encryption::EncryptionPair; use rnex_core::prudp::ticket::read_secure_connection_data; use rnex_core::rmc::structures::RmcSerialize; +use std::io::Cursor; use typenum::U5; +use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; type Rc4U32 = StreamCipherCoreWrapper>; @@ -47,7 +52,6 @@ pub struct SecureInstance { session_key: [u8; 32], streams: Vec>>, self_signature: [u8; 16], - #[allow(dead_code)] remote_signature: [u8; 16], pid: u32, } diff --git a/prudpv1/src/prudp/socket.rs b/prudpv1/src/prudp/socket.rs index c6f5faa..a3b0445 100644 --- a/prudpv1/src/prudp/socket.rs +++ b/prudpv1/src/prudp/socket.rs @@ -16,7 +16,6 @@ use std::io::Cursor; use std::marker::PhantomData; use std::ops::Deref; use std::sync::{Arc, Weak}; -use tokio::spawn; use v_byte_helpers::ReadExtensions; use v_byte_helpers::little_endian::read_u16; @@ -69,33 +68,6 @@ impl InternalConnection { prev_val } - async fn close_connection(&mut self) { - let mut packet = PRUDPV1Packet { - header: PRUDPV1Header { - sequence_id: self.next_server_count(), - substream_id: 0, - session_id: self.session_id, - types_and_flags: TypesFlags::default().types(DISCONNECT), - destination_port: self.common.socket_addr.virtual_port, - source_port: self.server_port, - ..Default::default() - }, - payload: Vec::new(), - options: vec![FragmentId(0)], - ..Default::default() - }; - - // no need for encryption the, the payload is empty - - packet.set_sizes(); - - self.crypto_handler_instance.sign_packet(&mut packet); - - self.send_raw_packet(&packet).await; - - self.delete_connection().await; - } - /// Sends a raw packet to a given client on the connection /// /// a raw packet is one which does not get processed any further(other than to send it @@ -131,7 +103,7 @@ pub struct ExternalConnection { #[derive(Clone)] pub struct SendingConnection { common: Arc, - internal: Weak, + internal: Weak>, } pub struct CommonSocket { @@ -194,67 +166,71 @@ pub(super) trait AnyInternalSocket: } #[async_trait] -pub(super) trait AnyInternalConnection: Send + Sync + 'static { - async fn send_data_packet(&self, data: Vec); +pub(super) trait AnyInternalConnection: + Send + Sync + Deref + 'static +{ + async fn send_data_packet(&mut self, data: Vec); - async fn close_connection(&self); + async fn close_connection(&mut self); } #[async_trait] -impl AnyInternalConnection for Mutex> { - async fn send_data_packet(&self, data: Vec) { - let pieces = data.chunks(600); - let max_piece = pieces.len() - 1; - let mut piece_num = 1; - let mut locked = self.lock().await; - let packets: Vec<_> = pieces - .enumerate() - .map(|(i, piece)| { - let mut packet = PRUDPV1Packet { - header: PRUDPV1Header { - sequence_id: locked.next_server_count(), - substream_id: 0, - session_id: locked.session_id, - types_and_flags: TypesFlags::default() - .types(DATA) - .flags(RELIABLE | NEED_ACK), - destination_port: locked.common.socket_addr.virtual_port, - source_port: locked.server_port, - ..Default::default() - }, - payload: piece.to_owned(), - options: vec![FragmentId(if i == max_piece { 0 } else { piece_num })], - ..Default::default() - }; +impl AnyInternalConnection for InternalConnection { + async fn send_data_packet(&mut self, data: Vec) { + let mut packet = PRUDPV1Packet { + header: PRUDPV1Header { + sequence_id: self.next_server_count(), + substream_id: 0, + session_id: self.session_id, + types_and_flags: TypesFlags::default().types(DATA).flags(RELIABLE | NEED_ACK), + destination_port: self.common.socket_addr.virtual_port, + source_port: self.server_port, + ..Default::default() + }, + payload: data, + options: vec![FragmentId(0)], + ..Default::default() + }; - locked - .crypto_handler_instance - .encrypt_outgoing(0, &mut packet.payload[..]); + self.crypto_handler_instance + .encrypt_outgoing(0, &mut packet.payload[..]); - packet.set_sizes(); + packet.set_sizes(); - locked.crypto_handler_instance.sign_packet(&mut packet); + self.crypto_handler_instance.sign_packet(&mut packet); - piece_num += 1; - packet - }) - .collect(); - drop(locked); + self.send_raw_packet(&packet).await; - for packet in packets { - let mut locked = self.lock().await; - locked.send_raw_packet(&packet).await; - - locked.unacknowleged_packets.push((Instant::now(), packet)); - drop(locked); - sleep(Duration::from_secs(16)).await; - } + self.unacknowleged_packets.push((Instant::now(), packet)); } - async fn close_connection(&self) { - let mut locked = self.lock().await; + async fn close_connection(&mut self) { + // jon confirmed that this should be a safe way to dc a client - locked.close_connection().await; + let mut packet = PRUDPV1Packet { + header: PRUDPV1Header { + sequence_id: self.next_server_count(), + substream_id: 0, + session_id: self.session_id, + types_and_flags: TypesFlags::default().types(DISCONNECT), + destination_port: self.common.socket_addr.virtual_port, + source_port: self.server_port, + ..Default::default() + }, + payload: Vec::new(), + options: vec![FragmentId(0)], + ..Default::default() + }; + + // no need for encryption the, the payload is empty + + packet.set_sizes(); + + self.crypto_handler_instance.sign_packet(&mut packet); + + self.send_raw_packet(&packet).await; + + self.delete_connection().await; } } @@ -418,7 +394,7 @@ impl InternalSocket { let internal = Arc::new(Mutex::new(internal)); - let dyn_internal: Arc = internal.clone(); + let dyn_internal: Arc> = internal.clone(); let external = ExternalConnection { sending: SendingConnection { @@ -899,9 +875,10 @@ impl ExternalConnection { impl SendingConnection { pub async fn send(&self, data: Vec) -> Option<()> { let internal = self.internal.upgrade()?; - spawn(async move { - internal.send_data_packet(data).await; - }); + + let mut internal = internal.lock().await; + + internal.send_data_packet(data).await; Some(()) } @@ -910,6 +887,8 @@ impl SendingConnection { return; }; + let mut internal = internal.lock().await; + internal.close_connection().await; } } diff --git a/prudpv1/src/prudp/unsecure.rs b/prudpv1/src/prudp/unsecure.rs index 79cc908..d47550f 100644 --- a/prudpv1/src/prudp/unsecure.rs +++ b/prudpv1/src/prudp/unsecure.rs @@ -1,6 +1,7 @@ use crate::prudp::packet::PRUDPV1Packet; use crate::prudp::socket::{CryptoHandler, CryptoHandlerConnectionInstance}; -use rc4::{KeyInit, Rc4, StreamCipher}; +use once_cell::sync::Lazy; +use rc4::{Key, KeyInit, Rc4, StreamCipher}; use rnex_core::prudp::encryption::{DEFAULT_KEY, EncryptionPair}; use typenum::U5; @@ -10,7 +11,6 @@ pub struct UnsecureInstance { key: &'static str, streams: Vec>>, self_signature: [u8; 16], - #[allow(dead_code)] remote_signature: [u8; 16], } diff --git a/rnex-core/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json b/rnex-core/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json new file mode 100644 index 0000000..abf5c03 --- /dev/null +++ b/rnex-core/.sqlx/query-164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9.json @@ -0,0 +1,28 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT owner, under_review FROM datastore.objects WHERE data_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "owner", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "under_review", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + true, + false + ] + }, + "hash": "164708b549c483a041d2e54065ed3ffbd9f8d5304f6aa6d785dbddbb1626c0e9" +} diff --git a/rnex-core/.sqlx/query-1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703.json b/rnex-core/.sqlx/query-1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703.json new file mode 100644 index 0000000..befa7e1 --- /dev/null +++ b/rnex-core/.sqlx/query-1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703.json @@ -0,0 +1,112 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date\n FROM datastore.objects WHERE data_id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "owner", + "type_info": "Int4" + }, + { + "ordinal": 2, + "name": "size", + "type_info": "Int4" + }, + { + "ordinal": 3, + "name": "name", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "data_type", + "type_info": "Int4" + }, + { + "ordinal": 5, + "name": "meta_binary", + "type_info": "Bytea" + }, + { + "ordinal": 6, + "name": "permission", + "type_info": "Int4" + }, + { + "ordinal": 7, + "name": "permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 8, + "name": "delete_permission", + "type_info": "Int4" + }, + { + "ordinal": 9, + "name": "delete_permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 10, + "name": "period", + "type_info": "Int4" + }, + { + "ordinal": 11, + "name": "refer_data_id", + "type_info": "Int8" + }, + { + "ordinal": 12, + "name": "flag", + "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "tags", + "type_info": "TextArray" + }, + { + "ordinal": 14, + "name": "creation_date", + "type_info": "Timestamp" + }, + { + "ordinal": 15, + "name": "update_date", + "type_info": "Timestamp" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true + ] + }, + "hash": "1c2be699b4bfc7e5e6d3a74d7badf67d1812b99e1ec952a044fc03e1a5c63703" +} diff --git a/rnex-core/.sqlx/query-219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c.json b/rnex-core/.sqlx/query-219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c.json new file mode 100644 index 0000000..cf80412 --- /dev/null +++ b/rnex-core/.sqlx/query-219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO datastore.objects (\n owner, size, name, data_type, meta_binary,\n permission, permission_recipients,\n delete_permission, delete_permission_recipients,\n flag, period, refer_data_id, tags,\n persistence_slot_id, extra_data, creation_date, update_date\n ) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17\n ) RETURNING data_id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int4", + "Int4", + "Text", + "Int4", + "Bytea", + "Int4", + "Int4Array", + "Int4", + "Int4Array", + "Int4", + "Int4", + "Int8", + "TextArray", + "Int4", + "TextArray", + "Timestamp", + "Timestamp" + ] + }, + "nullable": [ + false + ] + }, + "hash": "219fec3fc852f36de99e5f00ca7a1675439bb44c91158f8b8a696e326c45447c" +} diff --git a/rnex-core/.sqlx/query-29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4.json b/rnex-core/.sqlx/query-29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4.json new file mode 100644 index 0000000..0c3393d --- /dev/null +++ b/rnex-core/.sqlx/query-29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO datastore.object_custom_rankings (data_id, application_id, value)\n VALUES ($1, $2, $3)\n ON CONFLICT (data_id, application_id)\n DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Int8", + "Int8" + ] + }, + "nullable": [] + }, + "hash": "29d4f5c07b36c3d3b6b54a86a1757f27247530878b7f82feeb65802d995a38c4" +} diff --git a/rnex-core/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json b/rnex-core/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json new file mode 100644 index 0000000..83246ca --- /dev/null +++ b/rnex-core/.sqlx/query-2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + null + ] + }, + "hash": "2ff34379bbc32276c3b78ef1283b8158ea907d36588e1e59f6cbe752d89361bb" +} diff --git a/rnex-core/.sqlx/query-37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json b/rnex-core/.sqlx/query-37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json new file mode 100644 index 0000000..35c78ee --- /dev/null +++ b/rnex-core/.sqlx/query-37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT data_id\n FROM datastore.objects\n WHERE owner = $1 AND data_type > 2 AND data_type < 50\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int4" + ] + }, + "nullable": [ + false + ] + }, + "hash": "37d449b81e2aa3abdbdaf38587ae1a6a6c5c38acb06d91c5b0924c3f0a5d2e92" +} diff --git a/rnex-core/.sqlx/query-3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json b/rnex-core/.sqlx/query-3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json new file mode 100644 index 0000000..166c25d --- /dev/null +++ b/rnex-core/.sqlx/query-3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT buffer\n FROM datastore.buffer_queues\n WHERE data_id = $1 AND slot = $2\n ORDER BY creation_date ASC\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "buffer", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [ + "Int8", + "Int4" + ] + }, + "nullable": [ + false + ] + }, + "hash": "3d06238fddc72d1ba452602e1a8002e9186ce1dfc6c68b52d9d2a8a38f5c3a1f" +} diff --git a/rnex-core/.sqlx/query-8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79.json b/rnex-core/.sqlx/query-8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79.json new file mode 100644 index 0000000..dd1c783 --- /dev/null +++ b/rnex-core/.sqlx/query-8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79.json @@ -0,0 +1,29 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT\n rankings.data_id,\n rankings.value\n FROM datastore.object_custom_rankings rankings\n JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord)\n ON rankings.data_id = rows.data_id\n AND rankings.application_id = $2\n ORDER BY rows.ord\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "value", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8Array", + "Int8" + ] + }, + "nullable": [ + false, + true + ] + }, + "hash": "8605011b998a4608c739bf5ab388a7a9bf551126712c1d1089a4263453090e79" +} diff --git a/rnex-core/.sqlx/query-8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d.json b/rnex-core/.sqlx/query-8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d.json new file mode 100644 index 0000000..dbab55e --- /dev/null +++ b/rnex-core/.sqlx/query-8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d.json @@ -0,0 +1,40 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT slot, total_value, count, initial_value\n FROM datastore.object_ratings\n WHERE data_id = $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "slot", + "type_info": "Int2" + }, + { + "ordinal": 1, + "name": "total_value", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "count", + "type_info": "Int4" + }, + { + "ordinal": 3, + "name": "initial_value", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + true, + false, + true + ] + }, + "hash": "8706ac06d78ffaa2a45418be7ae71340561031d8e5c91f46c041f83e54c31a7d" +} diff --git a/rnex-core/.sqlx/query-93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb.json b/rnex-core/.sqlx/query-93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb.json new file mode 100644 index 0000000..0a8127b --- /dev/null +++ b/rnex-core/.sqlx/query-93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb.json @@ -0,0 +1,28 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT under_review, access_password\n FROM datastore.objects\n WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "under_review", + "type_info": "Bool" + }, + { + "ordinal": 1, + "name": "access_password", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + false, + false + ] + }, + "hash": "93be6b6b0ac5d85881e6e223a7d48f5eb4a3761dd71129ba6939cdd0d62569fb" +} diff --git a/rnex-core/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json b/rnex-core/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json new file mode 100644 index 0000000..552f92a --- /dev/null +++ b/rnex-core/.sqlx/query-e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [] + }, + "hash": "e28d8776cc49b55fe76cf33ac12fe18e500d243f1b55fd18e7d96d281605bcf9" +} diff --git a/rnex-core/.sqlx/query-efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c.json b/rnex-core/.sqlx/query-efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c.json new file mode 100644 index 0000000..60714c0 --- /dev/null +++ b/rnex-core/.sqlx/query-efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c.json @@ -0,0 +1,125 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT data_id, owner, size, name, data_type, meta_binary,\n permission, permission_recipients, delete_permission, delete_permission_recipients,\n period, refer_data_id, flag, tags, creation_date, update_date,\n access_password, under_review\n FROM datastore.objects\n WHERE owner = $1 AND persistence_slot_id = $2\n AND upload_completed = TRUE AND deleted = FALSE", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "data_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "owner", + "type_info": "Int4" + }, + { + "ordinal": 2, + "name": "size", + "type_info": "Int4" + }, + { + "ordinal": 3, + "name": "name", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "data_type", + "type_info": "Int4" + }, + { + "ordinal": 5, + "name": "meta_binary", + "type_info": "Bytea" + }, + { + "ordinal": 6, + "name": "permission", + "type_info": "Int4" + }, + { + "ordinal": 7, + "name": "permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 8, + "name": "delete_permission", + "type_info": "Int4" + }, + { + "ordinal": 9, + "name": "delete_permission_recipients", + "type_info": "Int4Array" + }, + { + "ordinal": 10, + "name": "period", + "type_info": "Int4" + }, + { + "ordinal": 11, + "name": "refer_data_id", + "type_info": "Int8" + }, + { + "ordinal": 12, + "name": "flag", + "type_info": "Int4" + }, + { + "ordinal": 13, + "name": "tags", + "type_info": "TextArray" + }, + { + "ordinal": 14, + "name": "creation_date", + "type_info": "Timestamp" + }, + { + "ordinal": 15, + "name": "update_date", + "type_info": "Timestamp" + }, + { + "ordinal": 16, + "name": "access_password", + "type_info": "Int8" + }, + { + "ordinal": 17, + "name": "under_review", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Int4", + "Int4" + ] + }, + "nullable": [ + false, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + true, + false, + false + ] + }, + "hash": "efe4bf3602782a0d521274956e0fcecccf8f0f8dd20d890a76acf85265b2192c" +} diff --git a/rnex-core/Cargo.toml b/rnex-core/Cargo.toml index f30c47c..620357b 100644 --- a/rnex-core/Cargo.toml +++ b/rnex-core/Cargo.toml @@ -34,7 +34,6 @@ aws-config = { version = "1.8.15", optional = true } base64 = "0.22.1" sha2 = "0.10.9" urlencoding = "2.1.3" -futures = "0.3.32" [dev-dependencies] # criterion = "0.7.0" @@ -42,19 +41,12 @@ futures = "0.3.32" [features] rmc_struct_header = [] guest_login = [] -friends = ["guest_login", "database-support"] +friends = ["guest_login"] big_pid = [] -v3-3-2 = [] -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"] +v3-8-15 = ["rmc_struct_header"] 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"] +datastore = ["dep:sqlx", "v3-8-15", "dep:aws-sdk-s3", "dep:aws-config"] [[bench]] name = "rmc_serialization" diff --git a/rnex-core/src/executables/backend_server_secure.rs b/rnex-core/src/executables/backend_server_secure.rs index 88f2508..cbb64d8 100644 --- a/rnex-core/src/executables/backend_server_secure.rs +++ b/rnex-core/src/executables/backend_server_secure.rs @@ -1,5 +1,13 @@ use cfg_if::cfg_if; use rnex_core::common::setup; +use rnex_core::executables::common::new_simple_backend; +use rnex_core::executables::friends_backend::start_friends_backend; +use rnex_core::nex::matchmake::MatchmakeManager; +use rnex_core::nex::remote_console::RemoteConsole; +use rnex_core::nex::user::User; +use rnex_core::rmc::protocols::{RemoteDisconnectable, RmcPureRemoteObject}; +use std::sync::Arc; +use std::sync::atomic::AtomicU32; #[tokio::main] async fn main() { @@ -7,7 +15,6 @@ async fn main() { cfg_if! { if #[cfg(feature = "friends")]{ - use rnex_core::executables::friends_backend::start_friends_backend; start_friends_backend().await; } else if #[cfg(feature = "datastore")] { use rnex_core::executables::common::DB_POOL; diff --git a/rnex-core/src/executables/common.rs b/rnex-core/src/executables/common.rs index c94a463..280ab7f 100644 --- a/rnex-core/src/executables/common.rs +++ b/rnex-core/src/executables/common.rs @@ -8,21 +8,23 @@ use std::io::Cursor; use std::net::{Ipv4Addr, SocketAddrV4}; use std::sync::Arc; use tokio::net::TcpListener; +use std::sync::LazyLock; +use std::sync::OnceLock; cfg_if! { if #[cfg(feature = "datastore")] { use sqlx::postgres::PgPool; } } -use crate::reggie::UnitPacketRead; -use cfg_if::cfg_if; use log::error; use std::error::Error; +use std::string::ToString; +use cfg_if::cfg_if; +use crate::reggie::UnitPacketRead; const IP_REQ_SERVICE_URL: &str = "https://ipinfo.io/ip"; cfg_if! { if #[cfg(feature = "datastore")] { - use std::sync::{LazyLock, OnceLock}; pub static RNEX_DATASTORE_DATABASE_URL: LazyLock = LazyLock::new(|| { std::env::var("RNEX_DATASTORE_DATABASE_URL") .expect("RNEX_DATASTORE_DATABASE_URL must be set") diff --git a/rnex-core/src/executables/friends_backend.rs b/rnex-core/src/executables/friends_backend.rs index d2ce497..5dfcf02 100644 --- a/rnex-core/src/executables/friends_backend.rs +++ b/rnex-core/src/executables/friends_backend.rs @@ -8,11 +8,15 @@ use log::error; use tokio::net::TcpListener; use crate::{ - executables::common::{OWN_IP_PRIVATE, SERVER_PORT}, - nex::friends_handler::{FriendsGuest, FriendsManager, FriendsUser, RemoteFriendRemote}, + executables::common::{OWN_IP_PRIVATE, SERVER_PORT, new_simple_backend}, + nex::friends_handler::{ + FriendsGuest, FriendsManager, FriendsUser, RemoteFriendRemote, RemoteFriendsUser, + }, reggie::UnitPacketRead, rmc::{ - protocols::{RmcPureRemoteObject, new_rmc_gateway_connection}, + protocols::{ + RmcCallable, RmcPureRemoteObject, friends::RemoteFriends, new_rmc_gateway_connection, + }, structures::RmcSerialize, }, rnex_proxy_common::ConnectionInitData, @@ -61,8 +65,8 @@ pub async fn start_friends_backend() { }) }); } else { - new_rmc_gateway_connection(stream.into(), move |_| { - Arc::new_cyclic(move |_| FriendsGuest { + new_rmc_gateway_connection(stream.into(), move |r| { + Arc::new_cyclic(move |this| FriendsGuest { fm, addr: c.prudpsock_addr, }) diff --git a/rnex-core/src/executables/mod.rs b/rnex-core/src/executables/mod.rs index 83a9df5..cc9b83d 100644 --- a/rnex-core/src/executables/mod.rs +++ b/rnex-core/src/executables/mod.rs @@ -1,10 +1,3 @@ -use cfg_if::cfg_if; - pub mod common; -cfg_if! { - if #[cfg(feature = "friends")]{ - pub mod friends_backend; - } else { - pub mod regular_backend; - } -} +pub mod friends_backend; +pub mod regular_backend; diff --git a/rnex-core/src/executables/regular_backend.rs b/rnex-core/src/executables/regular_backend.rs index 7f62864..65cb2ca 100644 --- a/rnex-core/src/executables/regular_backend.rs +++ b/rnex-core/src/executables/regular_backend.rs @@ -11,7 +11,6 @@ pub async fn start_regular_backend() { //gid_counter: AtomicU32::new(1), sessions: Default::default(), users: Default::default(), - users_by_pid: Default::default(), rv_cid_counter: AtomicU32::new(1), }); diff --git a/rnex-core/src/grpc/account.rs b/rnex-core/src/grpc/account.rs index 9d2d4e8..d6ad140 100644 --- a/rnex-core/src/grpc/account.rs +++ b/rnex-core/src/grpc/account.rs @@ -103,41 +103,6 @@ impl Client { Ok(val.as_bytes().try_into().map_err(|_| SomethingHappened)?) } - pub async fn get_user_level(&mut self, pid: PID) -> Result { - let req = self - .do_request(object! { - "query": r"query($pid: Int!){ - userByPid(pid: $pid){ - accountLevel - } - }", - "variables": { - "pid": pid - } - }) - .await?; - - let Some(val) = req - .entries() - .find(|v| v.0 == "data") - .ok_or(SomethingHappened)? - .1 - .entries() - .find(|v| v.0 == "userByPid") - .ok_or(SomethingHappened)? - .1 - .entries() - .find(|v| v.0 == "accountLevel") - .ok_or(SomethingHappened)? - .1 - .as_i32() - else { - return Err(SomethingHappened); - }; - - Ok(val) - } - pub async fn get_pid_from_token(&mut self, token: String) -> Result { let req = self .do_request(object! { diff --git a/rnex-core/src/kerberos/mod.rs b/rnex-core/src/kerberos/mod.rs index 3512eb6..00f775d 100644 --- a/rnex-core/src/kerberos/mod.rs +++ b/rnex-core/src/kerberos/mod.rs @@ -18,13 +18,13 @@ use rnex_core::PID; cfg_if! { if #[cfg(feature = "friends")]{ - pub type SessionLengthTy = U16; + pub type SESSION_KEY_LENGTH_TY = U16; } else { use rc4::consts::U32; - pub type SessionLengthTy = U32; + pub type SESSION_KEY_LENGTH_TY = U32; } } -pub const SESSION_KEY_LENGTH: usize = SessionLengthTy::USIZE; +pub const SESSION_KEY_LENGTH: usize = SESSION_KEY_LENGTH_TY::USIZE; type Md5Hmac = Hmac; diff --git a/rnex-core/src/main.rs b/rnex-core/src/main.rs new file mode 100644 index 0000000..eda5915 --- /dev/null +++ b/rnex-core/src/main.rs @@ -0,0 +1,127 @@ +#![allow(dead_code)] +#![allow(async_fn_in_trait)] +//#![warn(missing_docs)] + +//! # Splatoon RNEX server +//! +//! This server still includes the code for rnex itself as this is the first rnex server and thus +//! also the first and only current usage of rnex, expect this and rnex to be split into seperate +//! repos soon. + +extern crate self as rust_nex; + +use once_cell::sync::Lazy; +use std::hint::black_box; + +mod prudp; +pub mod rmc; +//mod protocols; + +mod grpc; +mod kerberos; +mod nex; +mod result; +mod versions; +pub mod reggie; +pub mod util; +pub mod common; + +pub mod config{ + pub const FEATURE_HAS_STRUCT_HEADER: bool = cfg!(feature = "rmc_struct_header"); +} + +use std::io::Cursor; +use std::ops::Deref; +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, Gathering, MatchmakeParam, MatchmakeSession, MatchmakeSessionSearchCriteria}; +use rnex_core::rmc::structures::RmcSerialize; +use rnex_core::rmc::structures::variant::Variant; + +static DUMMY: Lazy = Lazy::new(|| AutoMatchmakeParam{ + additional_participants: vec![1,2,3,4], + auto_matchmake_option: 10, + gid_for_participation_check: 9, + join_message: "hi".to_string(), + participation_count: 32, + target_gids: vec![45,2,51,1,1,1,1], + search_criteria: vec![MatchmakeSessionSearchCriteria{ + attribs: vec!["hi".to_string(), "ig".to_string(), "gotta put data here".to_string()], + exclude_locked: true, + exclude_non_host_pid: false, + exclude_system_password_set: true, + exclude_user_password_set: false, + game_mode: "some gamemode".to_string(), + matchmake_param: MatchmakeParam{ + params: vec![ + ("SR".to_string(), Variant::Bool(true)), + ("SR2".to_string(), Variant::Double(1.0)), + ("SR3".to_string(), Variant::SInt64(42)), + ("SR4".to_string(), Variant::String("test".to_string())) + ] + }, + matchmake_system_type: "some type".to_string(), + maximum_participants: "???".to_string(), + minimum_participants: "-99".to_string(), + refer_gid: 123, + selection_method: 9999999, + vacant_only: true, + vacant_participants: 1000 + }], + matchmake_session: MatchmakeSession{ + refer_gid: 10, + matchmake_system_type: 139, + matchmake_param: MatchmakeParam{ + params: vec![ + ("QSR".to_string(), Variant::Bool(false)), + ("SRQ2".to_string(), Variant::Double(1.1)), + ("SQR3".to_string(), Variant::SInt64(422)), + ("SDR4".to_string(), Variant::String("tetst".to_string())) + ] + }, + participation_count: 99, + application_buffer: vec![1,2,3,4,5,6,7,8,9], + attributes: vec![10,20,99,100000], + datetime: KerberosDateTime::now(), + gamemode: 111, + open_participation: false, + option0: 100, + progress_score: 1, + system_password_enabled: false, + user_password: "aaa".to_string(), + session_key: vec![91,123,5,2,1,2,4,124,4], + user_password_enabled: false, + gathering: Gathering{ + minimum_participants: 1, + maximum_participants: 12, + description: "aaargh".to_string(), + flags: 100, + host_pid: 999999919, + owner_pid: 138830, + participant_policy: 1, + policy_argument: 99837, + self_gid: 129, + state: 1389488 + } + } +}); + +static DUMMY_SER: Lazy> = Lazy::new(|| serialize_to_vec(DUMMY.deref())); + +fn serialize_to_vec(r: &impl RmcSerialize) -> Vec{ + let vec = r.to_data(); + + vec.unwrap() +} + +fn read_struct(r: &[u8]) -> T{ + T::deserialize(&mut Cursor::new(r)).unwrap() +} + +fn main(){ + for _ in 0..10000000 { + let v = serialize_to_vec(black_box(DUMMY.deref())); + let u = read_struct::(black_box(DUMMY_SER.deref().as_slice())); + black_box(v); + black_box(u); + } +} \ No newline at end of file diff --git a/rnex-core/src/nex/auth_handler.rs b/rnex-core/src/nex/auth_handler.rs index a5ffe2b..341dc93 100644 --- a/rnex-core/src/nex/auth_handler.rs +++ b/rnex-core/src/nex/auth_handler.rs @@ -129,7 +129,7 @@ impl AuthHandler { }; let Ok(passwd) = client.get_nex_password(pid).await else { - warn!("unable to get nex password for pid: {}:", pid); + warn!("unable to get nex password"); return Err(ErrorCode::Core_Exception); }; @@ -337,3 +337,82 @@ impl Auth for AuthHandler { Err(ErrorCode::Core_Exception) } } + +mod test { + use std::io::Cursor; + + use rc4::{KeyInit, Rc4, StreamCipher}; + use rnex_core::PID; + use rnex_core::kerberos::KerberosDateTime; + use rnex_core::rmc::structures::connection_data::ConnectionData; + use rnex_core::rmc::{ + response::ErrorCode, + structures::{RmcSerialize, qresult::QResult}, + }; + + use crate::kerberos::{self, derive_key}; + use crate::rmc; + use crate::rmc::message::RMCMessage; + use crate::rmc::response::{RMCResponse, RMCResponseResult}; + + #[test] + fn test() { + return; + let packet = [ + 26, 1, 0, 0, 10, 1, 30, 0, 0, 0, 1, 128, 0, 0, 1, 0, 1, 0, 86, 4, 0, 0, 116, 0, 0, 0, + 144, 209, 130, 175, 45, 215, 95, 55, 226, 192, 51, 54, 201, 84, 118, 150, 159, 164, 32, + 103, 134, 252, 199, 168, 178, 5, 6, 208, 206, 241, 94, 23, 136, 37, 109, 247, 156, 252, + 189, 233, 142, 115, 206, 72, 180, 57, 106, 223, 37, 59, 144, 208, 250, 197, 51, 202, + 185, 156, 51, 159, 219, 117, 250, 103, 184, 1, 103, 108, 15, 14, 174, 160, 192, 146, + 135, 10, 55, 125, 68, 181, 88, 127, 183, 34, 4, 213, 19, 146, 81, 56, 248, 213, 241, + 168, 205, 253, 29, 10, 123, 198, 177, 157, 247, 209, 113, 167, 231, 42, 214, 15, 12, + 200, 192, 230, 125, 227, 74, 0, 112, 114, 117, 100, 112, 115, 58, 47, 80, 73, 68, 61, + 50, 59, 115, 105, 100, 61, 49, 59, 115, 116, 114, 101, 97, 109, 61, 49, 48, 59, 116, + 121, 112, 101, 61, 50, 59, 97, 100, 100, 114, 101, 115, 115, 61, 57, 49, 46, 57, 56, + 46, 49, 50, 56, 46, 56, 54, 59, 112, 111, 114, 116, 61, 54, 48, 48, 49, 59, 67, 73, 68, + 61, 49, 0, 0, 0, 0, 0, 1, 0, 0, 162, 243, 240, 168, 31, 0, 0, 0, 51, 0, 98, 114, 97, + 110, 99, 104, 58, 111, 114, 105, 103, 105, 110, 47, 112, 114, 111, 106, 101, 99, 116, + 47, 119, 117, 112, 45, 97, 103, 109, 106, 32, 98, 117, 105, 108, 100, 58, 51, 95, 56, + 95, 49, 53, 95, 50, 48, 48, 52, 95, 48, 0, + ]; + let rmc_packet = RMCResponse::new(&mut Cursor::new(&packet)).unwrap(); + println!("{:?}", rmc_packet); + + let RMCResponseResult::Success { + call_id, + method_id, + data, + } = rmc_packet.response_result + else { + panic!(); + }; + + println!("{}", hex::encode(&data)); + + let mut data = + <(QResult, PID, Vec, ConnectionData, String) as RmcSerialize>::deserialize( + &mut Cursor::new(&data[..]), + ) + .unwrap(); + + println!("{:?}", data); + + let key = derive_key(1110, "AAAAAAAAAAAAAAAA".as_bytes()); + + let mut rc4 = Rc4::new((&key).into()); + + rc4.apply_keystream(&mut data.2); + println!("raw tick: {:?}", data.2); + + let tick: &kerberos::Ticket = + bytemuck::from_bytes(&data.2[..size_of::()]); + + let remainder = &data.2[size_of::()..]; + + println!("tick: {:?}", tick); + let data = as RmcSerialize>::deserialize(&mut Cursor::new(remainder)).unwrap(); + println!("inner ticket raw: {:?}", data); + + println!("{:?}", data); + } +} diff --git a/rnex-core/src/nex/datastore.rs b/rnex-core/src/nex/datastore.rs index fad7300..763bc3e 100644 --- a/rnex-core/src/nex/datastore.rs +++ b/rnex-core/src/nex/datastore.rs @@ -1,144 +1,140 @@ -use crate::nex::user::User; -use rnex_core::executables::common::{ - RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db, -}; -use rnex_core::kerberos::KerberosDateTime; -use rnex_core::nex::s3presigner::S3Presigner; -use rnex_core::rmc::protocols::datastore::{ - BufferQueueParam, CompletePostParam, DataStoreCustomRankingResult, - DataStoreGetCustomRankingByDataIDParam, DataStorePrepareGetParam, DataStoreReqGetInfo, - DataStoreSearchParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, - RateCustomRankingParam, RatingInfo, RatingInfoWithSlot, -}; -use rnex_core::rmc::protocols::datastore::{DataStore, PreparePostParam, ReqPostInfo}; -use rnex_core::rmc::response::ErrorCode; -use rnex_core::rmc::structures::qbuffer::QBuffer; -use rnex_core::rmc::structures::qresult::QResult; -use sqlx::types::time; +use cfg_if::cfg_if; +cfg_if! { + if #[cfg(feature = "datastore")] { + use crate::define_rmc_proto; + use macros::rmc_struct; + use rnex_core::prudp::socket_addr::PRUDPSockAddr; + use std::sync::{Weak}; + use chrono::Utc; + use sqlx::types::time; + use sqlx::types::time::PrimitiveDateTime; + use rnex_core::PID; + use rnex_core::nex::remote_console::RemoteConsole; + use rnex_core::nex::s3presigner::S3Presigner; + use rnex_core::rmc::response::ErrorCode; + use rnex_core::rmc::protocols::secure::{Secure, RawSecure, RawSecureInfo, RemoteSecure}; + use rnex_core::rmc::protocols::datastore::{BufferQueueParam, CompletePostParam, DataStoreCustomRankingResult, DataStoreGetCustomRankingByDataIDParam, DataStorePrepareGetParam, DataStoreReqGetInfo, DataStoreSearchParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, PersistenceTarget, RateCustomRankingParam, RatingInfo, RatingInfoWithSlot}; + use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore, PreparePostParam, ReqPostInfo}; + use crate::nex::user::User; + use rnex_core::executables::common::{RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db}; + use rnex_core::rmc::structures::qbuffer::QBuffer; + use sqlx::types::chrono::DateTime; + use rnex_core::kerberos::KerberosDateTime; + use rnex_core::rmc::structures::qresult::QResult; -fn map_row_to_meta_info( - row_data_id: i64, - row_owner: i32, - row_size: i32, - row_name: String, - row_data_type: i16, - row_meta_binary: Vec, - row_permission: i16, - row_permission_recipients: Vec, - row_delete_permission: i16, - row_delete_permission_recipients: Vec, - row_period: i16, - row_refer_data_id: i64, - row_flag: i32, - row_tags: Vec, - row_creation_date: chrono::NaiveDateTime, - row_update_date: chrono::NaiveDateTime, - ratings: Vec, -) -> GetMetaInfo { - GetMetaInfo { - dataid: row_data_id as u64, - owner: row_owner as u32, - size: row_size as u32, - name: row_name, - data_type: row_data_type as u16, - meta_binary: QBuffer(row_meta_binary), - permission: Permission { - permission: row_permission as u8, - recipient_ids: row_permission_recipients - .into_iter() - .map(|id| id as u32) - .collect(), - }, - del_permission: Permission { - permission: row_delete_permission as u8, - recipient_ids: row_delete_permission_recipients - .into_iter() - .map(|id| id as u32) - .collect(), - }, - period: row_period as u16, - status: 0, - referred_count: 0, - refer_dat_id: row_refer_data_id as u32, - flag: row_flag as u32, - tags: row_tags, - expire_time: KerberosDateTime::from_u64(0x9C3F3E0000), - created_time: KerberosDateTime::from_naive(row_creation_date), - updated_time: KerberosDateTime::from_naive(row_update_date), - referred_time: KerberosDateTime::from_naive(row_creation_date), - ratings, - } -} + fn map_row_to_meta_info( + row_data_id: i64, + row_owner: i32, + row_size: i32, + row_name: String, + row_data_type: i16, + row_meta_binary: Vec, + row_permission: i16, + row_permission_recipients: Vec, + row_delete_permission: i16, + row_delete_permission_recipients: Vec, + row_period: i16, + row_refer_data_id: i64, + row_flag: i32, + row_tags: Vec, + row_creation_date: chrono::NaiveDateTime, + row_update_date: chrono::NaiveDateTime, + ratings: Vec + ) -> GetMetaInfo { + GetMetaInfo { + dataid: row_data_id as u64, + owner: row_owner as u32, + size: row_size as u32, + name: row_name, + data_type: row_data_type as u16, + meta_binary: QBuffer(row_meta_binary), + permission: Permission { + permission: row_permission as u8, + recipient_ids: row_permission_recipients.into_iter().map(|id| id as u32).collect(), + }, + del_permission: Permission { + permission: row_delete_permission as u8, + recipient_ids: row_delete_permission_recipients.into_iter().map(|id| id as u32).collect(), + }, + period: row_period as u16, + status: 0, + referred_count: 0, + refer_dat_id: row_refer_data_id as u32, + flag: row_flag as u32, + tags: row_tags, + expire_time: KerberosDateTime::from_u64(0x9C3F3E0000), + created_time: KerberosDateTime::from_naive(row_creation_date), + updated_time: KerberosDateTime::from_naive(row_update_date), + referred_time: KerberosDateTime::from_naive(row_creation_date), + ratings, + } + } -async fn check_object_availability(data_id: u64, password: u64) -> Result<(), ErrorCode> { - let row = sqlx::query!( - r#" + async fn check_object_availability(data_id: u64, password: u64) -> Result<(), ErrorCode> { + let row = sqlx::query!( + r#" SELECT under_review, access_password FROM datastore.objects WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE "#, - data_id as i64 - ) - .fetch_optional(get_db()) - .await - .map_err(|e| { - eprintln!("Availability check DB error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })? - .ok_or(ErrorCode::DataStore_NotFound)?; + data_id as i64 + ) + .fetch_optional(get_db()) + .await + .map_err(|e| { + eprintln!("Availability check DB error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })? + .ok_or(ErrorCode::DataStore_NotFound)?; - let access_password = row.access_password as u64; - if access_password != 0 && access_password != password { - return Err(ErrorCode::DataStore_InvalidPassword); - } + let access_password = row.access_password as u64; + if access_password != 0 && access_password != password { + return Err(ErrorCode::DataStore_InvalidPassword); + } - if row.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } + if row.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } - Ok(()) -} + Ok(()) + } -async fn get_object_ratings( - data_id: u64, - password: u64, -) -> Result, ErrorCode> { - check_object_availability(data_id, password).await?; + async fn get_object_ratings(data_id: u64, password: u64) -> Result, ErrorCode> { + check_object_availability(data_id, password).await?; - let rows = sqlx::query!( - r#" + let rows = sqlx::query!( + r#" SELECT slot, total_value, count, initial_value FROM datastore.object_ratings WHERE data_id = $1 "#, - data_id as i64 - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - eprintln!("Ratings fetch error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; + data_id as i64 + ) + .fetch_all(get_db()) + .await + .map_err(|e| { + eprintln!("Ratings fetch error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; - let ratings = rows - .into_iter() - .map(|row| RatingInfoWithSlot { - slot: row.slot as i8, - rating: RatingInfo { - total_value: row.total_value.unwrap_or(0), - count: row.count as u32, - initial_value: row.initial_value.unwrap_or(0), - }, - }) - .collect(); + let ratings = rows.into_iter().map(|row| { + RatingInfoWithSlot { + slot: row.slot as i8, + rating: RatingInfo { + total_value: row.total_value.unwrap_or(0), + count: row.count as u32, + initial_value: row.initial_value.unwrap_or(0), + }, + } + }).collect(); - Ok(ratings) -} + Ok(ratings) + } -async fn get_object_info_by_data_id(data_id: u64, password: u64) -> Result { - check_object_availability(data_id, password).await?; + async fn get_object_info_by_data_id(data_id: u64, password: u64) -> Result { + check_object_availability(data_id, password).await?; - let row = sqlx::query!( + let row = sqlx::query!( r#"SELECT data_id, owner, size, name, data_type, meta_binary, permission, permission_recipients, delete_permission, delete_permission_recipients, period, refer_data_id, flag, tags, creation_date, update_date @@ -150,68 +146,37 @@ async fn get_object_info_by_data_id(data_id: u64, password: u64) -> Result Result { - let row = sqlx::query!( + async fn get_object_info_by_persistence_target(target: PersistenceTarget, password: u64) -> Result { + let row = sqlx::query!( r#"SELECT data_id, owner, size, name, data_type, meta_binary, permission, permission_recipients, delete_permission, delete_permission_recipients, period, refer_data_id, flag, tags, creation_date, update_date, @@ -227,146 +192,124 @@ async fn get_object_info_by_persistence_target( .map_err(|_| ErrorCode::DataStore_SystemFileError)? .ok_or(ErrorCode::DataStore_NotFound)?; - let db_password = row.access_password as u64; - if db_password != 0 && db_password != password { - return Err(ErrorCode::DataStore_InvalidPassword); - } + let db_password = row.access_password as u64; + if db_password != 0 && db_password != password { + return Err(ErrorCode::DataStore_InvalidPassword); + } - if row.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } + if row.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } - let ratings = get_object_ratings(row.data_id as u64, password).await?; + let ratings = get_object_ratings(row.data_id as u64, password).await?; - Ok(map_row_to_meta_info( - row.data_id, - row.owner.unwrap_or(0), - row.size.unwrap_or(0), - row.name.unwrap_or_default(), - row.data_type.unwrap_or(0) as i16, - row.meta_binary.unwrap_or_default(), - row.permission.unwrap_or(0) as i16, - row.permission_recipients - .unwrap_or_default() - .into_iter() - .map(|id| id as i64) - .collect(), - row.delete_permission.unwrap_or(0) as i16, - row.delete_permission_recipients - .unwrap_or_default() - .into_iter() - .map(|id| id as i64) - .collect(), - row.period.unwrap_or(0) as i16, - row.refer_data_id.unwrap_or(0), - row.flag.unwrap_or(0), - row.tags.unwrap_or_default(), - row.creation_date - .map(|dt| { - chrono::NaiveDateTime::new( - chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32) - .unwrap(), - chrono::NaiveTime::from_hms_opt( - dt.hour() as u32, - dt.minute() as u32, - dt.second() as u32, - ) - .unwrap(), - ) - }) - .unwrap_or_default(), - row.update_date - .map(|dt| { - chrono::NaiveDateTime::new( - chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32) - .unwrap(), - chrono::NaiveTime::from_hms_opt( - dt.hour() as u32, - dt.minute() as u32, - dt.second() as u32, - ) - .unwrap(), - ) - }) - .unwrap_or_default(), - ratings, - )) -} + Ok(map_row_to_meta_info( + row.data_id, + row.owner.unwrap_or(0), + row.size.unwrap_or(0), + row.name.unwrap_or_default(), + row.data_type.unwrap_or(0) as i16, + row.meta_binary.unwrap_or_default(), + row.permission.unwrap_or(0) as i16, + row.permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), + row.delete_permission.unwrap_or(0) as i16, + row.delete_permission_recipients.unwrap_or_default().into_iter().map(|id| id as i64).collect(), + row.period.unwrap_or(0) as i16, + row.refer_data_id.unwrap_or(0), + row.flag.unwrap_or(0), + row.tags.unwrap_or_default(), + row.creation_date.map(|dt| chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), + chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() + )).unwrap_or_default(), + row.update_date.map(|dt| chrono::NaiveDateTime::new( + chrono::NaiveDate::from_ymd_opt(dt.year(), dt.month() as u32, dt.day() as u32).unwrap(), + chrono::NaiveTime::from_hms_opt(dt.hour() as u32, dt.minute() as u32, dt.second() as u32).unwrap() + )).unwrap_or_default(), + ratings + )) + } -async fn get_buffer_queues_by_data_id_and_slot( - data_id: u64, - slot: u32, -) -> Result, ErrorCode> { - check_object_availability(data_id, 0).await?; + async fn get_buffer_queues_by_data_id_and_slot( + data_id: u64, + slot: u32 + ) -> Result, ErrorCode> { + check_object_availability(data_id, 0).await?; - let rows = sqlx::query!( - r#" + let rows = sqlx::query!( + r#" SELECT buffer FROM datastore.buffer_queues WHERE data_id = $1 AND slot = $2 ORDER BY creation_date ASC "#, - data_id as i64, - slot as i32 - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - log::error!("Buffer queue fetch error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; + data_id as i64, + slot as i32 + ) + .fetch_all(get_db()) + .await + .map_err(|e| { + log::error!("Buffer queue fetch error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; - let buffer_queues = rows.into_iter().map(|row| QBuffer(row.buffer)).collect(); + let buffer_queues = rows + .into_iter() + .map(|row| QBuffer(row.buffer)) + .collect(); - Ok(buffer_queues) -} + Ok(buffer_queues) + } -fn verify_object_permission( - owner_id: u32, - viewer_id: u32, - permission: &Permission, -) -> Result<(), ErrorCode> { - if owner_id == viewer_id { - return Ok(()); - } + fn verify_object_permission( + owner_id: u32, + viewer_id: u32, + permission: &Permission, + ) -> Result<(), ErrorCode> { + if owner_id == viewer_id { + return Ok(()); + } - match permission.permission { - 0 => Ok(()), // All can read - 1 => Err(ErrorCode::DataStore_PermissionDenied), // Friends only, unimplemented - 2 => { - // Recipient IDs can read - if permission.recipient_ids.contains(&viewer_id) { - Ok(()) - } else { - Err(ErrorCode::DataStore_PermissionDenied) + match permission.permission { + 0 => Ok(()), // All can read + 1 => Err(ErrorCode::DataStore_PermissionDenied), // Friends only, unimplemented + 2 => { + // Recipient IDs can read + if permission.recipient_ids.contains(&viewer_id) { + Ok(()) + } else { + Err(ErrorCode::DataStore_PermissionDenied) + } + } + 3 => Err(ErrorCode::DataStore_PermissionDenied), // Owner only, redundant + _ => Err(ErrorCode::DataStore_InvalidArgument), // ??? haxx0r } } - 3 => Err(ErrorCode::DataStore_PermissionDenied), // Owner only, redundant - _ => Err(ErrorCode::DataStore_InvalidArgument), // ??? haxx0r - } -} -fn filter_properties_by_result_option(meta_info: &mut GetMetaInfo, result_option: u8) { - if (result_option & 0x01) == 0 { - meta_info.meta_binary = QBuffer(Vec::new()); - } + fn filter_properties_by_result_option( + meta_info: &mut GetMetaInfo, + result_option: u8, + ) { + if (result_option & 0x01) == 0 { + meta_info.meta_binary = QBuffer(Vec::new()); + } - if (result_option & 0x04) == 0 { - meta_info.ratings = Vec::new(); - } + if (result_option & 0x04) == 0 { + meta_info.ratings = Vec::new(); + } - // No idea what the other things do. :shrug: -} + // No idea what the other things do. :shrug: + } -// Dawg... -async fn get_custom_rankings_by_data_ids( - application_id: u32, - data_ids: Vec, -) -> Vec { - let mut results = Vec::with_capacity(data_ids.len()); + // Dawg... + async fn get_custom_rankings_by_data_ids( + application_id: u32, + data_ids: Vec + ) -> Vec { + let mut results = Vec::with_capacity(data_ids.len()); - let rows = sqlx::query!( - r#" + let rows = sqlx::query!( + r#" SELECT rankings.data_id, rankings.value @@ -376,263 +319,124 @@ async fn get_custom_rankings_by_data_ids( AND rankings.application_id = $2 ORDER BY rows.ord "#, - &data_ids.iter().map(|&id| id as i64).collect::>(), - application_id as i32 - ) - .fetch_all(get_db()) - .await; + &data_ids.iter().map(|&id| id as i64).collect::>(), + application_id as i32 + ) + .fetch_all(get_db()) + .await; - let rows = match rows { - Ok(r) => r, - Err(e) => { - log::error!("Custom ranking query error: {:?}", e); - return results; + let rows = match rows { + Ok(r) => r, + Err(e) => { + log::error!("Custom ranking query error: {:?}", e); + return results; + } + }; + + for row in rows { + let data_id = row.data_id as u64; + let score = row.value.unwrap_or(0) as u32; + + if let Ok(meta) = get_object_info_by_data_id(data_id, 0).await { + results.push(DataStoreCustomRankingResult { + order: 0, + score, + meta_info: meta, + }); + } else { + log::warn!("Could not find metadata for ranked object {}", data_id); + } + } + + results } - }; - for row in rows { - let data_id = row.data_id as u64; - let score = row.value.unwrap_or(0) as u32; - - if let Ok(meta) = get_object_info_by_data_id(data_id, 0).await { - results.push(DataStoreCustomRankingResult { - order: 0, - score, - meta_info: meta, - }); - } else { - log::warn!("Could not find metadata for ranked object {}", data_id); - } - } - - results -} - -async fn get_user_course_object_ids(owner_pid: u32) -> Result, ErrorCode> { - let rows = sqlx::query!( - r#" + async fn get_user_course_object_ids(owner_pid: u32) -> Result, ErrorCode> { + let rows = sqlx::query!( + r#" SELECT data_id FROM datastore.objects WHERE owner = $1 AND data_type > 2 AND data_type < 50 "#, - owner_pid as i64 - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - log::error!("error fetching course IDs for PID {}: {:?}", owner_pid, e); - ErrorCode::DataStore_SystemFileError - })?; - - let mut valid_ids = Vec::new(); - for row in rows { - let data_id = row.data_id as u64; - // always check avail - if check_object_availability(data_id, 0).await.is_ok() { - valid_ids.push(data_id); - } - } - - Ok(valid_ids) -} - -fn get_blacklist_1() -> Vec { - vec![ - "けされ", - "消され", - "削除され", - "リセットされ", - "BANされ", - "BANされ", - "キミのコース", - "君のコース", - "きみのコース", - "い い ね", - "遊びます", - "地震", - "震災", - "被災", - "津波", - "バンされ", - "い~ね", - "震度", - "じしん", - "banされ", - "くわしくは", - "詳しくは", - "ちんちん", - "ち0こ", - "bicth", - "い.い.ね", - "ナイ~ス", - "い&い", - "い-いね", - "いぃね", - "nigger", - "ngger", - "star if u", - "Star if u", - "Star if you", - "star if you", - "PENlS", - "マンコ", - "butthole", - "LILI", - "vagina", - "vagyna", - "うんち", - "うんこ", - "ウンコ", - "Iine", - "EENE", - "まんこ", - "ウンチ", - "niglet", - "nigglet", - "please like", - "きんたま", - "Butthole", - "llね", - "iいね", - "give a star", - "ちんぽ", - "亀頭", - "penis", - "ウンコ", - "plz more stars", - "star plz", - "い()ね", - "PLEASE star", - "Bitte Sterne", - ] - .into_iter() - .map(String::from) - .collect() -} - -fn get_blacklist_2() -> Vec { - vec![ - "ゼロから", - "0から", - "0から", - "い  い  ね", - "いい", - "東日本", - "大震", - ] - .into_iter() - .map(String::from) - .collect() -} - -fn get_blacklist_3() -> Vec { - vec![ - "いいね", - "下さい", - "ください", - "押して", - "おして", - "返す", - "かえす", - "星", - "してくれ", - "するよ", - "☆くれたら", - "☆あげます", - "★くれたら", - "★あげます", - "しね", - "ころす", - "ころされた", - "アナル", - "ファック", - "キンタマ", - "○ね", - "キチガイ", - "うんこ", - "KITIGAI", - "金玉", - "おっぱい", - "☆おす", - "☆押す", - "★おす", - "★押す", - "いいする", - "いいよ", - "イイネ", - "ケツ", - "うんち", - "かくせいざい", - "覚せい剤", - "シャブ", - "きんたま", - "ちんちん", - "おしっこ", - "ちんぽこ", - "ころして", - "グッド", - "グット", - "レ●プ", - "バーカ", - "きちがい", - "ちんげ", - "マンコ", - "まんこ", - "チンポ", - "クズ", - "ウンコ", - "ナイスおねがいします", - "penis", - "イイね", - "☆よろ", - "ナイス!して", - "ま/んこ", - "まん/こ", - ] - .into_iter() - .map(String::from) - .collect() -} - -impl DataStore for User { - async fn get_meta(&self, mut metaparam: GetMetaParam) -> Result { - let mut meta_info = if metaparam.dataid != 0 { - get_object_info_by_data_id(metaparam.dataid, metaparam.access_password).await? - } else { - get_object_info_by_persistence_target( - metaparam.persistence_target, - metaparam.access_password, + owner_pid as i64 ) - .await? - }; + .fetch_all(get_db()) + .await + .map_err(|e| { + log::error!("error fetching course IDs for PID {}: {:?}", owner_pid, e); + ErrorCode::DataStore_SystemFileError + })?; - let current_pid = self.pid; - verify_object_permission(meta_info.owner, current_pid, &meta_info.permission)?; + let mut valid_ids = Vec::new(); + for row in rows { + let data_id = row.data_id as u64; + // always check avail + if check_object_availability(data_id, 0).await.is_ok() { + valid_ids.push(data_id); + } + } - filter_properties_by_result_option(&mut meta_info, metaparam.result_option); + Ok(valid_ids) + } - Ok(meta_info) - } + fn get_blacklist_1() -> Vec { + vec![ + "けされ", "消され", "削除され", "リセットされ", "BANされ", "BANされ", + "キミのコース", "君のコース", "きみのコース", "い い ね", "遊びます", "地震", + "震災", "被災", "津波", "バンされ", "い~ね", "震度", "じしん", "banされ", + "くわしくは", "詳しくは", "ちんちん", "ち0こ", "bicth", "い.い.ね", + "ナイ~ス", "い&い", "い-いね", "いぃね", "nigger", "ngger", "star if u", + "Star if u", "Star if you", "star if you", "PENlS", "マンコ", "butthole", + "LILI", "vagina", "vagyna", "うんち", "うんこ", "ウンコ", "Iine", + "EENE", "まんこ", "ウンチ", "niglet", "nigglet", "please like", "きんたま", + "Butthole", "llね", "iいね", "give a star", "ちんぽ", "亀頭", "penis", + "ウンコ", "plz more stars", "star plz", "い()ね", "PLEASE star", "Bitte Sterne", + ].into_iter().map(String::from).collect() + } - async fn prepare_post_object( - &self, - postparam: PreparePostParam, - ) -> Result { - let recipient_ids: Vec = postparam - .permission - .recipient_ids - .iter() - .map(|&id| id as i32) - .collect(); - let del_recipient_ids: Vec = postparam - .del_permission - .recipient_ids - .iter() - .map(|&id| id as i32) - .collect(); - let now = time::OffsetDateTime::now_utc(); + fn get_blacklist_2() -> Vec { + vec![ + "ゼロから", "0から", "0から", "い  い  ね", "いい", "東日本", "大震", + ].into_iter().map(String::from).collect() + } - let row = sqlx::query!( + fn get_blacklist_3() -> Vec { + vec![ + "いいね", "下さい", "ください", "押して", "おして", "返す", "かえす", + "星", "してくれ", "するよ", "☆くれたら", "☆あげます", "★くれたら", + "★あげます", "しね", "ころす", "ころされた", "アナル", "ファック", + "キンタマ", "○ね", "キチガイ", "うんこ", "KITIGAI", "金玉", "おっぱい", + "☆おす", "☆押す", "★おす", "★押す", "いいする", "いいよ", "イイネ", + "ケツ", "うんち", "かくせいざい", "覚せい剤", "シャブ", "きんたま", + "ちんちん", "おしっこ", "ちんぽこ", "ころして", "グッド", "グット", + "レ●プ", "バーカ", "きちがい", "ちんげ", "マンコ", "まんこ", "チンポ", + "クズ", "ウンコ", "ナイスおねがいします", "penis", "イイね", "☆よろ", + "ナイス!して", "ま/んこ", "まん/こ", + ].into_iter().map(String::from).collect() + } + + impl DataStore for User { + async fn get_meta(&self, mut metaparam: GetMetaParam) -> Result { + let mut meta_info = if metaparam.dataid != 0 { + get_object_info_by_data_id(metaparam.dataid, metaparam.access_password).await? + } else { + get_object_info_by_persistence_target(metaparam.persistence_target, metaparam.access_password).await? + }; + + let current_pid = self.pid; + verify_object_permission(meta_info.owner, current_pid, &meta_info.permission)?; + + filter_properties_by_result_option(&mut meta_info, metaparam.result_option); + + Ok(meta_info) + } + + async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result { + let recipient_ids: Vec = postparam.permission.recipient_ids.iter().map(|&id| id as i32).collect(); + let del_recipient_ids: Vec = postparam.del_permission.recipient_ids.iter().map(|&id| id as i32).collect(); + let now = time::OffsetDateTime::now_utc(); + + let row = sqlx::query!( r#" INSERT INTO datastore.objects ( owner, size, name, data_type, meta_binary, @@ -669,95 +473,87 @@ impl DataStore for User { ErrorCode::DataStore_SystemFileError })?; - let data_id = row.data_id as u64; - let presigner = S3Presigner::new( - &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), - format!("{}", *RNEX_DATASTORE_S3_BUCKET), - ) - .await; + let data_id = row.data_id as u64; + let presigner = S3Presigner::new( + &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), + format!("{}", *RNEX_DATASTORE_S3_BUCKET) + ).await; - let key = format!("data/{}.bin", data_id); + let key = format!("data/{}.bin", data_id); - let (upload_url, fields) = presigner.generate_presigned_post(&key).await; + let (upload_url, fields) = presigner.generate_presigned_post(&key).await; - let form_fields = fields - .into_iter() - .map(|(k, v)| KeyValue { key: k, value: v }) - .collect(); + let form_fields = fields.into_iter().map(|(k, v)| { + KeyValue { key: k, value: v } + }).collect(); - Ok(ReqPostInfo { - dataid: data_id, - url: upload_url, - request_headers: vec![], - form_fields, - root_ca_cert: vec![], - }) - } - - async fn complete_post_object( - &self, - completeparam: CompletePostParam, - ) -> Result<(), ErrorCode> { - log::info!("Data ID: {:?}", completeparam.dataid); - log::info!("Success: {:?}", completeparam.success); - - let record = sqlx::query!( - r#"SELECT owner, under_review FROM datastore.objects WHERE data_id = $1"#, - completeparam.dataid as i64 - ) - .fetch_optional(get_db()) - .await - .map_err(|e| { - eprintln!("select error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; - - let record = record.ok_or(ErrorCode::DataStore_NotFound)?; - - if record.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } - - if record.owner.unwrap_or(0) as u32 != self.pid { - return Err(ErrorCode::DataStore_PermissionDenied); - } - - if completeparam.success { - sqlx::query!( - r#"UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1"#, - completeparam.dataid as i64 - ) - .execute(get_db()) - .await - .map_err(|e| { - eprintln!("update error: {:?}", e); - ErrorCode::DataStore_SystemFileError - })?; - } else { - return Err(ErrorCode::Transport_TemporaryServerError); - } - - Ok(()) - } - - async fn rate_custom_ranking( - &self, - rankingparam: Vec, - ) -> Result<(), ErrorCode> { - for abcparam in rankingparam { - let exists = sqlx::query_scalar!( - r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#, - abcparam.dataid as i64 - ) - .fetch_one(get_db()) - .await - .map_err(|_| ErrorCode::DataStore_SystemFileError)?; - - if !exists.unwrap_or(false) { - return Err(ErrorCode::DataStore_NotFound); + Ok(ReqPostInfo { + dataid: data_id, + url: upload_url, + request_headers: vec![], + form_fields, + root_ca_cert: vec![], + }) } - sqlx::query!( + async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode> { + log::info!("Data ID: {:?}", completeparam.dataid); + log::info!("Success: {:?}", completeparam.success); + + let record = sqlx::query!( + r#"SELECT owner, under_review FROM datastore.objects WHERE data_id = $1"#, + completeparam.dataid as i64 + ) + .fetch_optional(get_db()) + .await + .map_err(|e| { + eprintln!("select error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + + let record = record.ok_or(ErrorCode::DataStore_NotFound)?; + + if record.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } + + if record.owner.unwrap_or(0) as u32 != self.pid { + return Err(ErrorCode::DataStore_PermissionDenied); + } + + if completeparam.success { + sqlx::query!( + r#"UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1"#, + completeparam.dataid as i64 + ) + .execute(get_db()) + .await + .map_err(|e| { + eprintln!("update error: {:?}", e); + ErrorCode::DataStore_SystemFileError + })?; + } else { + return Err(ErrorCode::Transport_TemporaryServerError); + } + + Ok(()) + } + + async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode> { + for abcparam in rankingparam { + let exists = sqlx::query_scalar!( + r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#, + abcparam.dataid as i64 + ) + .fetch_one(get_db()) + .await + .map_err(|_| ErrorCode::DataStore_SystemFileError)?; + + if !exists.unwrap_or(false) { + return Err(ErrorCode::DataStore_NotFound); + } + + sqlx::query!( r#" INSERT INTO datastore.object_custom_rankings (data_id, application_id, value) VALUES ($1, $2, $3) @@ -774,269 +570,216 @@ impl DataStore for User { log::error!("update/insert error: {:?}", e); ErrorCode::DataStore_SystemFileError })?; - } - - Ok(()) - } - - async fn get_application_config(&self, appid: u32) -> Result, ErrorCode> { - const MAX_COURSE_UPLOADS: i32 = 100; - - let config = match appid { - 0 => vec![ - 0x00000001, - 0x00000032, - 0x00000096, - 0x0000012c, - 0x000001f4, - 0x00000320, - 0x00000514, - 0x000007d0, - 0x00000bb8, - 0x00001388, - MAX_COURSE_UPLOADS, - 0x00000014, - 0x0000001e, - 0x00000028, - 0x00000032, - 0x0000003c, - 0x00000046, - 0x00000050, - 0x0000005a, - 0x00000064, - 0x00000023, - 0x0000004b, - 0x00000023, - 0x0000004b, - 0x00000032, - 0x00000000, - 0x00000003, - 0x00000003, - 0x00000064, - 0x00000006, - 0x00000001, - 0x00000060, - 0x00000005, - 0x00000060, - 0x00000000, - 0x000007e4, - 0x00000001, - 0x00000001, - 0x0000000c, - 0x00000000, - ], - 1 => vec![ - 2, 1770179696, 1770179664, 1770179640, 1770180827, 1770180777, 1770180745, - 1770177625, 1770177590, - ], - 2 => vec![0x000007df, 0x0000000c, 0x00000016, 0x00000005, 0x00000000], - 10 => vec![35, 75, 96, 40, 5, 6], - _ => { - log::error!("unknown SMM app id: {}", appid); - return Err(ErrorCode::DataStore_Unknown); - } - }; - - Ok(config) - } - - async fn get_custom_ranking_by_data_id( - &self, - custom_ranking_param: DataStoreGetCustomRankingByDataIDParam, - ) -> Result<(Vec, Vec), ErrorCode> { - println!("appid: {:?}", custom_ranking_param.application_id); - println!("dataid list: {:?}", custom_ranking_param.data_id_list); - println!("result option: {:?}", custom_ranking_param.result_option); - - let mut ranking_results = get_custom_rankings_by_data_ids( - custom_ranking_param.application_id, - custom_ranking_param.data_id_list, - ) - .await; - - let mut q_results = Vec::with_capacity(ranking_results.len()); - - for result in &mut ranking_results { - if (custom_ranking_param.result_option & 0x01) == 0 { - result.meta_info.tags = Vec::new(); - } - - if (custom_ranking_param.result_option & 0x02) == 0 { - result.meta_info.ratings = Vec::new(); - } - - if (custom_ranking_param.result_option & 0x04) == 0 { - result.meta_info.meta_binary = QBuffer(Vec::new()); - } - - if (custom_ranking_param.result_option & 0x20) == 0 { - result.score = 0; - } - - q_results.push(QResult::success(ErrorCode::Core_Unknown)); - } - - Ok((ranking_results, q_results)) - } - - async fn get_buffer_queue( - &self, - bufferparam: BufferQueueParam, - ) -> Result, ErrorCode> { - // log::info!("GetBufferQueue: dataid={}, slot={}", param.dataid, param.slot); - - let buffers = - get_buffer_queues_by_data_id_and_slot(bufferparam.dataid, bufferparam.slot).await?; - - Ok(buffers) - } - - async fn prepare_get_object( - &self, - prepare_get_param: DataStorePrepareGetParam, - ) -> Result { - let meta_info = if prepare_get_param.dataid != 0 { - get_object_info_by_data_id(prepare_get_param.dataid, prepare_get_param.access_password) - .await? - } else { - get_object_info_by_persistence_target( - prepare_get_param.persistence_target, - prepare_get_param.access_password, - ) - .await? - }; - - verify_object_permission(meta_info.owner, self.pid, &meta_info.permission)?; - - let presigner = S3Presigner::new( - &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), - format!("{}", *RNEX_DATASTORE_S3_BUCKET), - ) - .await; - - let key = format!("data/{}.bin", meta_info.dataid); - let download_url = presigner.generate_presigned_get(&key); - - Ok(DataStoreReqGetInfo { - url: download_url, - request_headers: vec![], - size: meta_info.size, - root_ca_cert: vec![], - dataid: meta_info.dataid, - }) - } - - async fn followings_latest_course_search_object( - &self, - course_search_param: DataStoreSearchParam, - _extra_data: Vec, - ) -> Result, ErrorCode> { - let mut all_results = Vec::new(); - - for &owner_pid in &course_search_param.owner_ids { - let course_ids = get_user_course_object_ids(owner_pid).await?; - - if course_ids.is_empty() { - continue; - } - - let mut results = get_custom_rankings_by_data_ids(0, course_ids).await; - - // Flag 0x1: Return Tags - // Flag 0x2: Return Ratings - // Flag 0x4: Return MetaBinary - // Flag 0x20: Return Score - for res in &mut results { - if course_search_param.result_option & 0x1 == 0 { - res.meta_info.tags = Vec::new(); - } - if course_search_param.result_option & 0x2 == 0 { - res.meta_info.ratings = Vec::new(); - } - if course_search_param.result_option & 0x4 == 0 { - res.meta_info.meta_binary = - rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); - } - if course_search_param.result_option & 0x20 == 0 { - res.score = 0; } + + Ok(()) } - all_results.extend(results); - } + async fn get_application_config(&self, appid: u32) -> Result, ErrorCode> { + const MAX_COURSE_UPLOADS: i32 = 100; - // note: we assume the client sorts the data lol + let config = match appid { + 0 => vec![ + 0x00000001, 0x00000032, 0x00000096, 0x0000012c, 0x000001f4, + 0x00000320, 0x00000514, 0x000007d0, 0x00000bb8, 0x00001388, + MAX_COURSE_UPLOADS, 0x00000014, 0x0000001e, 0x00000028, 0x00000032, + 0x0000003c, 0x00000046, 0x00000050, 0x0000005a, 0x00000064, + 0x00000023, 0x0000004b, 0x00000023, 0x0000004b, 0x00000032, + 0x00000000, 0x00000003, 0x00000003, 0x00000064, 0x00000006, + 0x00000001, 0x00000060, 0x00000005, 0x00000060, 0x00000000, + 0x000007e4, 0x00000001, 0x00000001, 0x0000000c, 0x00000000, + ], + 1 => vec![ + 2, + 1770179696, + 1770179664, + 1770179640, + 1770180827, + 1770180777, + 1770180745, + 1770177625, + 1770177590, + ], + 2 => vec![0x000007df, 0x0000000c, 0x00000016, 0x00000005, 0x00000000], + 10 => vec![35, 75, 96, 40, 5, 6], + _ => { + log::error!("unknown SMM app id: {}", appid); + return Err(ErrorCode::DataStore_Unknown); + } + }; - Ok(all_results) - } - - async fn get_application_config_string( - &self, - application_id: u32, - ) -> Result, ErrorCode> { - let config = match application_id { - 128 => get_blacklist_1(), - 129 => get_blacklist_2(), - 130 => get_blacklist_3(), - _ => { - log::warn!( - "unsupported application_id in GetApplicationConfigString: {}", - application_id - ); - Vec::new() + Ok(config) } - }; - Ok(config) - } + async fn get_custom_ranking_by_data_id( + &self, + custom_ranking_param: DataStoreGetCustomRankingByDataIDParam + ) -> Result<(Vec, Vec), ErrorCode> { + println!("appid: {:?}", custom_ranking_param.application_id); + println!("dataid list: {:?}", custom_ranking_param.data_id_list); + println!("result option: {:?}", custom_ranking_param.result_option); - async fn get_metas_multiple_param( - &self, - params: Vec, - ) -> Result<(Vec, Vec), ErrorCode> { - let mut metas = Vec::with_capacity(params.len()); - let mut results = Vec::with_capacity(params.len()); + let mut ranking_results = get_custom_rankings_by_data_ids(custom_ranking_param.application_id, custom_ranking_param.data_id_list).await; - for param in params { - let info_result = if param.dataid != 0 { - get_object_info_by_data_id(param.dataid, param.access_password).await - } else { - get_object_info_by_persistence_target( - param.persistence_target, - param.access_password, - ) - .await - }; + let mut q_results = Vec::with_capacity(ranking_results.len()); - match info_result { - Ok(mut meta) => { - if let Err(e) = verify_object_permission(meta.owner, self.pid, &meta.permission) - { - metas.push(GetMetaInfo::default()); - results.push(QResult::error(e)); + for result in &mut ranking_results { + if (custom_ranking_param.result_option & 0x01) == 0 { + result.meta_info.tags = Vec::new(); + } + + if (custom_ranking_param.result_option & 0x02) == 0 { + result.meta_info.ratings = Vec::new(); + } + + if (custom_ranking_param.result_option & 0x04) == 0 { + result.meta_info.meta_binary = QBuffer(Vec::new()); + } + + if (custom_ranking_param.result_option & 0x20) == 0 { + result.score = 0; + } + + q_results.push(QResult::success(ErrorCode::Core_Unknown)); + } + + Ok((ranking_results, q_results)) + } + + async fn get_buffer_queue(&self, bufferparam: BufferQueueParam) -> Result, ErrorCode> { + // log::info!("GetBufferQueue: dataid={}, slot={}", param.dataid, param.slot); + + let buffers = get_buffer_queues_by_data_id_and_slot(bufferparam.dataid, bufferparam.slot).await?; + + Ok(buffers) + } + + async fn prepare_get_object(&self, prepare_get_param: DataStorePrepareGetParam) -> Result { + let meta_info = if prepare_get_param.dataid != 0 { + get_object_info_by_data_id(prepare_get_param.dataid, prepare_get_param.access_password).await? + } else { + get_object_info_by_persistence_target(prepare_get_param.persistence_target, prepare_get_param.access_password).await? + }; + + verify_object_permission(meta_info.owner, self.pid, &meta_info.permission)?; + + let presigner = S3Presigner::new( + &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), + format!("{}", *RNEX_DATASTORE_S3_BUCKET) + ).await; + + let key = format!("data/{}.bin", meta_info.dataid); + let download_url = presigner.generate_presigned_get(&key); + + Ok(DataStoreReqGetInfo { + url: download_url, + request_headers: vec![], + size: meta_info.size, + root_ca_cert: vec![], + dataid: meta_info.dataid, + }) + } + + async fn followings_latest_course_search_object( + &self, + course_search_param: DataStoreSearchParam, + _extra_data: Vec + ) -> Result, ErrorCode> { + let mut all_results = Vec::new(); + + for &owner_pid in &course_search_param.owner_ids { + let course_ids = get_user_course_object_ids(owner_pid).await?; + + if course_ids.is_empty() { + continue; + } + + let mut results = get_custom_rankings_by_data_ids(0, course_ids).await; + + // Flag 0x1: Return Tags + // Flag 0x2: Return Ratings + // Flag 0x4: Return MetaBinary + // Flag 0x20: Return Score + for res in &mut results { + if course_search_param.result_option & 0x1 == 0 { + res.meta_info.tags = Vec::new(); + } + if course_search_param.result_option & 0x2 == 0 { + res.meta_info.ratings = Vec::new(); + } + if course_search_param.result_option & 0x4 == 0 { + res.meta_info.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); + } + if course_search_param.result_option & 0x20 == 0 { + res.score = 0; + } + } + + all_results.extend(results); + } + + // note: we assume the client sorts the data lol + + Ok(all_results) + } + + async fn get_application_config_string(&self, application_id: u32) -> Result, ErrorCode> { + let config = match application_id { + 128 => get_blacklist_1(), + 129 => get_blacklist_2(), + 130 => get_blacklist_3(), + _ => { + log::warn!("unsupported application_id in GetApplicationConfigString: {}", application_id); + Vec::new() + } + }; + + Ok(config) + } + + async fn get_metas_multiple_param( + &self, + params: Vec + ) -> Result<(Vec, Vec), ErrorCode> { + let mut metas = Vec::with_capacity(params.len()); + let mut results = Vec::with_capacity(params.len()); + + for param in params { + let info_result = if param.dataid != 0 { + get_object_info_by_data_id(param.dataid, param.access_password).await } else { - if param.result_option & 0x1 == 0 { - meta.tags = Vec::new(); - } - if param.result_option & 0x2 == 0 { - meta.ratings = Vec::new(); - } - if param.result_option & 0x4 == 0 { - meta.meta_binary = - rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); - } + get_object_info_by_persistence_target(param.persistence_target, param.access_password).await + }; - metas.push(meta); - results.push(QResult::success(ErrorCode::Core_Unknown)); + match info_result { + Ok(mut meta) => { + if let Err(e) = verify_object_permission(meta.owner, self.pid, &meta.permission) { + metas.push(GetMetaInfo::default()); + results.push(QResult::error(e)); + } else { + if param.result_option & 0x1 == 0 { + meta.tags = Vec::new(); + } + if param.result_option & 0x2 == 0 { + meta.ratings = Vec::new(); + } + if param.result_option & 0x4 == 0 { + meta.meta_binary = rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); + } + + metas.push(meta); + results.push(QResult::success(ErrorCode::Core_Unknown)); + } + } + Err(e) => { + metas.push(GetMetaInfo::default()); + results.push(QResult::error(e)); + } } } - Err(e) => { - metas.push(GetMetaInfo::default()); - results.push(QResult::error(e)); - } + + Ok((metas, results)) } } - - Ok((metas, results)) } -} +} \ No newline at end of file diff --git a/rnex-core/src/nex/friends_handler.rs b/rnex-core/src/nex/friends_handler.rs index 3af6ff6..941b747 100644 --- a/rnex-core/src/nex/friends_handler.rs +++ b/rnex-core/src/nex/friends_handler.rs @@ -139,9 +139,6 @@ impl Friends for FriendsUser { let Ok(any_self_fr_info) = Any::new(&self_fr_info) else { return Err(ErrorCode::RendezVous_ControlScriptFailure); }; - let Ok(any_self_presence) = Any::new(&self_fr_info.presence) else { - return Err(ErrorCode::RendezVous_ControlScriptFailure); - }; drop(data); let mut fr_list = vec![FriendInfo { @@ -200,9 +197,6 @@ impl Friends for FriendsUser { println!("acquiring user and current friends locks"); let users = self.fm.users.read().await; - if users.iter().filter(|u| u.upgrade().is_some()).count() >= 100 { - return Err(ErrorCode::RendezVous_ConnectionFailure); - } println!("started summing users"); for u in users.deref().iter().filter_map(|u| u.upgrade()) { let data = u.data.read().await; @@ -233,18 +227,6 @@ impl Friends for FriendsUser { .await; }); } else { - let data = any_self_presence.clone(); - let u = u.clone(); - let sender = self.pid; - spawn(async move { - u.remote - .process_nintendo_notification_event_2(NintendoNotificationEvent { - event_type: 24, - sender, - data, - }) - .await; - }); drop(fr); } } @@ -281,22 +263,18 @@ impl Friends for FriendsUser { } async fn update_presence(&self, presence: NintendoPresenceV2) -> Result<(), ErrorCode> { - info!("user updated presence: {:?}", presence); let mut data = self.data.write().await; let Some(inner_data) = data.as_mut() else { - log::error!("unable to get presence data"); return Err(ErrorCode::RendezVous_PermissionDenied); }; inner_data.presence = presence; let Ok(any_self_fr_info) = Any::new(&inner_data.presence) else { - log::error!("unable to create presence any data holder"); return Err(ErrorCode::RendezVous_ControlScriptFailure); }; drop(data); let users = self.fm.users.read().await; for u in users.deref().iter().filter_map(|u| u.upgrade()) { - info!("sending presence update"); u.remote .process_nintendo_notification_event_2(NintendoNotificationEvent { event_type: 24, @@ -312,7 +290,7 @@ impl Friends for FriendsUser { async fn delete_persistent_notification( &self, - _notifs: Vec, + notifs: Vec, ) -> Result<(), ErrorCode> { Ok(()) } @@ -320,26 +298,6 @@ impl Friends for FriendsUser { async fn check_setting_status(&self) -> Result { Ok(0xFF) } - - async fn update_preference(&self, preference: PrincipalPreference) -> Result<(),ErrorCode> { - info!("user updated preference: {:?}", preference); - let any_presence: Any = Any::new(&preference).expect("out of memory"); - - let users = self.fm.users.read().await; - for u in users.deref().iter().filter_map(|u| u.upgrade()) { - info!("sending preference update"); - u.remote - .process_nintendo_notification_event_2(NintendoNotificationEvent { - event_type: 23, - sender: self.pid, - data: any_presence.clone(), - }) - .await; - } - drop(users); - - Ok(()) - } } type HMacMd5 = hmac::Hmac; @@ -350,10 +308,6 @@ impl Secure for FriendsUser { station_urls: Vec, ) -> Result<(QResult, u32, StationUrl), ErrorCode> { let cid = self.fm.next_cid(); - let users = self.fm.users.read().await; - if users.iter().filter(|u| u.upgrade().is_some()).count() >= 100 { - return Err(ErrorCode::RendezVous_ConnectionFailure); - } Ok(( QResult::success(ErrorCode::Core_Unknown), cid, diff --git a/rnex-core/src/nex/matchmake.rs b/rnex-core/src/nex/matchmake.rs index 70e720d..0a18f74 100644 --- a/rnex-core/src/nex/matchmake.rs +++ b/rnex-core/src/nex/matchmake.rs @@ -1,12 +1,12 @@ +use crate::nex::user::User; +use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; use log::info; use rand::random; use rnex_core::PID; use rnex_core::kerberos::KerberosDateTime; -use rnex_core::nex::user::User; use rnex_core::rmc::protocols::notifications::notification_types::{ HOST_CHANGED, OWNERSHIP_CHANGED, }; -use rnex_core::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::response::ErrorCode::{Core_InvalidArgument, RendezVous_SessionVoid}; use rnex_core::rmc::structures::matchmake::gathering_flags::PERSISTENT_GATHERING; @@ -28,7 +28,6 @@ pub struct MatchmakeManager { pub sessions: RwLock>>>, pub rv_cid_counter: AtomicU32, pub users: RwLock>>, - pub users_by_pid: RwLock>>, } impl MatchmakeManager { @@ -115,16 +114,9 @@ fn read_bounds_string(str: &str) -> Option<(T, T)> { } fn check_bounds_str(compare: T, str: &str) -> Option { - 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); - } - if str.is_empty() { - return Some(true); - } - None + let bounds: (T, T) = read_bounds_string(str)?; + + Some(bounds.0 <= compare && compare <= bounds.1) } pub async fn broadcast_notification>( @@ -163,47 +155,28 @@ impl ExtendedMatchmakeSession { return Default::default(); }; - cfg_if::cfg_if! { - if #[cfg(feature = "v3-5-0")]{ - let mm_session = MatchmakeSession { - gathering: Gathering { - self_gid: gid, - owner_pid: host.pid, - host_pid: host.pid, - ..session.gathering.clone() - }, - datetime: KerberosDateTime::now(), - session_key: (0..32).map(|_| random()).collect(), - matchmake_param: MatchmakeParam { - params: vec![ - ("@SR".to_owned(), Variant::Bool(true)), - ("@GIR".to_owned(), Variant::SInt64(3)), - ], - }, - system_password_enabled: false, - ..session - }; + let mm_session = MatchmakeSession { + gathering: Gathering { + self_gid: gid, + owner_pid: host.pid, + host_pid: host.pid, + ..session.gathering.clone() + }, + datetime: KerberosDateTime::now(), + session_key: (0..32).map(|_| random()).collect(), + matchmake_param: MatchmakeParam { + params: vec![ + ("@SR".to_owned(), Variant::Bool(true)), + ("@GIR".to_owned(), Variant::SInt64(3)), + ], + }, + system_password_enabled: false, + ..session + }; - return Self { - session: mm_session, - connected_players: Default::default(), - } - } else { - let mm_session = MatchmakeSession { - gathering: Gathering { - self_gid: gid, - owner_pid: host.pid, - host_pid: host.pid, - ..session.gathering.clone() - }, - session_key: (0..32).map(|_| random()).collect(), - ..session - }; - return Self { - session: mm_session, - connected_players: Default::default(), - } - } + Self { + session: mm_session, + connected_players: Default::default(), } } @@ -239,7 +212,6 @@ impl ExtendedMatchmakeSession { param_1: self.session.gathering.self_gid as PID, param_2: other_pid, str_param: "".into(), - #[cfg(feature = "third-notif-param")] param_3: 0, }) .await; @@ -272,7 +244,6 @@ impl ExtendedMatchmakeSession { param_1: self.session.gathering.self_gid as PID, param_2: *pid, str_param: join_msg.clone(), - #[cfg(feature = "third-notif-param")] param_3: self.connected_players.len() as _, }) .await; @@ -295,7 +266,6 @@ impl ExtendedMatchmakeSession { param_1: self.session.gathering.self_gid as PID, param_2: new_conn_pid, str_param: join_msg.clone(), - #[cfg(feature = "third-notif-param")] param_3: self.connected_players.len() as _, }) .await; @@ -348,19 +318,15 @@ impl ExtendedMatchmakeSession { } } - cfg_if::cfg_if! { - if #[cfg(feature = "v3-5-0")]{ - if search_criteria.exclude_system_password_set { - if self.session.system_password_enabled { - return Ok(false); - } - } + if search_criteria.exclude_system_password_set { + if self.session.system_password_enabled { + return Ok(false); + } + } - if search_criteria.exclude_user_password_set { - if self.session.user_password_enabled { - return Ok(false); - } - } + if search_criteria.exclude_user_password_set { + if self.session.user_password_enabled { + return Ok(false); } } @@ -400,32 +366,32 @@ impl ExtendedMatchmakeSession { return Ok(false); } - #[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).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).is_some_and(|s| { - self.session - .attributes - .get(3) - .is_some_and(|a| s.0.contains(a)) - }) { - return Ok(false); - } + 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) diff --git a/rnex-core/src/nex/mod.rs b/rnex-core/src/nex/mod.rs index ba92c5d..f54e939 100644 --- a/rnex-core/src/nex/mod.rs +++ b/rnex-core/src/nex/mod.rs @@ -3,20 +3,13 @@ use cfg_if::cfg_if; pub mod account; pub mod auth_handler; pub mod common; - -cfg_if! { - if #[cfg(feature = "friends")]{ - pub mod friends_handler; - } else { - pub mod matchmake; - pub mod remote_console; - pub mod user; - } -} - +pub mod friends_handler; +pub mod matchmake; +pub mod remote_console; +pub mod user; +pub mod datastore; cfg_if! { if #[cfg(feature = "datastore")] { pub mod s3presigner; - pub mod datastore; } -} +} \ No newline at end of file diff --git a/rnex-core/src/nex/user.rs b/rnex-core/src/nex/user.rs index 974c869..c418cfd 100644 --- a/rnex-core/src/nex/user.rs +++ b/rnex-core/src/nex/user.rs @@ -1,32 +1,29 @@ +use crate::define_rmc_proto; +use crate::nex::common::get_station_urls; +use crate::nex::matchmake::{ExtendedMatchmakeSession, MatchmakeManager}; +use crate::nex::remote_console::RemoteConsole; +use crate::rmc::protocols::matchmake::{ + Matchmake, RawMatchmake, RawMatchmakeInfo, RemoteMatchmake, +}; +use crate::rmc::protocols::nat_traversal::{ + NatTraversal, RawNatTraversal, RawNatTraversalInfo, RemoteNatTraversal, + RemoteNatTraversalConsole, +}; use rnex_core::PID; -use rnex_core::define_rmc_proto; use rnex_core::kerberos::KerberosDateTime; -use rnex_core::nex::common::get_station_urls; -use rnex_core::nex::matchmake::{ExtendedMatchmakeSession, MatchmakeManager}; -use rnex_core::nex::remote_console::RemoteConsole; use rnex_core::prudp::station_url::StationUrl; use rnex_core::prudp::station_url::UrlOptions::{ Address, NatFiltering, NatMapping, Port, RVConnectionID, }; -use rnex_core::rmc::protocols::matchmake::{ - Matchmake, RawMatchmake, RawMatchmakeInfo, RemoteMatchmake, -}; use rnex_core::rmc::protocols::matchmake_ext::{ MatchmakeExt, RawMatchmakeExt, RawMatchmakeExtInfo, RemoteMatchmakeExt, }; use rnex_core::rmc::protocols::matchmake_extension::{ MatchmakeExtension, RawMatchmakeExtension, RawMatchmakeExtensionInfo, RemoteMatchmakeExtension, }; -use rnex_core::rmc::protocols::nat_traversal::{ - NatTraversal, RawNatTraversal, RawNatTraversalInfo, RemoteNatTraversal, - RemoteNatTraversalConsole, -}; -use rnex_core::rmc::protocols::notifications::notification_types::{ - END_GATHERING, REQUEST_JOIN_GATHERING, -}; use rnex_core::rmc::protocols::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking}; use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure}; -use rnex_core::rmc::protocols::util::{RawUtility, RawUtilityInfo, RemoteUtility, Utility}; +use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore}; use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::any::Any; use rnex_core::rmc::structures::matchmake::{ @@ -36,11 +33,10 @@ use serde::{Deserialize, Serialize}; use std::env; use std::str::FromStr; -use cfg_if::cfg_if; +use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; use log::{error, info}; use macros::rmc_struct; use rnex_core::prudp::socket_addr::PRUDPSockAddr; -use rnex_core::rmc::protocols::notifications::{NotificationEvent, RemoteNotification}; use rnex_core::rmc::protocols::ranking::{ CompetitionRankingGetParam, CompetitionRankingScoreData, CompetitionRankingScoreInfo, }; @@ -49,13 +45,13 @@ use rnex_core::rmc::structures::qbuffer::QBuffer; use rnex_core::rmc::structures::qresult::QResult; use rnex_core::rmc::structures::ranking::UploadCompetitionData; use std::sync::{Arc, Weak}; +use cfg_if::cfg_if; +use rnex_core::rmc::protocols::ranking::{CompetitionRankingScoreData, CompetitionRankingGetParam, CompetitionRankingScoreInfo}; +use rnex_core::rmc::structures::ranking::{UploadCompetitionData}; use tokio::sync::{Mutex, RwLock}; -use crate::rmc::structures::matchmake::MatchmakeSessionSearchCriteria; - cfg_if! { if #[cfg(feature = "datastore")] { - use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore}; define_rmc_proto!( proto UserProtocol{ Secure, @@ -64,7 +60,6 @@ cfg_if! { Matchmake, NatTraversal, Ranking, - Utility, DataStore } ); @@ -76,7 +71,6 @@ cfg_if! { MatchmakeExt, Matchmake, NatTraversal, - Utility, Ranking } ); @@ -105,9 +99,6 @@ impl Secure for User { let mut users = self.matchmake_manager.users.write().await; users.insert(cid, self.this.clone()); drop(users); - let mut users = self.matchmake_manager.users_by_pid.write().await; - users.insert(self.pid, self.this.clone()); - drop(users); let stations = get_station_urls(&station_urls, self.ip, self.pid, cid).await?; @@ -182,7 +173,6 @@ impl MatchmakeExtension for User { Ok(Vec::new()) } - #[cfg(feature = "v3-5-0")] async fn update_progress_score(&self, gid: u32, progress: u8) -> Result<(), ErrorCode> { let session = self.matchmake_manager.get_session(gid).await?; @@ -260,10 +250,10 @@ impl MatchmakeExtension for User { .await?; let mut session = session.lock().await; - - #[cfg(feature = "v3-5-0")] - if join_session_param.user_password != session.session.user_password { - return Err(ErrorCode::RendezVous_InvalidPassword); + if session.session.user_password_enabled { + if join_session_param.user_password != session.session.user_password { + return Err(ErrorCode::RendezVous_InvalidPassword); + } } session @@ -410,147 +400,9 @@ impl MatchmakeExtension for User { Ok(()) } - - async fn create_matchmake_session( - &self, - gathering: Any, - message: String, - ) -> Result<(u32, Vec), ErrorCode> { - info!("gathering: {:?}", gathering); - let Some(Ok(session)): Option> = gathering.try_get() else { - return Err(ErrorCode::Core_InvalidArgument); - }; - - let session = self - .create_matchmake_session_with_param(CreateMatchmakeSessionParam { - matchmake_session: session, - additional_participants: vec![], - gid_for_participation_check: 0, - create_matchmake_session_option: 0, - join_message: message, - participation_count: 1, - }) - .await?; - - Ok((session.gathering.self_gid, session.session_key)) - } - - async fn get_friend_notification_data( - &self, - _ty: i32, - ) -> Result, ErrorCode> { - Ok(vec![]) - } - async fn update_notification_data( - &self, - ty: u32, - param_1: u32, - param_2: u32, - str_param: String, - ) -> Result<(), ErrorCode> { - let recpipent = param_2; - let Some(user) = self - .matchmake_manager - .users_by_pid - .read() - .await - .get(&recpipent) - .and_then(|v| v.upgrade()) - else { - return Err(ErrorCode::Core_InvalidArgument); - }; - println!("notif ty : {}", ty); - match ty { - REQUEST_JOIN_GATHERING => { - user.remote - .process_notification_event(NotificationEvent { - pid_source: self.pid, - notif_type: REQUEST_JOIN_GATHERING * 1000, - param_1, - param_2, - #[cfg(feature = "third-notif-param")] - param_3: 0, - str_param, - }) - .await; - } - END_GATHERING => { - user.remote - .process_notification_event(NotificationEvent { - pid_source: self.pid, - notif_type: END_GATHERING * 1000, - param_1, - param_2, - #[cfg(feature = "third-notif-param")] - param_3: 0, - str_param, - }) - .await; - } - _ => { - return Err(ErrorCode::Core_InvalidArgument); - } - } - Ok(()) - } - - async fn join_matchmake_session_ex( - &self, - gid: u32, - message: String, - _dont_care_block_list: bool, - //participation_count: u16, - ) -> Result, ErrorCode> { - let sess = self.matchmake_manager.get_session(gid).await?; - let mut sess = sess.lock().await; - sess.add_players(&[self.this.clone()], message).await; - - Ok(sess.session.session_key.clone()) - } - - 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)?; - - println!("{:?}", criteria); - - 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 { - async fn find_by_single_id(&self, gid: u32) -> Result<(bool, Any), ErrorCode> { - let s = self.matchmake_manager.get_session(gid).await?; - let s = s.lock().await; - Ok(( - true, - Any::new(&s.session).map_err(|_| ErrorCode::Custom_Unknown)?, - )) - } - async fn unregister_gathering(&self, _gid: u32) -> Result { Ok(true) } @@ -600,7 +452,6 @@ impl Matchmake for User { pid_source: self.pid, param_1: gid as PID, param_2: self.pid, - #[cfg(feature = "third-notif-param")] param_3: 0, str_param: "".to_string(), }) @@ -622,7 +473,6 @@ impl Matchmake for User { pid_source: self.pid, param_1: gid as PID, param_2: self.pid, - #[cfg(feature = "third-notif-param")] param_3: 0, str_param: "".to_string(), }) @@ -658,7 +508,6 @@ impl Matchmake for User { pid_source: self.pid, param_1: gid as PID, param_2: *candidate as PID, - #[cfg(feature = "third-notif-param")] param_3: 0, str_param: "".to_string(), }) @@ -798,12 +647,6 @@ 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, @@ -830,22 +673,16 @@ impl Ranking for User { } }; - let offset = param.range.offset as usize; - let size = param.range.size as usize; - - let start = offset.min(results.len()); - let end = (start + size).min(results.len()); - let team_votes = fetch_team_votes(fest_id)?; let mut wins = vec![0u32, 0u32]; for r in &results { - let won_team = (r.team_id ^ (!r.team_win)) & 1; + let won_team = r.team_id ^ (!r.team_win); if let Some(team) = wins.get_mut(won_team as usize) { *team += 1 }; } - let score_data: Vec = results[start..end] + let score_data: Vec = results .iter() .map(|r| CompetitionRankingScoreData { unk: 1, @@ -865,8 +702,6 @@ impl Ranking for User { team_votes, }; - println!("range: {:?}", param.range); - Ok(vec![info]) } diff --git a/rnex-core/src/prudp/ticket.rs b/rnex-core/src/prudp/ticket.rs index 97dc5d5..98e181f 100644 --- a/rnex-core/src/prudp/ticket.rs +++ b/rnex-core/src/prudp/ticket.rs @@ -6,7 +6,7 @@ use typenum::U16; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; use crate::{ - kerberos::{SESSION_KEY_LENGTH, SessionLengthTy, TicketInternalData, derive_key}, + kerberos::{SESSION_KEY_LENGTH, SESSION_KEY_LENGTH_TY, TicketInternalData, derive_key}, nex::account::Account, rmc::structures::RmcSerialize, }; @@ -53,7 +53,7 @@ pub fn read_secure_connection_data( let request_data_length = request_data.len(); let request_data = &mut request_data[0..request_data_length - 0x10]; - let mut rc4: StreamCipherCoreWrapper> = + let mut rc4: StreamCipherCoreWrapper> = Rc4::new_from_slice(&session_key).expect("unable to init rc4 keystream"); rc4.apply_keystream(request_data); diff --git a/rnex-core/src/prudp/virtual_port.rs b/rnex-core/src/prudp/virtual_port.rs index b23b5d0..625709b 100644 --- a/rnex-core/src/prudp/virtual_port.rs +++ b/rnex-core/src/prudp/virtual_port.rs @@ -1,5 +1,8 @@ use bytemuck::{Pod, Zeroable}; -use std::fmt::{Debug, Formatter}; +use std::{ + fmt::{Debug, Formatter}, + slice, +}; use v_byte_helpers::SwapEndian; #[repr(transparent)] diff --git a/rnex-core/src/rmc/protocols/auth.rs b/rnex-core/src/rmc/protocols/auth.rs index a065418..ca387f9 100644 --- a/rnex-core/src/rmc/protocols/auth.rs +++ b/rnex-core/src/rmc/protocols/auth.rs @@ -8,11 +8,11 @@ use rnex_core::rmc::structures::qresult::QResult; cfg_if! { if #[cfg(feature = "nx")]{ - type LoginExRet = (QResult, PID, Vec, ConnectionData, String, String); - type RequestTicketRet = (QResult, Vec, String); + type LOGIN_EX_RET = (QResult, PID, Vec, ConnectionData, String, String); + type REQUEST_TICKET_RET = (QResult, Vec, String); } else { - type LoginExRet = (QResult, PID, Vec, ConnectionData, String); - type RequestTicketRet = (QResult, Vec); + type LOGIN_EX_RET = (QResult, PID, Vec, ConnectionData, String); + type REQUEST_TICKET_RET = (QResult, Vec); } } @@ -31,14 +31,14 @@ pub trait Auth { /// representation of the `LoginEx` method(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) #[method_id(2)] - async fn login_ex(&self, name: String, extra_data: Any) -> Result; + async fn login_ex(&self, name: String, extra_data: Any) -> Result; #[method_id(3)] async fn request_ticket( &self, source_pid: PID, destination_pid: PID, - ) -> Result; + ) -> Result; /// representation of the `RequestTicket` method(for details see the /// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol)) diff --git a/rnex-core/src/rmc/protocols/datastore.rs b/rnex-core/src/rmc/protocols/datastore.rs index 51d5365..0c68fc5 100644 --- a/rnex-core/src/rmc/protocols/datastore.rs +++ b/rnex-core/src/rmc/protocols/datastore.rs @@ -1,9 +1,9 @@ -use macros::{RmcSerialize, method_id, rmc_proto}; -use rnex_core::PID; -use rnex_core::kerberos::KerberosDateTime; -use rnex_core::rmc::response::ErrorCode; +use macros::{method_id, rmc_proto, RmcSerialize, rmc_struct}; use rnex_core::rmc::structures::qbuffer::QBuffer; +use rnex_core::rmc::response::ErrorCode; use rnex_core::rmc::structures::qresult::QResult; +use rnex_core::kerberos::KerberosDateTime; +use rnex_core::PID; use rnex_core::rmc::structures::resultsrange::ResultsRange; #[derive(RmcSerialize, Clone, Debug, Default)] @@ -78,7 +78,7 @@ pub struct RatingInitParam { pub range_min: i32, pub range_max: i32, pub period_hour: i8, - pub period_duration: i16, + pub period_duration: i16 } #[derive(RmcSerialize, Clone)] @@ -214,53 +214,27 @@ pub struct DataStoreSearchParam { } #[rmc_proto(115)] -pub trait DataStore { +pub trait DataStore{ #[method_id(8)] async fn get_meta(&self, metaparam: GetMetaParam) -> Result; #[method_id(36)] - async fn get_metas_multiple_param( - &self, - params: Vec, - ) -> Result<(Vec, Vec), ErrorCode>; + async fn get_metas_multiple_param(&self, params: Vec) -> Result<(Vec, Vec), ErrorCode>; #[method_id(24)] - async fn prepare_post_object( - &self, - postparam: PreparePostParam, - ) -> Result; + async fn prepare_post_object(&self, postparam: PreparePostParam) -> Result; #[method_id(26)] - async fn complete_post_object(&self, completeparam: CompletePostParam) - -> Result<(), ErrorCode>; + async fn complete_post_object(&self, completeparam: CompletePostParam) -> Result<(), ErrorCode>; #[method_id(48)] - async fn rate_custom_ranking( - &self, - rankingparam: Vec, - ) -> Result<(), ErrorCode>; + async fn rate_custom_ranking(&self, rankingparam: Vec) -> Result<(), ErrorCode>; #[method_id(61)] async fn get_application_config(&self, appid: u32) -> Result, ErrorCode>; #[method_id(50)] - async fn get_custom_ranking_by_data_id( - &self, - custom_ranking_param: DataStoreGetCustomRankingByDataIDParam, - ) -> Result<(Vec, Vec), ErrorCode>; + async fn get_custom_ranking_by_data_id(&self, custom_ranking_param: DataStoreGetCustomRankingByDataIDParam) -> Result<(Vec, Vec), ErrorCode>; #[method_id(54)] - async fn get_buffer_queue( - &self, - bufferparam: BufferQueueParam, - ) -> Result, ErrorCode>; + async fn get_buffer_queue(&self, bufferparam: BufferQueueParam) -> Result, ErrorCode>; #[method_id(25)] - async fn prepare_get_object( - &self, - prepare_get_param: DataStorePrepareGetParam, - ) -> Result; + async fn prepare_get_object(&self, prepare_get_param: DataStorePrepareGetParam) -> Result; #[method_id(65)] - async fn followings_latest_course_search_object( - &self, - course_search_param: DataStoreSearchParam, - extra_data: Vec, - ) -> Result, ErrorCode>; + async fn followings_latest_course_search_object(&self, course_search_param: DataStoreSearchParam, extra_data: Vec) -> Result, ErrorCode>; #[method_id(74)] - async fn get_application_config_string( - &self, - application_id: u32, - ) -> Result, ErrorCode>; -} + async fn get_application_config_string(&self, application_id: u32) -> Result, ErrorCode>; +} \ No newline at end of file diff --git a/rnex-core/src/rmc/protocols/friends.rs b/rnex-core/src/rmc/protocols/friends.rs index d25ea9e..81dd63e 100644 --- a/rnex-core/src/rmc/protocols/friends.rs +++ b/rnex-core/src/rmc/protocols/friends.rs @@ -2,7 +2,7 @@ use macros::{RmcSerialize, method_id, rmc_proto}; use rnex_core::{kerberos::KerberosDateTime, rmc::response::ErrorCode}; -use rnex_core::rmc::structures::data::Data; +use rnex_core::rmc::structures::{data::Data, rmc_struct}; #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] @@ -67,7 +67,7 @@ pub struct NintendoPresenceV2 { pub unk6: u8, pub unk7: u8, } -#[derive(RmcSerialize, Clone, Debug)] +#[derive(RmcSerialize)] #[rmc_struct(0)] pub struct PrincipalPreference { #[extends] @@ -171,8 +171,6 @@ pub trait Friends { >; #[method_id(13)] async fn update_presence(&self, presence: NintendoPresenceV2) -> Result<(), ErrorCode>; - #[method_id(16)] - async fn update_preference(&self, preference: PrincipalPreference) -> Result<(), ErrorCode>; #[method_id(18)] async fn delete_persistent_notification( &self, diff --git a/rnex-core/src/rmc/protocols/matchmake.rs b/rnex-core/src/rmc/protocols/matchmake.rs index d1c43b9..94edce3 100644 --- a/rnex-core/src/rmc/protocols/matchmake.rs +++ b/rnex-core/src/rmc/protocols/matchmake.rs @@ -4,14 +4,10 @@ use rnex_core::rmc::response::ErrorCode; use rnex_core::PID; -use crate::rmc::structures::any::Any; - #[rmc_proto(21)] pub trait Matchmake { #[method_id(2)] async fn unregister_gathering(&self, gid: u32) -> Result; - #[method_id(21)] - async fn find_by_single_id(&self, gid: u32) -> Result<(bool, Any), ErrorCode>; #[method_id(41)] async fn get_session_urls(&self, gid: u32) -> Result, ErrorCode>; #[method_id(42)] diff --git a/rnex-core/src/rmc/protocols/matchmake_extension.rs b/rnex-core/src/rmc/protocols/matchmake_extension.rs index 7e7a00d..fff5252 100644 --- a/rnex-core/src/rmc/protocols/matchmake_extension.rs +++ b/rnex-core/src/rmc/protocols/matchmake_extension.rs @@ -1,94 +1,32 @@ use macros::{method_id, rmc_proto}; use rnex_core::rmc::response::ErrorCode; -use rnex_core::rmc::structures::matchmake::{ - AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession, -}; - -use crate::rmc::protocols::notifications::NotificationEvent; -use crate::rmc::structures::any::Any; -use crate::rmc::structures::matchmake::MatchmakeSessionSearchCriteria; +use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession}; #[rmc_proto(109)] -pub trait MatchmakeExtension { +pub trait MatchmakeExtension{ #[method_id(1)] async fn close_participation(&self, gid: u32) -> Result<(), ErrorCode>; #[method_id(2)] async fn open_participation(&self, gid: u32) -> Result<(), ErrorCode>; - #[method_id(6)] - async fn create_matchmake_session( - &self, - gathering: Any, - message: String, - ) -> Result<(u32, Vec), ErrorCode>; - - #[method_id(9)] - async fn update_notification_data( - &self, - ty: u32, - param1: u32, - param2: u32, - str_param: String, - ) -> Result<(), ErrorCode>; - - #[method_id(10)] - async fn get_friend_notification_data( - &self, - ty: i32, - ) -> Result, ErrorCode>; - #[method_id(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( - &self, - gid: u32, - message: String, - dont_care_block_list: bool, - // this is to cheat support for v3-3-0 - //participation_count: u16, - ) -> Result, ErrorCode>; #[method_id(8)] - async fn modify_current_game_attribute( - &self, - gid: u32, - attrib_index: u32, - attrib_val: u32, - ) -> Result<(), ErrorCode>; + async fn modify_current_game_attribute(&self, gid: u32, attrib_index: u32, attrib_val: u32) -> Result<(), ErrorCode>; #[method_id(16)] async fn get_playing_session(&self, pids: Vec) -> Result, ErrorCode>; #[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( - &self, - session: CreateMatchmakeSessionParam, - ) -> Result; + async fn create_matchmake_session_with_param(&self, session: CreateMatchmakeSessionParam) -> Result; #[method_id(39)] - async fn join_matchmake_session_with_param( - &self, - session: JoinMatchmakeSessionParam, - ) -> Result; + async fn join_matchmake_session_with_param(&self, session: JoinMatchmakeSessionParam) -> Result; #[method_id(40)] - async fn auto_matchmake_with_param_postpone( - &self, - session: AutoMatchmakeParam, - ) -> Result; + async fn auto_matchmake_with_param_postpone(&self, session: AutoMatchmakeParam) -> Result; #[method_id(41)] - async fn find_matchmake_session_by_gathering_id_detail( - &self, - gid: u32, - ) -> Result; -} + async fn find_matchmake_session_by_gathering_id_detail(&self, gid: u32) -> Result; +} \ No newline at end of file diff --git a/rnex-core/src/rmc/protocols/mod.rs b/rnex-core/src/rmc/protocols/mod.rs index 411ae28..a34b265 100644 --- a/rnex-core/src/rmc/protocols/mod.rs +++ b/rnex-core/src/rmc/protocols/mod.rs @@ -2,7 +2,6 @@ pub mod account_management; pub mod auth; -pub mod datastore; pub mod friends; pub mod matchmake; pub mod matchmake_ext; @@ -12,7 +11,7 @@ pub mod nintendo_notification; pub mod notifications; pub mod ranking; pub mod secure; -pub mod util; +pub mod datastore; use crate::result::ResultExtension; use crate::rmc::message::RMCMessage; diff --git a/rnex-core/src/rmc/protocols/notifications.rs b/rnex-core/src/rmc/protocols/notifications.rs index e66f8fe..eef5c6c 100644 --- a/rnex-core/src/rmc/protocols/notifications.rs +++ b/rnex-core/src/rmc/protocols/notifications.rs @@ -1,37 +1,21 @@ -use macros::{RmcSerialize, method_id, rmc_proto}; +use macros::{RmcSerialize, method_id, rmc_proto, rmc_struct}; use rnex_core::PID; pub mod notification_types { pub const OWNERSHIP_CHANGED: u32 = 4000; pub const HOST_CHANGED: u32 = 110000; - pub const REQUEST_JOIN_GATHERING: u32 = 101; - pub const END_GATHERING: u32 = 102; } -cfg_if::cfg_if! { - if #[cfg(feature = "third-notif-param")]{ - #[derive(RmcSerialize, Debug, Default, Clone)] - #[rmc_struct(0)] - pub struct NotificationEvent { - pub pid_source: PID, - pub notif_type: u32, - pub param_1: PID, - pub param_2: PID, - pub str_param: String, - pub param_3: PID, - } - } else { - #[derive(RmcSerialize, Debug, Default, Clone)] - #[rmc_struct(0)] - pub struct NotificationEvent { - pub pid_source: PID, - pub notif_type: u32, - pub param_1: PID, - pub param_2: PID, - pub str_param: String, - } - } +#[derive(RmcSerialize, Debug, Default, Clone)] +#[rmc_struct(0)] +pub struct NotificationEvent { + pub pid_source: PID, + pub notif_type: u32, + pub param_1: PID, + pub param_2: PID, + pub str_param: String, + pub param_3: PID, } #[rmc_proto(14, NoReturn)] diff --git a/rnex-core/src/rmc/protocols/ranking.rs b/rnex-core/src/rmc/protocols/ranking.rs index 68be98f..53ec9af 100644 --- a/rnex-core/src/rmc/protocols/ranking.rs +++ b/rnex-core/src/rmc/protocols/ranking.rs @@ -1,4 +1,4 @@ -use macros::{RmcSerialize, method_id, rmc_proto}; +use macros::{rmc_struct, rmc_proto, RmcSerialize, method_id}; use rnex_core::kerberos::KerberosDateTime; use rnex_core::rmc::structures::qbuffer::QBuffer; @@ -16,35 +16,29 @@ pub struct CompetitionRankingGetParam { #[derive(RmcSerialize, Debug, Default, Clone)] #[rmc_struct(0)] -pub struct CompetitionRankingScoreInfo { +pub struct CompetitionRankingScoreInfo{ pub fest_id: u32, pub score_data: Vec, pub unk: u32, pub team_wins: Vec, - pub team_votes: Vec, + pub team_votes: Vec } #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(0)] -pub struct CompetitionRankingScoreData { +pub struct CompetitionRankingScoreData{ pub unk: u32, pub pid: u32, pub score: u32, pub modified: KerberosDateTime, pub unk2: u8, - pub appdata: QBuffer, + pub appdata: QBuffer } #[rmc_proto(112)] -pub trait Ranking { +pub trait Ranking{ #[method_id(16)] - async fn competition_ranking_get_param( - &self, - param: CompetitionRankingGetParam, - ) -> Result, ErrorCode>; + async fn competition_ranking_get_param(&self, param: CompetitionRankingGetParam) -> Result,ErrorCode>; #[method_id(18)] - async fn upload_competition_ranking_score( - &self, - param: UploadCompetitionData, - ) -> Result; + async fn upload_competition_ranking_score(&self, param: UploadCompetitionData) -> Result; } diff --git a/rnex-core/src/rmc/protocols/util.rs b/rnex-core/src/rmc/protocols/util.rs deleted file mode 100644 index a89c79b..0000000 --- a/rnex-core/src/rmc/protocols/util.rs +++ /dev/null @@ -1,9 +0,0 @@ -use macros::{method_id, rmc_proto}; - -use rnex_core::rmc::response::ErrorCode; - -#[rmc_proto(110)] -pub trait Utility { - #[method_id(1)] - async fn acquire_nex_unique_id(&self) -> Result; -} diff --git a/rnex-core/src/rmc/response.rs b/rnex-core/src/rmc/response.rs index d401892..b042877 100644 --- a/rnex-core/src/rmc/response.rs +++ b/rnex-core/src/rmc/response.rs @@ -6,7 +6,7 @@ use crate::rmc::response::ErrorCode::Core_Exception; use crate::rmc::structures::qresult::ERROR_MASK; use crate::util::SendingBufferConnection; use bytemuck::bytes_of; -use log::{error, warn}; +use log::error; use std::io; use std::io::{Read, Seek, Write}; use std::mem::transmute; @@ -157,13 +157,10 @@ pub async fn send_result( method_id, data: v, }, - Err(e) => { - warn!("error occurred during call: {:?}", e); - RMCResponseResult::Error { - call_id, - error_code: e.into(), - } - } + Err(e) => RMCResponseResult::Error { + call_id, + error_code: e.into(), + }, }; let response = RMCResponse { diff --git a/rnex-core/src/rmc/structures/matchmake.rs b/rnex-core/src/rmc/structures/matchmake.rs index 88deea0..a1518d1 100644 --- a/rnex-core/src/rmc/structures/matchmake.rs +++ b/rnex-core/src/rmc/structures/matchmake.rs @@ -1,14 +1,11 @@ -use cfg_if::cfg_if; use macros::RmcSerialize; use rnex_core::kerberos::KerberosDateTime; 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)] +#[derive(RmcSerialize, Debug, Clone, Default)] #[rmc_struct(0)] pub struct Gathering { pub self_gid: u32, @@ -24,60 +21,41 @@ pub struct Gathering { } // rmc structure -#[derive(RmcSerialize, Debug, Clone, Default, PartialEq)] +#[derive(RmcSerialize, Debug, Clone, Default)] #[rmc_struct(0)] pub struct MatchmakeParam { pub params: Vec<(String, Variant)>, } -cfg_if! { - if #[cfg(feature = "v3-5-0")]{ - #[derive(RmcSerialize, Debug, Clone, Default, PartialEq)] - #[rmc_struct(3)] - pub struct MatchmakeSession { - //inherits from - #[extends] - pub gathering: Gathering, +// rmc structure +#[derive(RmcSerialize, Debug, Clone, Default)] +#[rmc_struct(3)] +pub struct MatchmakeSession { + //inherits from + #[extends] + pub gathering: Gathering, - pub gamemode: u32, - pub attributes: Vec, - pub open_participation: bool, - pub matchmake_system_type: u32, - pub application_buffer: Vec, - pub participation_count: u32, - pub progress_score: u8, - pub session_key: Vec, - pub option0: u32, - pub matchmake_param: MatchmakeParam, - pub datetime: KerberosDateTime, - pub user_password: String, - pub refer_gid: u32, - pub user_password_enabled: bool, - pub system_password_enabled: bool, - } - } else { - #[derive(RmcSerialize, Debug, Clone, Default, PartialEq)] - #[rmc_struct(0)] - pub struct MatchmakeSession { - //inherits from - #[extends] - pub gathering: Gathering, - - pub gamemode: u32, - pub attributes: Vec, - pub open_participation: bool, - pub matchmake_system_type: u32, - pub application_buffer: Vec, - pub participation_count: u32, - pub session_key: Vec, - } - } + pub gamemode: u32, + pub attributes: Vec, + pub open_participation: bool, + pub matchmake_system_type: u32, + pub application_buffer: Vec, + pub participation_count: u32, + pub progress_score: u8, + pub session_key: Vec, + pub option0: u32, + pub matchmake_param: MatchmakeParam, + pub datetime: KerberosDateTime, + pub user_password: String, + pub refer_gid: u32, + pub user_password_enabled: bool, + pub system_password_enabled: bool, } #[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, @@ -123,40 +101,20 @@ pub struct MatchmakeBlockListParam { option_flag: u32, } -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 - } - } +#[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 { diff --git a/rnex-core/src/rmc/structures/mod.rs b/rnex-core/src/rmc/structures/mod.rs index 63ae484..33de120 100644 --- a/rnex-core/src/rmc/structures/mod.rs +++ b/rnex-core/src/rmc/structures/mod.rs @@ -13,15 +13,12 @@ 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")] StationUrlInvalid, #[error("error formatting text: {0}")] FormatError(#[from] fmt::Error), - #[error("uncategorized rmc error occurred: {0}")] - Other(Box), } pub type Result = std::result::Result; @@ -38,11 +35,10 @@ 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<()>; @@ -70,9 +66,6 @@ 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 deleted file mode 100644 index efb6c05..0000000 --- a/rnex-core/src/rmc/structures/string_set.rs +++ /dev/null @@ -1,95 +0,0 @@ -use std::{collections::HashSet, hash::Hash, str::FromStr, string::ToString}; - -use rnex_core::rmc::structures::RmcSerialize; - -#[derive(Debug, Clone)] -pub struct StringSet(pub 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("|") - .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) - }, - )?, - )) - } -} - -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"); - } - } - - let _: StringSet = StringSet::from_str("").unwrap(); - - let _: StringSet = StringSet::from_str("10").unwrap(); - } -} diff --git a/rnex-core/src/rmc/structures/variant.rs b/rnex-core/src/rmc/structures/variant.rs index c5c41b0..9f705d0 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, PartialEq)] +#[derive(Debug, Clone, Default)] pub enum Variant { #[default] None, diff --git a/rnex-core/src/rnex_proxy_common.rs b/rnex-core/src/rnex_proxy_common.rs index 54de962..d103e43 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::{Ipv4Addr, SocketAddr, SocketAddrV4}, + net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4}, }; use crate::{ diff --git a/rnex-core/src/util.rs b/rnex-core/src/util.rs index 2bcf87b..ff0150c 100644 --- a/rnex-core/src/util.rs +++ b/rnex-core/src/util.rs @@ -1,25 +1,24 @@ -use crate::reggie::{UnitPacketRead, UnitPacketWrite}; -use log::{error, info}; use std::ops::Deref; -use std::sync::{Arc, Weak}; -use std::vec; +use std::sync::Arc; +use log::{error, info}; use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; +use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio::sync::Notify; -use tokio::sync::mpsc::{Receiver, Sender, channel}; use tokio::task; +use crate::reggie::{UnitPacketRead, UnitPacketWrite}; #[derive(Clone)] pub struct SendingBufferConnection(Sender>, Arc); pub struct SplittableBufferConnection(SendingBufferConnection, Receiver>); -impl AsRef for SplittableBufferConnection { +impl AsRef for SplittableBufferConnection{ fn as_ref(&self) -> &SendingBufferConnection { &self.0 } } -impl Deref for SplittableBufferConnection { +impl Deref for SplittableBufferConnection{ type Target = SendingBufferConnection; fn deref(&self) -> &Self::Target { @@ -27,7 +26,9 @@ impl Deref for SplittableBufferConnection { } } -impl From for SplittableBufferConnection { + + +impl From for SplittableBufferConnection{ fn from(value: T) -> Self { Self::new(value) } @@ -47,6 +48,7 @@ impl SplittableBufferConnection { let mut recver = inside_recv; let mut stream = stream; + loop { tokio::select! { data = recver.recv() => { @@ -79,7 +81,7 @@ impl SplittableBufferConnection { } } } - if let Err(e) = stream.shutdown().await { + if let Err(e) = stream.shutdown().await{ error!("failed to shut down stream: {}", e); } }); @@ -89,11 +91,11 @@ impl SplittableBufferConnection { } } -impl SendingBufferConnection { - pub async fn send(&self, buffer: Vec) -> Option<()> { +impl SendingBufferConnection{ + pub async fn send(&self, buffer: Vec) -> Option<()>{ self.0.send(buffer).await.ok() } - pub fn is_alive(&self) -> bool { + pub fn is_alive(&self) -> bool{ !self.0.is_closed() } pub async fn disconnect(&self) { @@ -104,34 +106,12 @@ impl SendingBufferConnection { } } -impl SplittableBufferConnection { - pub async fn recv(&mut self) -> Option> { +impl SplittableBufferConnection{ + pub async fn recv(&mut self) -> Option>{ self.1.recv().await } - pub fn duplicate_sender(&self) -> SendingBufferConnection { + pub fn duplicate_sender(&self) -> SendingBufferConnection{ self.0.clone() } } - -struct WeakVec(Vec>); - -impl WeakVec { - pub fn new() -> Self { - Self(vec![]) - } - - pub fn from_vec(vec: Vec>) -> Self { - Self(vec) - } - - pub fn push(&mut self, val: Weak) { - self.0.retain(|v| v.upgrade().is_some()); - - self.0.push(val); - } - - pub fn iter(&self) -> impl Iterator> { - self.0.iter().filter_map(|w| w.upgrade()) - } -} diff --git a/rnex-core/src/versions.rs b/rnex-core/src/versions.rs index 03b71b5..7b5ec30 100644 --- a/rnex-core/src/versions.rs +++ b/rnex-core/src/versions.rs @@ -3,93 +3,95 @@ use std::ops::{BitAnd, BitOr}; use typenum::{Cmp, IsEqual, IsLess, IsLessOrEqual, Unsigned}; /// This trait represents a version at compile time -trait Version { +trait Version{ type Major: Unsigned; type Minor: Unsigned; } /// This struct contains nothing and is used to represent specific versions as an instance of /// [`Version`]. It is instances as `Ver` -struct Ver { - _phantom: PhantomData<(MAJ, MIN)>, +struct Ver{ + _phantom: PhantomData<(MAJ, MIN)> } -impl Version for Ver { +impl Version for Ver{ type Major = MAJ; type Minor = MIN; } /// Represents two versions which can be compared -trait ComparableVersion: Version { +trait ComparableVersion: Version{ type IsAtLeast: SameOrUnit; } -impl ComparableVersion for U -where +impl ComparableVersion for U where ::Major: Cmp, ::Minor: IsLessOrEqual, - ::Major: - IsEqual>>, - ::Major: IsLess< - Self::Major, - Output: BitOr< - typenum::And< - typenum::Eq, - typenum::LeEq, - >, - Output: SameOrUnit, - >, + ::Major: IsEqual< + Self::Major, + Output: BitAnd< + typenum::LeEq >, -{ + >, + ::Major: IsLess< + Self::Major, + Output: BitOr< + typenum::And< + typenum::Eq, + typenum::LeEq, + >, + Output: SameOrUnit + > + > { + type IsAtLeast = typenum::Or< typenum::Le, - typenum::And, typenum::LeEq>, + typenum::And< + typenum::Eq, + typenum::LeEq, + > >; } + /// Simple check for testing if the `TEST` version is at least `REQ` or higher. type VersionAbove = >::IsAtLeast; -trait VersionIsAtLeast {} +trait VersionIsAtLeast{} + +impl> VersionIsAtLeast for T{} -impl> VersionIsAtLeast - for T -{ -} /// Trait for containing the result of elements which only conditionally exist -trait CondElemResult { +trait CondElemResult{ type Output; } /// Empty helper struct which only servers to give a concrete type when creating fields in rmc /// structs which have a version requirement. This is not meant to be used directly, use /// [`MinVersion`] instead. -struct MinVersionElementHelper> { - _phantom: PhantomData<(T, REQUIRED, VER)>, +struct MinVersionElementHelper>{ + _phantom: PhantomData<(T, REQUIRED, VER)> } /// This should be used either with [`typenum::True`] or [`typenum::False`]. When `True` the [`Self::Output`] /// will be the same as the `T` you put into Output. When `False` it will always be `()` -trait SameOrUnit { +trait SameOrUnit{ type Output; } -impl SameOrUnit for typenum::True { +impl SameOrUnit for typenum::True{ type Output = T; } -impl SameOrUnit for typenum::False { +impl SameOrUnit for typenum::False{ type Output = (); } -impl> CondElemResult - for MinVersionElementHelper -{ +impl> CondElemResult for MinVersionElementHelper where { type Output = <>::IsAtLeast as SameOrUnit>::Output; } /// When the version condition is met the field will exist and will simply be `T` if not it will be /// replaced by `()`. Use this when you need to add versioning to rmc structs. -type MinVersion = - as CondElemResult>::Output; +type MinVersion = as CondElemResult>::Output; \ No newline at end of file diff --git a/setup-hook.sh b/setup-hook.sh deleted file mode 100755 index 04774d6..0000000 --- a/setup-hook.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -cp buildscripts/pre-commit .git/hooks/ diff --git a/test-all.sh b/test-all.sh deleted file mode 100755 index 989b74f..0000000 --- a/test-all.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/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" diff --git a/test-edition.sh b/test-edition.sh index aaafad6..ac3fc49 100755 --- a/test-edition.sh +++ b/test-edition.sh @@ -1,7 +1,4 @@ #!/usr/bin/env bash - -set -euo pipefail - if [ -z ${EDITION+x} ]; then EDITION=$1 fi