From 87336c66bed298d97efd10c746ff21ca8fe5078c Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 22 Apr 2024 18:14:32 -0400 Subject: [PATCH 01/67] chore: begin rewrite and TS migration --- .eslintrc.json | 42 - .gitignore | 7 +- LICENSE | 661 ++ README.md | 58 +- access.txt | 62 - app/.eslintrc.json | 41 - app/assets/css/connections-list-section.css | 15 - app/assets/css/main.css | 73 - app/assets/css/packet-details-section.css | 35 - app/assets/css/packets-section.css | 70 - app/assets/js/ipc.js | 33 - app/assets/js/renderer.js | 702 -- app/assets/js/util.js | 78 - app/index.html | 45 - app/index.js | 152 - build_games_list.js | 209 - eslint.config.js | 67 + nex/nex.txt | 69 - nex/nex_datastore.txt | 69 - nex/nex_match_making.txt | 69 - nex/nex_messaging.txt | 69 - nex/nex_ranking.txt | 69 - nex/nex_utility.txt | 69 - package-lock.json | 5907 +++-------------- package.json | 64 +- src/byte-stream.ts | 120 + src/connection.js | 463 -- src/fragmentation_manager.js | 72 - src/kerberos.js | 94 - src/nex/byte-stream.ts | 12 + src/nex/connection.ts | 349 + src/nex/counter.ts | 13 + src/nex/kerberos.ts | 62 + src/nex/protocols/manager.ts | 18 + src/nex/protocols/secure-connection/index.ts | 58 + .../secure-connection/requests/index.ts | 2 + .../secure-connection/requests/register-ex.ts | 26 + .../secure-connection/requests/register.ts | 22 + .../secure-connection/responses/index.ts | 2 + .../responses/register-ex.ts | 33 + .../secure-connection/responses/register.ts | 33 + src/nex/protocols/ticket-granting/index.ts | 74 + .../ticket-granting/requests/index.ts | 3 + .../ticket-granting/requests/login-ex.ts | 25 + .../ticket-granting/requests/login.ts | 21 + .../requests/request-ticket.ts | 24 + .../ticket-granting/responses/index.ts | 3 + .../ticket-granting/responses/login-ex.ts | 43 + .../ticket-granting/responses/login.ts | 43 + .../responses/request-ticket.ts | 40 + src/nex/prudp-packet.ts | 148 + src/nex/prudp-packetv0.ts | 96 + src/nex/prudp-packetv1.ts | 161 + src/nex/raw-rmc-packet.ts | 48 + src/nex/rmc-message.ts | 118 + src/nex/session.ts | 297 + src/nex/substream.ts | 90 + src/nex/titles.json | 2273 +++++++ src/nex/types/any-data-holder.ts | 48 + src/nex/types/bool.ts | 23 + src/nex/types/buffer.ts | 26 + src/nex/types/data.ts | 24 + src/nex/types/datetime.ts | 58 + src/nex/types/double.ts | 23 + src/nex/types/float.ts | 23 + src/nex/types/int16.ts | 23 + src/nex/types/int32.ts | 23 + src/nex/types/int64.ts | 23 + src/nex/types/int8.ts | 23 + src/nex/types/list.ts | 38 + src/nex/types/map.ts | 48 + src/nex/types/pid.ts | 31 + src/nex/types/qbuffer.ts | 25 + src/nex/types/qresult.ts | 340 + src/nex/types/result-range.ts | 33 + src/nex/types/rv-connection-data.ts | 51 + src/nex/types/rv-type.ts | 8 + src/nex/types/station-url.ts | 36 + src/nex/types/string.ts | 32 + src/nex/types/structure.ts | 16 + src/nex/types/uint16.ts | 23 + src/nex/types/uint32.ts | 23 + src/nex/types/uint64.ts | 23 + src/nex/types/uint8.ts | 23 + src/nex/types/variant.ts | 53 + src/packet.js | 297 - src/packetv0.js | 152 - src/packetv1.js | 186 - src/parser.js | 365 - src/pcap-parser.js | 110 - src/pcap-parser.ts | 116 + src/pcapng-parser.js | 384 -- src/pcapng-parser.ts | 400 ++ src/protocols/authentication.js | 162 - src/protocols/datastore.js | 811 --- src/protocols/friends_3ds.js | 140 - src/protocols/friends_wiiu.js | 104 - src/protocols/index.js | 19 - src/protocols/match_making.js | 758 --- src/protocols/match_making_ext.js | 150 - src/protocols/matchmake_extension.js | 908 --- src/protocols/message_delivery.js | 71 - src/protocols/nat_traversal.js | 166 - src/protocols/nintendo_notifications.js | 86 - src/protocols/notifications.js | 70 - .../patches/datastore_badge_arcade.js | 71 - .../patches/datastore_pokemon_bank.js | 343 - src/protocols/patches/datastore_smm.js | 744 --- .../patches/matchmake_extension_mk8.js | 71 - src/protocols/patches/ranking_legacy.js | 185 - src/protocols/patches/ranking_splatoon.js | 119 - .../patches/secure_connection_badge_arcade.js | 71 - src/protocols/patches/service_item_tkcd.js | 408 -- .../patches/service_item_wii_sports_club.js | 408 -- src/protocols/patches/shop_badge_arcade.js | 87 - src/protocols/patches/shop_pokemon_bank.js | 215 - src/protocols/ranking.js | 313 - src/protocols/requests/authentication.js | 151 - src/protocols/requests/datastore.js | 1048 --- .../requests/datastore_badge_arcade.js | 25 - .../requests/datastore_pokemon_bank.js | 362 - src/protocols/requests/datastore_smm.js | 950 --- src/protocols/requests/friends_3ds.js | 99 - src/protocols/requests/friends_wiiu.js | 53 - src/protocols/requests/match_making.js | 984 --- src/protocols/requests/match_making_ext.js | 145 - src/protocols/requests/matchmake_extension.js | 1185 ---- .../requests/matchmake_extension_mk8.js | 45 - src/protocols/requests/message_delivery.js | 25 - src/protocols/requests/nat_traversal.js | 176 - .../requests/nintendo_notifications.js | 45 - src/protocols/requests/notifications.js | 26 - src/protocols/requests/ranking.js | 423 -- src/protocols/requests/ranking_legacy.js | 358 - src/protocols/requests/ranking_splatoon.js | 87 - src/protocols/requests/secure_connection.js | 172 - .../secure_connection_badge_arcade.js | 14 - src/protocols/requests/service_item_tkcd.js | 435 -- .../requests/service_item_wii_sports_club.js | 414 -- src/protocols/requests/shop_badge_arcade.js | 51 - src/protocols/requests/shop_pokemon_bank.js | 173 - src/protocols/requests/storage_manager.js | 38 - src/protocols/requests/subscription.js | 364 - src/protocols/requests/utility.js | 115 - src/protocols/responses/authentication.js | 202 - src/protocols/responses/datastore.js | 809 --- .../responses/datastore_badge_arcade.js | 30 - .../responses/datastore_pokemon_bank.js | 325 - src/protocols/responses/datastore_smm.js | 690 -- src/protocols/responses/friends_3ds.js | 73 - src/protocols/responses/friends_wiiu.js | 75 - src/protocols/responses/match_making.js | 814 --- src/protocols/responses/match_making_ext.js | 111 - .../responses/matchmake_extension.js | 840 --- .../responses/matchmake_extension_mk8.js | 25 - src/protocols/responses/message_delivery.js | 14 - src/protocols/responses/nat_traversal.js | 98 - .../responses/nintendo_notifications.js | 18 - src/protocols/responses/notifications.js | 0 src/protocols/responses/ranking.js | 216 - src/protocols/responses/ranking_legacy.js | 190 - src/protocols/responses/ranking_splatoon.js | 87 - src/protocols/responses/secure_connection.js | 146 - .../secure_connection_badge_arcade.js | 33 - src/protocols/responses/service_item_tkcd.js | 426 -- .../responses/service_item_wii_sports_club.js | 387 -- src/protocols/responses/shop_badge_arcade.js | 33 - src/protocols/responses/shop_pokemon_bank.js | 187 - src/protocols/responses/storage_manager.js | 49 - src/protocols/responses/subscription.js | 363 - src/protocols/responses/utility.js | 138 - src/protocols/secure_connection.js | 189 - src/protocols/service_item.js | 41 - src/protocols/shop.js | 41 - src/protocols/storage_manager.js | 89 - src/protocols/subscription.js | 342 - src/protocols/types/authentication.js | 181 - src/protocols/types/datastore.js | 1835 ----- src/protocols/types/datastore_badge_arcade.js | 43 - src/protocols/types/datastore_pokemon_bank.js | 549 -- src/protocols/types/datastore_smm.js | 463 -- src/protocols/types/friends_3ds.js | 279 - src/protocols/types/friends_wiiu.js | 661 -- src/protocols/types/match_making.js | 1106 --- src/protocols/types/message_delivery.js | 181 - src/protocols/types/nintendo_notifications.js | 146 - src/protocols/types/notifications.js | 69 - src/protocols/types/ranking.js | 296 - src/protocols/types/ranking_legacy.js | 63 - src/protocols/types/secure_connection.js | 76 - src/protocols/types/service_item_tkcd.js | 1773 ----- .../types/service_item_wii_sports_club.js | 1155 ---- src/protocols/types/shop_badge_arcade.js | 38 - src/protocols/types/shop_pokemon_bank.js | 74 - src/protocols/types/utility.js | 33 - src/protocols/utility.js | 194 - src/rc4.ts | 48 + src/renderers/main/index.html | 12 + src/rmc.js | 111 - src/stream.js | 387 -- src/titles.json | 1125 ---- src/types.js | 445 -- src/types/frame.ts | 15 + src/types/nex/byte-stream-settings.ts | 12 + src/types/nex/packet.ts | 7 + src/types/nex/service-protocol.ts | 10 + src/types/nex/udp-packet.ts | 9 + src/types/pcap-parser.ts | 9 + src/types/pcapng-parser.ts | 51 + src/types/state.ts | 8 + src/util.js | 14 - src/windows/main/index.ts | 71 + src/windows/main/menu.ts | 8 + test/smm1/parse-smm1.js | 8 - titleids.txt | 73 - tsconfig.json | 24 + 216 files changed, 7969 insertions(+), 41968 deletions(-) delete mode 100644 .eslintrc.json create mode 100644 LICENSE delete mode 100644 access.txt delete mode 100644 app/.eslintrc.json delete mode 100644 app/assets/css/connections-list-section.css delete mode 100644 app/assets/css/main.css delete mode 100644 app/assets/css/packet-details-section.css delete mode 100644 app/assets/css/packets-section.css delete mode 100644 app/assets/js/ipc.js delete mode 100644 app/assets/js/renderer.js delete mode 100644 app/assets/js/util.js delete mode 100644 app/index.html delete mode 100644 app/index.js delete mode 100644 build_games_list.js create mode 100644 eslint.config.js delete mode 100644 nex/nex.txt delete mode 100644 nex/nex_datastore.txt delete mode 100644 nex/nex_match_making.txt delete mode 100644 nex/nex_messaging.txt delete mode 100644 nex/nex_ranking.txt delete mode 100644 nex/nex_utility.txt create mode 100644 src/byte-stream.ts delete mode 100644 src/connection.js delete mode 100644 src/fragmentation_manager.js delete mode 100644 src/kerberos.js create mode 100644 src/nex/byte-stream.ts create mode 100644 src/nex/connection.ts create mode 100644 src/nex/counter.ts create mode 100644 src/nex/kerberos.ts create mode 100644 src/nex/protocols/manager.ts create mode 100644 src/nex/protocols/secure-connection/index.ts create mode 100644 src/nex/protocols/secure-connection/requests/index.ts create mode 100644 src/nex/protocols/secure-connection/requests/register-ex.ts create mode 100644 src/nex/protocols/secure-connection/requests/register.ts create mode 100644 src/nex/protocols/secure-connection/responses/index.ts create mode 100644 src/nex/protocols/secure-connection/responses/register-ex.ts create mode 100644 src/nex/protocols/secure-connection/responses/register.ts create mode 100644 src/nex/protocols/ticket-granting/index.ts create mode 100644 src/nex/protocols/ticket-granting/requests/index.ts create mode 100644 src/nex/protocols/ticket-granting/requests/login-ex.ts create mode 100644 src/nex/protocols/ticket-granting/requests/login.ts create mode 100644 src/nex/protocols/ticket-granting/requests/request-ticket.ts create mode 100644 src/nex/protocols/ticket-granting/responses/index.ts create mode 100644 src/nex/protocols/ticket-granting/responses/login-ex.ts create mode 100644 src/nex/protocols/ticket-granting/responses/login.ts create mode 100644 src/nex/protocols/ticket-granting/responses/request-ticket.ts create mode 100644 src/nex/prudp-packet.ts create mode 100644 src/nex/prudp-packetv0.ts create mode 100644 src/nex/prudp-packetv1.ts create mode 100644 src/nex/raw-rmc-packet.ts create mode 100644 src/nex/rmc-message.ts create mode 100644 src/nex/session.ts create mode 100644 src/nex/substream.ts create mode 100644 src/nex/titles.json create mode 100644 src/nex/types/any-data-holder.ts create mode 100644 src/nex/types/bool.ts create mode 100644 src/nex/types/buffer.ts create mode 100644 src/nex/types/data.ts create mode 100644 src/nex/types/datetime.ts create mode 100644 src/nex/types/double.ts create mode 100644 src/nex/types/float.ts create mode 100644 src/nex/types/int16.ts create mode 100644 src/nex/types/int32.ts create mode 100644 src/nex/types/int64.ts create mode 100644 src/nex/types/int8.ts create mode 100644 src/nex/types/list.ts create mode 100644 src/nex/types/map.ts create mode 100644 src/nex/types/pid.ts create mode 100644 src/nex/types/qbuffer.ts create mode 100644 src/nex/types/qresult.ts create mode 100644 src/nex/types/result-range.ts create mode 100644 src/nex/types/rv-connection-data.ts create mode 100644 src/nex/types/rv-type.ts create mode 100644 src/nex/types/station-url.ts create mode 100644 src/nex/types/string.ts create mode 100644 src/nex/types/structure.ts create mode 100644 src/nex/types/uint16.ts create mode 100644 src/nex/types/uint32.ts create mode 100644 src/nex/types/uint64.ts create mode 100644 src/nex/types/uint8.ts create mode 100644 src/nex/types/variant.ts delete mode 100644 src/packet.js delete mode 100644 src/packetv0.js delete mode 100644 src/packetv1.js delete mode 100644 src/parser.js delete mode 100644 src/pcap-parser.js create mode 100644 src/pcap-parser.ts delete mode 100644 src/pcapng-parser.js create mode 100644 src/pcapng-parser.ts delete mode 100644 src/protocols/authentication.js delete mode 100644 src/protocols/datastore.js delete mode 100644 src/protocols/friends_3ds.js delete mode 100644 src/protocols/friends_wiiu.js delete mode 100644 src/protocols/index.js delete mode 100644 src/protocols/match_making.js delete mode 100644 src/protocols/match_making_ext.js delete mode 100644 src/protocols/matchmake_extension.js delete mode 100644 src/protocols/message_delivery.js delete mode 100644 src/protocols/nat_traversal.js delete mode 100644 src/protocols/nintendo_notifications.js delete mode 100644 src/protocols/notifications.js delete mode 100644 src/protocols/patches/datastore_badge_arcade.js delete mode 100644 src/protocols/patches/datastore_pokemon_bank.js delete mode 100644 src/protocols/patches/datastore_smm.js delete mode 100644 src/protocols/patches/matchmake_extension_mk8.js delete mode 100644 src/protocols/patches/ranking_legacy.js delete mode 100644 src/protocols/patches/ranking_splatoon.js delete mode 100644 src/protocols/patches/secure_connection_badge_arcade.js delete mode 100644 src/protocols/patches/service_item_tkcd.js delete mode 100644 src/protocols/patches/service_item_wii_sports_club.js delete mode 100644 src/protocols/patches/shop_badge_arcade.js delete mode 100644 src/protocols/patches/shop_pokemon_bank.js delete mode 100644 src/protocols/ranking.js delete mode 100644 src/protocols/requests/authentication.js delete mode 100644 src/protocols/requests/datastore.js delete mode 100644 src/protocols/requests/datastore_badge_arcade.js delete mode 100644 src/protocols/requests/datastore_pokemon_bank.js delete mode 100644 src/protocols/requests/datastore_smm.js delete mode 100644 src/protocols/requests/friends_3ds.js delete mode 100644 src/protocols/requests/friends_wiiu.js delete mode 100644 src/protocols/requests/match_making.js delete mode 100644 src/protocols/requests/match_making_ext.js delete mode 100644 src/protocols/requests/matchmake_extension.js delete mode 100644 src/protocols/requests/matchmake_extension_mk8.js delete mode 100644 src/protocols/requests/message_delivery.js delete mode 100644 src/protocols/requests/nat_traversal.js delete mode 100644 src/protocols/requests/nintendo_notifications.js delete mode 100644 src/protocols/requests/notifications.js delete mode 100644 src/protocols/requests/ranking.js delete mode 100644 src/protocols/requests/ranking_legacy.js delete mode 100644 src/protocols/requests/ranking_splatoon.js delete mode 100644 src/protocols/requests/secure_connection.js delete mode 100644 src/protocols/requests/secure_connection_badge_arcade.js delete mode 100644 src/protocols/requests/service_item_tkcd.js delete mode 100644 src/protocols/requests/service_item_wii_sports_club.js delete mode 100644 src/protocols/requests/shop_badge_arcade.js delete mode 100644 src/protocols/requests/shop_pokemon_bank.js delete mode 100644 src/protocols/requests/storage_manager.js delete mode 100644 src/protocols/requests/subscription.js delete mode 100644 src/protocols/requests/utility.js delete mode 100644 src/protocols/responses/authentication.js delete mode 100644 src/protocols/responses/datastore.js delete mode 100644 src/protocols/responses/datastore_badge_arcade.js delete mode 100644 src/protocols/responses/datastore_pokemon_bank.js delete mode 100644 src/protocols/responses/datastore_smm.js delete mode 100644 src/protocols/responses/friends_3ds.js delete mode 100644 src/protocols/responses/friends_wiiu.js delete mode 100644 src/protocols/responses/match_making.js delete mode 100644 src/protocols/responses/match_making_ext.js delete mode 100644 src/protocols/responses/matchmake_extension.js delete mode 100644 src/protocols/responses/matchmake_extension_mk8.js delete mode 100644 src/protocols/responses/message_delivery.js delete mode 100644 src/protocols/responses/nat_traversal.js delete mode 100644 src/protocols/responses/nintendo_notifications.js delete mode 100644 src/protocols/responses/notifications.js delete mode 100644 src/protocols/responses/ranking.js delete mode 100644 src/protocols/responses/ranking_legacy.js delete mode 100644 src/protocols/responses/ranking_splatoon.js delete mode 100644 src/protocols/responses/secure_connection.js delete mode 100644 src/protocols/responses/secure_connection_badge_arcade.js delete mode 100644 src/protocols/responses/service_item_tkcd.js delete mode 100644 src/protocols/responses/service_item_wii_sports_club.js delete mode 100644 src/protocols/responses/shop_badge_arcade.js delete mode 100644 src/protocols/responses/shop_pokemon_bank.js delete mode 100644 src/protocols/responses/storage_manager.js delete mode 100644 src/protocols/responses/subscription.js delete mode 100644 src/protocols/responses/utility.js delete mode 100644 src/protocols/secure_connection.js delete mode 100644 src/protocols/service_item.js delete mode 100644 src/protocols/shop.js delete mode 100644 src/protocols/storage_manager.js delete mode 100644 src/protocols/subscription.js delete mode 100644 src/protocols/types/authentication.js delete mode 100644 src/protocols/types/datastore.js delete mode 100644 src/protocols/types/datastore_badge_arcade.js delete mode 100644 src/protocols/types/datastore_pokemon_bank.js delete mode 100644 src/protocols/types/datastore_smm.js delete mode 100644 src/protocols/types/friends_3ds.js delete mode 100644 src/protocols/types/friends_wiiu.js delete mode 100644 src/protocols/types/match_making.js delete mode 100644 src/protocols/types/message_delivery.js delete mode 100644 src/protocols/types/nintendo_notifications.js delete mode 100644 src/protocols/types/notifications.js delete mode 100644 src/protocols/types/ranking.js delete mode 100644 src/protocols/types/ranking_legacy.js delete mode 100644 src/protocols/types/secure_connection.js delete mode 100644 src/protocols/types/service_item_tkcd.js delete mode 100644 src/protocols/types/service_item_wii_sports_club.js delete mode 100644 src/protocols/types/shop_badge_arcade.js delete mode 100644 src/protocols/types/shop_pokemon_bank.js delete mode 100644 src/protocols/types/utility.js delete mode 100644 src/protocols/utility.js create mode 100644 src/rc4.ts create mode 100644 src/renderers/main/index.html delete mode 100644 src/rmc.js delete mode 100644 src/stream.js delete mode 100644 src/titles.json delete mode 100644 src/types.js create mode 100644 src/types/frame.ts create mode 100644 src/types/nex/byte-stream-settings.ts create mode 100644 src/types/nex/packet.ts create mode 100644 src/types/nex/service-protocol.ts create mode 100644 src/types/nex/udp-packet.ts create mode 100644 src/types/pcap-parser.ts create mode 100644 src/types/pcapng-parser.ts create mode 100644 src/types/state.ts delete mode 100644 src/util.js create mode 100644 src/windows/main/index.ts create mode 100644 src/windows/main/menu.ts delete mode 100644 test/smm1/parse-smm1.js delete mode 100644 titleids.txt create mode 100644 tsconfig.json diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index bcb34ee..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "env": { - "node": true, - "commonjs": true, - "es2021": true - }, - "extends": [ - "eslint:recommended", - "plugin:jsdoc/recommended" - ], - "overrides": [ - ], - "parserOptions": { - "ecmaVersion": "latest" - }, - "rules": { - "indent": [ - "error", - "tab" - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "single" - ], - "semi": [ - "error", - "always" - ] - }, - "plugins": [ - "jsdoc" - ], - "settings": { - "jsdoc": { - "mode": "typescript" - } - } -} diff --git a/.gitignore b/.gitignore index f4702b1..50f69ec 100644 --- a/.gitignore +++ b/.gitignore @@ -58,7 +58,6 @@ typings/ .env # custom -nex-keys.txt -*.pcapng -t.js -builds \ No newline at end of file +dist +*.pcap +*.pcapng \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0ad25db --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/README.md b/README.md index 5045b84..1b55577 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,27 @@ # NEX Viewer -### Utility for parsing and (eventually) viewing NEX connections from PCAP(NG) network dumps - -## TODO: -### This tool is still VERY early in development, so nearly nothing is finished -- [x] PRUDP v0 packet parsing -- [x] PRUDP v1 packet parsing -- [ ] Fragmented payloads -- [ ] SMM DataStore method 50 (0x32) (`DataStoreSMM::GetCustomRankingByDataId`) is completely busted -- [ ] NEX Protocols (there is mixed support, some protocols are partially implemented) -- [ ] CLI Display - - -## Installation -``` -npm i https://github.com/PretendoNetwork/nex-viewer -``` - -## Example usage -```js -const NEXParser = require('../..'); -const parser = new NEXParser(); - -parser.on('packet', packet => { - // DO SOMETHING - console.log(packet); -}); - -parser.parse(__dirname + '/smm.pcapng'); -``` +### Utility for viewing PRUDP connections and NEX/Rendez-Vous sessions. ## NEX keys -PRUDP packet payloads get encrypted using a key which is encrypted using a key which is derived from your NEX account PID and password. In order to read packets, `nex-viewer` requires a `nex-keys.txt` file to be placed in any of these locations: +> [!WARNING] +> Older versions of NEX Viewer precomputed the Kerberos keys for each password. These precomputed keys are NOT usable in newer versions of NEX Viewer. Password files must now always contain the raw game server password for each PID -- `src` folder of this repo -- Root folder of this repo -- `%AppData%/Wireshark/nex-keys.txt` (Windows) -- `~/.config/wireshark/nex-keys.txt` (Linux/MacOS) +In order to decrypt PRUDP packet payloads for the games secure server(s) your game server account credentials must be known by NEX Viewer. populate your credentials file in one of the following locations -`nex-viewer` will check the local repo first then look elsewhere for the file depending on your operating system. `nex-keys.txt` must be in the following format: +- `%AppData%/NEXViewer/game-server-passwords.txt` (Windows) +- `~/.config/nex-viewer/game-server-passwords.txt` (Linux/MacOS) + +`game-server-passwords.txt` must be in the following format: ``` -NEX_PID:NEX_PASSWORD -NEX_PID:NEX_PASSWORD -NEX_PID:NEX_PASSWORD -NEX_PID:NEX_PASSWORD +PID:PASSWORD +PID:PASSWORD +PID:PASSWORD +PID:PASSWORD +etc... ``` -With each NEX account details on a new line. Each time `nex-viewer` runs it will derive the correct crypto key from each PID:PASSWORD and write it back to `nex-keys.txt`. This way your NEX password does not stay in plain-text on disk - -## WARNING! -DO NOT SHARE YOUR NEX PID AND PASSWORD WITH ANYBODY UNLESS YOU ABSOLUTELY KNOW WHAT YOU ARE DOING OR YOU DO NOT CARE ABOUT THE ACCOUNT. THIS PID/PASSWORD COMBINATION IS WHAT THE CONSOLE USES TO VERIFY YOU WHEN PLAYING ONLINE, NOT YOUR NNID USERNAME/PASSWORD. SHARING THESE DETAILS CAN ALLOW ANYONE TO LOGIN TO ANY GAME UNDER YOUR ACCOUNT +> [!CAUTION] +DO NOT SHARE YOUR NEX PID AND PASSWORD WITH ANYBODY UNLESS YOU ABSOLUTELY KNOW WHAT YOU ARE DOING OR YOU DO NOT CARE ABOUT THE ACCOUNT. THIS PID/PASSWORD COMBINATION IS WHAT THE CONSOLE USES TO AUTHENTICATE YOU WHEN PLAYING ONLINE, NOT YOUR NNID USERNAME/PASSWORD. SHARING THESE DETAILS CAN ALLOW ANYONE TO LOGIN TO ANY GAME UNDER YOUR ACCOUNT. ## Obtaining NEX account details NEX accounts are _**not**_ the same thing as NNIDs. How you obtain your NEX account details depends on your system. See below for details diff --git a/access.txt b/access.txt deleted file mode 100644 index c2d70fa..0000000 --- a/access.txt +++ /dev/null @@ -1,62 +0,0 @@ -Angry Birds Star Wars 3DS | fbae7416 -Angry Birds Trilogy 3DS | ac4fbf0d -Animal Crossing: New Leaf | d6f08b40 -Animal Crossing Plaza | 7b9b09cb -Axiom Verge | 24e0a63b -Badge Arcade | 82d5962d -BIOHAZARD REVELATIONS UE | 59d539a9 -DKC: Tropical Freeze | 7fcf384a -DuckTales: Remastered | 1294a96c -FAST Racing NEO | 811aa39f -FotNS: Ken's Rage 2 | 9994e29c -Hyrule Warriors | 7fcc1f7c -Injustice: Gods Among Us | 65e9f4d6 -IRONFALL Invasion | feb81c7c -Kid Icarus Uprising | 58a7e494 -Legend of Kay | 478232f3 -Luigi's Mansion 2 | 3861a9f8 -Mario & Sonic Rio 2016 3DS | a2dbfa39 -Mario & Sonic Rio 2016 Wii U | 63fecb0f -MARIO & SONIC SOCHI 2014 | 585214a5 -MARIO KART 7 | 6181dff1 -MARIO KART 8 | 25dbf96a -Mario Tennis Open | 0fabeff2 -Mario Tennis: Ultra Smash | c69b92a0 -Mario vs. DK: Tipping Stars | d8927c3f -Metroid Prime: FF | f79fb3c5 -Mighty No. 9 | bb980c2e -Minecraft: Wii U Edition | f1b61c8e -Nano Assault Neo | 7e484a8e -NINJA GAIDEN 3: Razor's Edge | f857b4bd -Nova-111 | bafe9856 -OlliOlli | 60e5df12 -PIKMIN 3 | f6accfc1 -Pokémon Bank | 9a2961d8 -Pokémon Rumble World | 844f1d0c -Pokémon X/Y | 876138df -POKKÉN TOURNAMENT | 6ef3adf1 -Puddle | afcffb5c -PUYOPUYOTETRIS | 4eb0ca36 -RTK 12 | bfede098 -Runner2 | 1084452a -SI2 | 44adeb87 -SONIC LOST WORLD | 69a9fc95 -Sonic Transformed | b26a3421 -Splatoon | 6f599f81 -Star Wars Pinball | ecd0e530 -Steel Diver: Sub Wars | fb9537fe -Super Mario Maker | 9f2b4678 -Super Smash Bros. | 2869ba38 -Team Kirby Clash Deluxe | e0c85605 -TEKKEN TAG 2 Wii U EDITION | 0f037f64 -Terraria | 3d37fbdb -TLoZ: Tri Force Heroes | c1621b84 -Trine 2 | f9c35adc -WARRIORS OROCHI 3 Hyper | d74bb27d -Wii Karaoke U | dfc5a4ac -Wii Party U | a5b77314 -Wii Sports Club | 4d324052 -Xenoblade Chronicles X | 59d7be84 -Yo-kai Watch 2 | 7ab183bb -Zen Pinball 2 | 2ff15f7e -役満 鳳凰 | 23aab2d3 diff --git a/app/.eslintrc.json b/app/.eslintrc.json deleted file mode 100644 index 63eeedf..0000000 --- a/app/.eslintrc.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "env": { - "browser": true, - "commonjs": true, - "es2021": true - }, - "extends": [ - "eslint:recommended", - "plugin:jsdoc/recommended" - ], - "overrides": [ - ], - "parserOptions": { - "ecmaVersion": 2020, - "sourceType": "module", - "ecmaFeatures": { - "jsx": true - } - }, - "rules": { - "indent": [ - "error", - "tab" - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "single" - ], - "semi": [ - "error", - "always" - ] - }, - "plugins": [ - "jsdoc" - ] -} diff --git a/app/assets/css/connections-list-section.css b/app/assets/css/connections-list-section.css deleted file mode 100644 index 3049f3f..0000000 --- a/app/assets/css/connections-list-section.css +++ /dev/null @@ -1,15 +0,0 @@ -#connections-list .connection { - padding-top: 5px; - padding-left: 30px; - cursor: pointer; -} - -#connections-list .connection:hover { - background: #8FBDDA !important; - color: black !important; -} - -#connections-list .connection.selected { - background: #308dc7; - color: white; -} \ No newline at end of file diff --git a/app/assets/css/main.css b/app/assets/css/main.css deleted file mode 100644 index b17f727..0000000 --- a/app/assets/css/main.css +++ /dev/null @@ -1,73 +0,0 @@ -* { - box-sizing: border-box; -} - -html, -body { - height: 100vh; - margin: 0; -} - -body { - background-color: #F8F8F8; - margin: 0; - font-size: large; - overflow: hidden; -} - -#header { - background: #5d8aad; - color: white; - padding: 5px; - font-family: system-ui; - display: flex; - align-items: center; - gap: 20px; -} - -#header-search { - flex: 1; -} - -.search-hidden { - display: none; -} - -main { - min-height: calc(100% - 30px); - padding: 10px; - height: auto; - display: grid; - grid-template-columns: 1fr 1fr; - grid-template-rows: 1fr 1fr; - gap: 10px 10px; - grid-template-areas: - "packets packets" - "packet-details connections-list"; -} - -#packets { - grid-area: packets; -} - -#packet-details { - grid-area: packet-details; -} - -#connections-list { - grid-area: connections-list; -} - -#packets, -#packet-details, -#connections-list { - border: 1px solid grey; - overflow-y: scroll; - overflow-x: scroll; - font-family: monospace; - white-space: nowrap; -} - -summary { - cursor: pointer; -} \ No newline at end of file diff --git a/app/assets/css/packet-details-section.css b/app/assets/css/packet-details-section.css deleted file mode 100644 index 349f82f..0000000 --- a/app/assets/css/packet-details-section.css +++ /dev/null @@ -1,35 +0,0 @@ -/* Put the first
tag into place */ -#packet-details>details { - padding-top: 10px; - padding-left: 30px; -} - -/* Change the huge arrow with a smaller one */ -#packet-details details>summary { - list-style-type: '▸'; -} - -#packet-details details[open]>summary { - list-style-type: '▾'; -} - -/* Move the arrow/ tag back in line with the rest of the list */ -#packet-details details { - margin-left: -10px; -} - -/* Offset child
elements for a cascading effect */ -#packet-details details>div { - margin-left: 25px; -} - -/* Offset spans */ -#packet-details span.name { - margin-right: 3px; -} - -/* Used in packet stack traces */ -#packet-details code { - display: block; - white-space: pre-wrap; -} \ No newline at end of file diff --git a/app/assets/css/packets-section.css b/app/assets/css/packets-section.css deleted file mode 100644 index 521a114..0000000 --- a/app/assets/css/packets-section.css +++ /dev/null @@ -1,70 +0,0 @@ -/* -Give the section 0 height initially. -Height is set by the JS to account for overflow - */ -#packets { - height: 0px; -} - -#packet-list { - border-collapse: collapse; - font-size: 16px; - min-width: 100%; - text-align: left; -} - -/* Keep header at the top during scrolling */ -#packet-list thead { - position: sticky; - top: 0; - background: white; -} - -/* Border between columns and remove click events */ -#packet-list th, -#packet-list td { - border-right: 1px solid grey; - cursor: default; -} - -#packet-list thead { - color: grey; - white-space: nowrap; -} - -#packet-list tbody tr { - background: #DAEEFF; -} - -#packet-list tbody tr:hover { - background: #8FBDDA !important; - color: black !important; -} - -#packet-list tbody tr.selected { - background: #308dc7; - color: white; -} - -#packet-list tbody tr.error { - background: #ffa4a4; -} - -#packet-list tbody tr.error:hover { - background: #ff5858 !important; - color: black !important; -} - -#packet-list tbody tr.error.selected { - background: #DD1717; - color: white; -} - -#packet-list tbody tr.hidden { - display: none; -} - -#packet-list tbody td { - white-space: nowrap; - cursor: pointer; -} \ No newline at end of file diff --git a/app/assets/js/ipc.js b/app/assets/js/ipc.js deleted file mode 100644 index 7bd58b3..0000000 --- a/app/assets/js/ipc.js +++ /dev/null @@ -1,33 +0,0 @@ -const { ipcRenderer } = require('electron'); -import { ready, removeAllChildNodes } from './util.js'; -import { - populateConnectionsList, - addPacketToList, - connectionsListSection, - packetDetailsSection, - packetsTableBodySection, - hidePingPackets, - showPingPackets -} from './renderer.js'; - -ipcRenderer.on('clear-sections', () => { - removeAllChildNodes(packetsTableBodySection); - removeAllChildNodes(packetDetailsSection); - removeAllChildNodes(connectionsListSection); -}); - -ipcRenderer.on('packet', (event, packet) => { - addPacketToList(JSON.parse(packet)); -}); - -ipcRenderer.on('connections', (event, connections) => { - populateConnectionsList(JSON.parse(connections)); -}); - -ipcRenderer.on('hide-ping-packets', hidePingPackets); - -ipcRenderer.on('show-ping-packets', showPingPackets); - -ready(() => { - ipcRenderer.send('renderer-ready'); -}); \ No newline at end of file diff --git a/app/assets/js/renderer.js b/app/assets/js/renderer.js deleted file mode 100644 index c73ce1e..0000000 --- a/app/assets/js/renderer.js +++ /dev/null @@ -1,702 +0,0 @@ -import { - removeAllChildNodes, - toHexString, - isObject, - isArray, - isNEXPrimative, - emptyObject -} from './util.js'; - -const mainElement = document.querySelector('main'); -const packetsSection = document.getElementById('packets'); -export const packetDetailsSection = document.getElementById('packet-details'); -export const connectionsListSection = document.getElementById('connections-list'); -export const packetsTableBodySection = packetsSection.querySelector('tbody'); -let selectedPacket; -let displayPingPackets = false; - -const LIST_TYPE_REGEX = /List<(.*)>/; -const MAP_TYPE_REGEX = /Map<(.*)>/; - -document.querySelector('#header-search').addEventListener('keyup', event => { - const filter = event.target.value; - - const packets = packetsTableBodySection.querySelectorAll('tr[data-serialized]'); - - for (const packet of packets) { - if (packet.outerHTML.toLowerCase().includes(filter.toLowerCase())) { - packet.classList.remove('search-hidden'); - } else { - packet.classList.add('search-hidden'); - } - } - - if (filter.trim() === '') { - if (selectedPacket) { - selectedPacket.scrollIntoView({block: 'nearest', inline: 'nearest'}); - } - } -}); - -/** - * @returns {void} - */ -function resizePacketsSection() { - // * Hack to get the exact height of the element to match the grid - // * while being set to `display: block` for overflow - const mainElement = document.querySelector('main'); - const gridTemplateRows = getComputedStyle(mainElement).getPropertyValue('grid-template-rows'); - const height = gridTemplateRows.split(' ')[0]; - - // * Sometimes doesn't visually update? - packetsSection.style.height = height; - packetDetailsSection.style.height = height; - connectionsListSection.style.height = height; -} - -const mainElementResizeObserver = new ResizeObserver(() => { - resizePacketsSection(); -}); - -mainElementResizeObserver.observe(mainElement); - -/** - * @param {object} connections List of NEX connections - */ -export function populateConnectionsList(connections) { - for (const connection of connections) { - const connectionElementDiv = document.createElement('div'); - connectionElementDiv.classList.add('connection'); - - let title; - - // * Hack to detect raw RMC connections - if (connection.discriminator !== 'authentication' && connection.discriminator !== 'secure') { - title = `${connection.discriminator} ${connection.title.name || 'Unknown'} (${connection.secure ? 'Secure' : 'Authentication'})`; - } else { - title = `${connection.title.name || 'Unknown'} (${connection.secure ? 'Secure' : 'Authentication'})`; - } - - const connectionTitle = document.createElement('span'); - connectionTitle.appendChild(document.createTextNode(title)); - - connectionElementDiv.appendChild(connectionTitle); - - connectionElementDiv.addEventListener('click', () => { - if (connectionElementDiv.classList.contains('selected')) { - removePacketFilter(); - } else { - filterPacketsByDiscriminator(connection.discriminator); - } - - document.querySelector('.connection.selected')?.classList.toggle('selected'); - connectionElementDiv.classList.toggle('selected'); - }); - - connectionsListSection.appendChild(connectionElementDiv); - } -} - -/** - * Removes the packet filtering and shows all packets - */ -function removePacketFilter() { - const packets = packetsTableBodySection.querySelectorAll('tbody tr'); - - for (const packet of packets) { - packet.classList.remove('hidden'); - } -} - -/** - * Hides PING packets from the packets view - */ -export function hidePingPackets() { - displayPingPackets = true; - const packetsToHide = packetsTableBodySection.querySelectorAll('[data-packet-type="PING"]:not(.hidden)'); - - for (const packet of packetsToHide) { - packet.classList.add('hidden'); - } -} - -/** - * Shows PING packets in the packets view - */ -export function showPingPackets() { - displayPingPackets = false; - const packetsToShow = packetsTableBodySection.querySelectorAll('[data-packet-type="PING"].hidden'); - - for (const packet of packetsToShow) { - packet.classList.remove('hidden'); - } -} - -/** - * @param {string} discriminator Connection discriminator - */ -function filterPacketsByDiscriminator(discriminator) { - const packets = packetsTableBodySection.querySelectorAll('tbody tr'); - - for (const packet of packets) { - packet.classList.remove('hidden'); - - const packetData = JSON.parse(packet.dataset.serialized); - - if (packetData.rawRMC) { - if (packetData.server !== discriminator) { - packet.classList.add('hidden'); - } - } else { - if (packetData.sourceAddress !== discriminator && packetData.destinationAddress !== discriminator) { - packet.classList.add('hidden'); - } - } - - if (displayPingPackets && packet.dataset.packetType === 'PING') { - packet.classList.add('hidden'); - } - } -} - -/** - * @param {object} packet PRUDP packet data to be added to the packet list - */ -export function addPacketToList(packet) { - - const tr = document.createElement('tr'); - - const time = document.createElement('td'); - const source = document.createElement('td'); - const destination = document.createElement('td'); - const version = document.createElement('td'); - const info = document.createElement('td'); - - let infoData = []; - let isAck = false; - - if (!packet.rawRMC) { - infoData.push(packet.type); - } - - if (!packet.rawRMC && packet.type === 'DATA') { - infoData.push(`FRAGMENT=${packet.fragmentId}`); - } - - if (!packet.rawRMC && packet.flags.includes('ACK')) { - infoData.push('ACK'); - isAck = true; - } - - if (!packet.rawRMC && packet.flags.includes('MULTI_ACK')) { - infoData.push('MULTI_ACK'); - isAck = true; - } - - if (packet.stackTrace) { - tr.classList.add('error'); - } - - if (packet.type === 'DATA' && packet.fragmentId === 0 && !isAck) { - infoData.push(`${packet.rmc.protocolName}->${packet.rmc.methodName}`); - - if (packet.rmc.isRequest === true) { - infoData.push('REQUEST'); - } else if (packet.rmc.isRequest === false) { - infoData.push('RESPONSE'); - - if (packet.rmc.isSuccess === true) { - infoData.push('SUCCESS'); - } else if (packet.rmc.isSuccess === false) { - infoData.push('FAILURE'); - - if (packet.rmc.errorCode) { - infoData.push(`ERROR CODE=0x${packet.rmc.errorCode.toString(16)}`); - } - } - } - } - - const timeString = packet.rawRMC ? '' : packet.date; - const sourceString = packet.rawRMC ? '' : packet.sourceAddress; - const destinationString = packet.rawRMC ? '' : packet.destinationAddress; - const versionString = packet.rawRMC ? 'Raw RMC' : `v${packet.version}`; - const infoString = infoData.join(', '); - - time.appendChild(document.createTextNode(timeString)); - source.appendChild(document.createTextNode(sourceString)); - destination.appendChild(document.createTextNode(destinationString)); - version.appendChild(document.createTextNode(versionString)); - info.appendChild(document.createTextNode(infoString)); - - tr.appendChild(time); - tr.appendChild(source); - tr.appendChild(destination); - tr.appendChild(version); - tr.appendChild(info); - - tr.dataset.serialized = JSON.stringify(packet); - tr.dataset.packetType = packet.type; - - if (displayPingPackets && packet.type === 'PING') { - tr.classList.add('hidden'); - } - - packetsTableBodySection.appendChild(tr); -} - -/** - * @param {Element} tr The row to be selected in the packet list - */ -function setSelectedPacketRow(tr) { - document.querySelector('tr.selected')?.classList.toggle('selected'); - tr.classList.toggle('selected'); - - selectedPacket = tr; - - updatePacketDetails(JSON.parse(tr.dataset.serialized)); -} - -/** - * @param {object} packet PRUDP packet data to be formatted in the details section - */ -function updatePacketDetails(packet) { - const root = document.createElement('details'); - const rootSummary = document.createElement('summary'); - const rootDiv = document.createElement('div'); - - const rootElementSourceDiv = document.createElement('div'); - const rootElementSourceName = document.createElement('span'); - const rootElementSourceValue = document.createElement('span'); - rootElementSourceName.classList.add('name'); - rootElementSourceValue.classList.add('value'); - - const rootElementDestinationDiv = document.createElement('div'); - const rootElementDestinationName = document.createElement('span'); - const rootElementDestinationValue = document.createElement('span'); - rootElementDestinationName.classList.add('name'); - rootElementDestinationValue.classList.add('value'); - - const rootElementFlagsDiv = document.createElement('div'); - const rootElementFlagsName = document.createElement('span'); - const rootElementFlagsValue = document.createElement('span'); - rootElementFlagsName.classList.add('name'); - rootElementFlagsValue.classList.add('value'); - - const rootElementTypeDiv = document.createElement('div'); - const rootElementTypeName = document.createElement('span'); - const rootElementTypeValue = document.createElement('span'); - rootElementTypeName.classList.add('name'); - rootElementTypeValue.classList.add('value'); - - const rootElementSessionIdDiv = document.createElement('div'); - const rootElementSessionIdName = document.createElement('span'); - const rootElementSessionIdValue = document.createElement('span'); - rootElementSessionIdName.classList.add('name'); - rootElementSessionIdValue.classList.add('value'); - - const rootElementSignatureDiv = document.createElement('div'); - const rootElementSignatureName = document.createElement('span'); - const rootElementSignatureValue = document.createElement('span'); - rootElementSignatureName.classList.add('name'); - rootElementSignatureValue.classList.add('value'); - - const rootElementSequenceIdDiv = document.createElement('div'); - const rootElementSequenceIdName = document.createElement('span'); - const rootElementSequenceIdValue = document.createElement('span'); - rootElementSequenceIdName.classList.add('name'); - rootElementSequenceIdValue.classList.add('value'); - - const rootElementFragmentIdDiv = document.createElement('div'); - const rootElementFragmentIdName = document.createElement('span'); - const rootElementFragmentIdValue = document.createElement('span'); - rootElementFragmentIdName.classList.add('name'); - rootElementFragmentIdValue.classList.add('value'); - - const rootElementChecksumDiv = document.createElement('div'); - const rootElementChecksumName = document.createElement('span'); - const rootElementChecksumValue = document.createElement('span'); - rootElementChecksumName.classList.add('name'); - rootElementChecksumValue.classList.add('value'); - - rootElementSourceName.appendChild(document.createTextNode('Source:')); - rootElementSourceValue.appendChild(document.createTextNode(packet.source)); - rootElementDestinationName.appendChild(document.createTextNode('Destination:')); - rootElementDestinationValue.appendChild(document.createTextNode(packet.destination)); - rootElementFlagsName.appendChild(document.createTextNode('Flags:')); - rootElementFlagsValue.appendChild(document.createTextNode(JSON.stringify(packet.flags))); - rootElementTypeName.appendChild(document.createTextNode('Type:')); - rootElementTypeValue.appendChild(document.createTextNode(packet.type)); - rootElementSessionIdName.appendChild(document.createTextNode('SessionId:')); - rootElementSessionIdValue.appendChild(document.createTextNode(packet.sessionId)); - rootElementSignatureName.appendChild(document.createTextNode('Signature:')); - rootElementSignatureValue.appendChild(document.createTextNode(packet.signature)); - rootElementSequenceIdName.appendChild(document.createTextNode('SequenceId:')); - rootElementSequenceIdValue.appendChild(document.createTextNode(packet.sequenceId)); - rootElementFragmentIdName.appendChild(document.createTextNode('FragmentId:')); - rootElementFragmentIdValue.appendChild(document.createTextNode(packet.fragmentId)); - rootElementChecksumName.appendChild(document.createTextNode('Checksum:')); - rootElementChecksumValue.appendChild(document.createTextNode(packet.checksum)); - - rootElementSourceDiv.appendChild(rootElementSourceName); - rootElementSourceDiv.appendChild(rootElementSourceValue); - rootElementDestinationDiv.appendChild(rootElementDestinationName); - rootElementDestinationDiv.appendChild(rootElementDestinationValue); - rootElementFlagsDiv.appendChild(rootElementFlagsName); - rootElementFlagsDiv.appendChild(rootElementFlagsValue); - rootElementTypeDiv.appendChild(rootElementTypeName); - rootElementTypeDiv.appendChild(rootElementTypeValue); - rootElementSessionIdDiv.appendChild(rootElementSessionIdName); - rootElementSessionIdDiv.appendChild(rootElementSessionIdValue); - rootElementSignatureDiv.appendChild(rootElementSignatureName); - rootElementSignatureDiv.appendChild(rootElementSignatureValue); - rootElementSequenceIdDiv.appendChild(rootElementSequenceIdName); - rootElementSequenceIdDiv.appendChild(rootElementSequenceIdValue); - rootElementFragmentIdDiv.appendChild(rootElementFragmentIdName); - rootElementFragmentIdDiv.appendChild(rootElementFragmentIdValue); - rootElementChecksumDiv.appendChild(rootElementChecksumName); - rootElementChecksumDiv.appendChild(rootElementChecksumValue); - - rootSummary.appendChild(document.createTextNode('Packet')); - - rootDiv.appendChild(rootElementSourceDiv); - rootDiv.appendChild(rootElementDestinationDiv); - rootDiv.appendChild(rootElementFlagsDiv); - rootDiv.appendChild(rootElementTypeDiv); - rootDiv.appendChild(rootElementSessionIdDiv); - rootDiv.appendChild(rootElementSignatureDiv); - rootDiv.appendChild(rootElementSequenceIdDiv); - - if (packet.type === 'DATA') { - rootDiv.appendChild(rootElementFragmentIdDiv); - } - - if (packet.version === 0) { - rootDiv.appendChild(rootElementChecksumDiv); - } - - if (packet.stackTrace) { - const stackTraceRoot = document.createElement('div'); - const stackTraceRootDetails = document.createElement('details'); - const stackTraceRootSummary = document.createElement('summary'); - const stackTraceRootDetailsRoot = document.createElement('div'); - const stackTrace = document.createElement('code'); - - stackTrace.appendChild(document.createTextNode(packet.stackTrace)); - stackTraceRootDetailsRoot.appendChild(stackTrace); - stackTraceRootSummary.appendChild(document.createTextNode('Stack trace')); - stackTraceRootDetails.appendChild(stackTraceRootSummary); - stackTraceRootDetails.appendChild(stackTraceRootDetailsRoot); - stackTraceRoot.appendChild(stackTraceRootDetails); - rootDiv.appendChild(stackTraceRoot); - } else if (packet.type === 'DATA' && !packet.flags.includes('ACK') && !packet.flags.includes('MULTI_ACK')) { - const rmcRoot = document.createElement('div'); - const rmcRootDetails = document.createElement('details'); - const rmcRootSummary = document.createElement('summary'); - const rmcRootDetailsRoot = document.createElement('div'); - - const rmcRootDetailsProtocolIdDiv = document.createElement('div'); - const rmcRootDetailsProtocolIdName = document.createElement('span'); - const rmcRootDetailsProtocolIdValue = document.createElement('span'); - rmcRootDetailsProtocolIdName.classList.add('name'); - rmcRootDetailsProtocolIdValue.classList.add('value'); - - let rmcRootDetailsCustomIdDiv; - let rmcRootDetailsCustomIdName; - let rmcRootDetailsCustomIdValue; - if (packet.rmc.protocolId === 0x7F) { - rmcRootDetailsCustomIdDiv = document.createElement('div'); - rmcRootDetailsCustomIdName = document.createElement('span'); - rmcRootDetailsCustomIdValue = document.createElement('span'); - rmcRootDetailsCustomIdName.classList.add('name'); - rmcRootDetailsCustomIdValue.classList.add('value'); - } - - const rmcRootDetailsMethodIdDiv = document.createElement('div'); - const rmcRootDetailsMethodIdName = document.createElement('span'); - const rmcRootDetailsMethodIdValue = document.createElement('span'); - rmcRootDetailsMethodIdName.classList.add('name'); - rmcRootDetailsMethodIdValue.classList.add('value'); - - const rmcRootDetailsCallIdDiv = document.createElement('div'); - const rmcRootDetailsCallIdName = document.createElement('span'); - const rmcRootDetailsCallIdValue = document.createElement('span'); - rmcRootDetailsCallIdName.classList.add('name'); - rmcRootDetailsCallIdValue.classList.add('value'); - - const rmcRootDetailsErrorCodeDiv = document.createElement('div'); - const rmcRootDetailsErrorCodeName = document.createElement('span'); - const rmcRootDetailsErrorCodeValue = document.createElement('span'); - rmcRootDetailsErrorCodeName.classList.add('name'); - rmcRootDetailsErrorCodeValue.classList.add('value'); - - rmcRootDetailsProtocolIdName.appendChild(document.createTextNode('Protocol ID:')); - rmcRootDetailsProtocolIdValue.appendChild(document.createTextNode(packet.rmc.protocolId)); - - if (packet.rmc.protocolId === 0x7F) { - rmcRootDetailsCustomIdName.appendChild(document.createTextNode('Custom ID:')); - rmcRootDetailsCustomIdValue.appendChild(document.createTextNode(packet.rmc.customId)); - } - - rmcRootDetailsMethodIdName.appendChild(document.createTextNode('Method ID:')); - rmcRootDetailsMethodIdValue.appendChild(document.createTextNode(packet.rmc.methodId)); - rmcRootDetailsCallIdName.appendChild(document.createTextNode('Call ID:')); - rmcRootDetailsCallIdValue.appendChild(document.createTextNode(packet.rmc.callId)); - rmcRootDetailsErrorCodeName.appendChild(document.createTextNode('Error Code:')); - rmcRootDetailsErrorCodeValue.appendChild(document.createTextNode(packet.rmc.errorCode)); - - rmcRootDetailsProtocolIdDiv.appendChild(rmcRootDetailsProtocolIdName); - rmcRootDetailsProtocolIdDiv.appendChild(rmcRootDetailsProtocolIdValue); - - if (packet.rmc.protocolId === 0x7F) { - rmcRootDetailsCustomIdDiv.appendChild(rmcRootDetailsCustomIdName); - rmcRootDetailsCustomIdDiv.appendChild(rmcRootDetailsCustomIdValue); - } - - rmcRootDetailsMethodIdDiv.appendChild(rmcRootDetailsMethodIdName); - rmcRootDetailsMethodIdDiv.appendChild(rmcRootDetailsMethodIdValue); - rmcRootDetailsCallIdDiv.appendChild(rmcRootDetailsCallIdName); - rmcRootDetailsCallIdDiv.appendChild(rmcRootDetailsCallIdValue); - rmcRootDetailsErrorCodeDiv.appendChild(rmcRootDetailsErrorCodeName); - rmcRootDetailsErrorCodeDiv.appendChild(rmcRootDetailsErrorCodeValue); - - rmcRootDetailsRoot.appendChild(rmcRootDetailsProtocolIdDiv); - - if (packet.rmc.protocolId === 0x7F) { - rmcRootDetailsRoot.appendChild(rmcRootDetailsCustomIdDiv); - } - - rmcRootDetailsRoot.appendChild(rmcRootDetailsMethodIdDiv); - rmcRootDetailsRoot.appendChild(rmcRootDetailsCallIdDiv); - - if (packet.rmc.isRequest === true || packet.rmc.isSuccess === true) { - if (emptyObject(packet.rmc.body)) { - const rmcValueElementDiv = document.createElement('div'); - const rmcValueElementName = document.createElement('span'); - const rmcValueElementValue = document.createElement('span'); - rmcValueElementName.classList.add('name'); - rmcValueElementValue.classList.add('value'); - - rmcValueElementName.appendChild(document.createTextNode('Body:')); - - if (packet.rmc.isRequest) { - rmcValueElementValue.appendChild(document.createTextNode('This method takes no parameters')); - } else { - rmcValueElementValue.appendChild(document.createTextNode('This method doesn\'t return anything')); - } - - rmcValueElementDiv.appendChild(rmcValueElementName); - rmcValueElementDiv.appendChild(rmcValueElementValue); - - rmcRootDetailsRoot.appendChild(rmcValueElementDiv); - } else { - const serializedRMCBodyDetails = document.createElement('details'); - const serializedRMCBodySummary = document.createElement('summary'); - - serializedRMCBodySummary.appendChild(document.createTextNode('Body')); - - serializedRMCBodyDetails.appendChild(serializedRMCBodySummary); - serializedRMCBodyDetails.appendChild(serializeRMCBody(packet.rmc.body)); - - const rmcBody = document.createElement('div'); - rmcBody.appendChild(serializedRMCBodyDetails); - - rmcRootDetailsRoot.appendChild(rmcBody); - } - } else if (packet.rmc.isRequest === false && packet.rmc.isSuccess === false) { - // * Error codes only exist on responses - rmcRootDetailsRoot.appendChild(rmcRootDetailsErrorCodeDiv); - } - - rmcRootSummary.appendChild(document.createTextNode('RMC')); - rmcRootDetails.appendChild(rmcRootSummary); - rmcRootDetails.appendChild(rmcRootDetailsRoot); - rmcRoot.appendChild(rmcRootDetails); - rootDiv.appendChild(rmcRoot); - } - - root.appendChild(rootSummary); - root.appendChild(rootDiv); - root.open = true; - - removeAllChildNodes(packetDetailsSection); - - packetDetailsSection.appendChild(root); -} - -/** - * @param {object} rmcData RMC data to serialize - * @returns {Element} HTML element containing serialized RMC data - */ -function serializeRMCBody(rmcData) { - const serializedRMCDataDiv = document.createElement('div'); - - for (const key in rmcData) { - if (Object.hasOwnProperty.call(rmcData, key)) { - const value = rmcData[key]; - const typeName = value.__typeName; - let typeValue = value.__typeValue; - - if (typeName === 'Buffer' || typeName === 'qBuffer' || typeName === 'unknown') { - typeValue = toHexString(typeValue.data); // * typeValue is a NodeJS Buffer object - } - - if (key === '__typeInherits') { - for (const inheritedType of value) { - const inheritedTypeName = inheritedType.__typeName; - const inheritedTypeValue = inheritedType.__typeValue; - - const serializedRMCDataDetails = document.createElement('details'); - const serializedRMCDataSummary = document.createElement('summary'); - - serializedRMCDataSummary.appendChild(document.createTextNode(`Inherits from ${inheritedTypeName}`)); - - serializedRMCDataDetails.appendChild(serializedRMCDataSummary); - serializedRMCDataDetails.appendChild(serializeRMCBody(inheritedTypeValue)); - - serializedRMCDataDiv.appendChild(serializedRMCDataDetails); - } - } else if (key === '__structureVersion') { - const rmcValueElementDiv = document.createElement('div'); - const rmcValueElementName = document.createElement('span'); - const rmcValueElementValue = document.createElement('span'); - rmcValueElementName.classList.add('name'); - rmcValueElementValue.classList.add('value'); - - rmcValueElementName.appendChild(document.createTextNode('Structure Version:')); - rmcValueElementValue.appendChild(document.createTextNode(value)); - - rmcValueElementDiv.appendChild(rmcValueElementName); - rmcValueElementDiv.appendChild(rmcValueElementValue); - - serializedRMCDataDiv.appendChild(rmcValueElementDiv); - } else { - if (isObject(typeValue)) { - const serializedRMCDataDetails = document.createElement('details'); - const serializedRMCDataSummary = document.createElement('summary'); - - serializedRMCDataSummary.appendChild(document.createTextNode(`${key} (${typeName})`)); - - serializedRMCDataDetails.appendChild(serializedRMCDataSummary); - serializedRMCDataDetails.appendChild(serializeRMCBody(typeValue)); - - serializedRMCDataDiv.appendChild(serializedRMCDataDetails); - } else if (isArray(typeValue)) { - const serializedRMCDataDetails = serializeNEXList(key, value); - serializedRMCDataDiv.appendChild(serializedRMCDataDetails); - } else { - const rmcValueElementDiv = document.createElement('div'); - const rmcValueElementName = document.createElement('span'); - const rmcValueElementValue = document.createElement('span'); - rmcValueElementName.classList.add('name'); - rmcValueElementValue.classList.add('value'); - - rmcValueElementName.appendChild(document.createTextNode(`${key} (${typeName}):`)); - rmcValueElementValue.appendChild(document.createTextNode(typeValue)); - - rmcValueElementDiv.appendChild(rmcValueElementName); - rmcValueElementDiv.appendChild(rmcValueElementValue); - - serializedRMCDataDiv.appendChild(rmcValueElementDiv); - } - } - } - } - - return serializedRMCDataDiv; -} - -/** - * @param {string} key Name of NEX list - * @param {object} value NEX list to serialize - * @returns {Element} HTML element containing serialized NEX list - */ -function serializeNEXList(key, value) { - const typeName = value.__typeName; - let typeValue = value.__typeValue; - - let listType = typeName.match(LIST_TYPE_REGEX)?.[1] || typeName; // * Support Map lists - let isMap = false; - let isList = false; - let mapKeyTypeName; - let mapValueTypeName; - - if (listType.match(MAP_TYPE_REGEX)) { - isMap = true; - [mapKeyTypeName, mapValueTypeName] = listType.match(MAP_TYPE_REGEX)[1].split(', '); - } - - if (listType.match(LIST_TYPE_REGEX)) { - isList = true; - } - - const serializedRMCDataDetails = document.createElement('details'); - const serializedRMCDataSummary = document.createElement('summary'); - - serializedRMCDataSummary.appendChild(document.createTextNode(`${key} (${typeName} length ${typeValue.length})`)); - serializedRMCDataDetails.appendChild(serializedRMCDataSummary); - - for (let i = 0; i < typeValue.length; i++) { - let value = typeValue[i]; - - if (isNEXPrimative(listType)) { - if (listType === 'Buffer' || listType === 'qBuffer' || listType === 'unknown') { - value = toHexString(value.data); // * value is a NodeJS Buffer object - } - - const rmcValueElementDiv = document.createElement('div'); - const rmcValueElementName = document.createElement('span'); - const rmcValueElementValue = document.createElement('span'); - rmcValueElementName.classList.add('name'); - rmcValueElementValue.classList.add('value'); - - rmcValueElementName.appendChild(document.createTextNode(`${key}[${i}] (${listType}):`)); - rmcValueElementValue.appendChild(document.createTextNode(value)); - - rmcValueElementDiv.appendChild(rmcValueElementName); - rmcValueElementDiv.appendChild(rmcValueElementValue); - - serializedRMCDataDetails.appendChild(rmcValueElementDiv); - } else if (isList) { - const listValue = {}; - listValue.__typeName = listType; - listValue.__typeValue = value; - - const rmcListElementDiv = document.createElement('div'); - rmcListElementDiv.appendChild(serializeNEXList(`${key}[${i}]`, listValue)); - serializedRMCDataDetails.appendChild(rmcListElementDiv); - } else { - if (isMap) { - value.key.__typeName = mapKeyTypeName; - value.value.__typeName = mapValueTypeName; - } - - const rmcValueElementDiv = document.createElement('div'); - const rmcValueElementSummary = document.createElement('summary'); - const rmcValueElementDetails = document.createElement('details'); - - rmcValueElementSummary.appendChild(document.createTextNode(`${key}[${i}] (${listType}):`)); - rmcValueElementDetails.appendChild(serializeRMCBody(value)); - - rmcValueElementDetails.appendChild(rmcValueElementSummary); - - rmcValueElementDiv.appendChild(rmcValueElementDetails); - - serializedRMCDataDetails.appendChild(rmcValueElementDiv); - } - } - - return serializedRMCDataDetails; -} - -document.addEventListener('click', event => { - event.stopPropagation(); - - if (event.target.tagName.toLowerCase() === 'td') { - setSelectedPacketRow(event.target.parentElement); - } - - if (event.target.tagName.toLowerCase() === 'tr') { - setSelectedPacketRow(event.target); - } -}); diff --git a/app/assets/js/util.js b/app/assets/js/util.js deleted file mode 100644 index 5300c65..0000000 --- a/app/assets/js/util.js +++ /dev/null @@ -1,78 +0,0 @@ - -/** - * @param {Element} parent Element whos children will be removed - */ -export function removeAllChildNodes(parent) { - while (parent.firstChild) { - parent.removeChild(parent.firstChild); - } -} - -/** - * @param {Function} fn Callback function ran when frontend is ready for data - */ -export function ready(fn) { - if (document.readyState !== 'loading') { - fn(); - } else { - document.addEventListener('DOMContentLoaded', fn); - } -} - -/** - * @param {*} item Value to check if is Object - * @returns {boolean} Is object? - */ -export function isObject(item) { - return (typeof item === 'object' && !Array.isArray(item) && item !== null); -} - -/** - * @param {*} item Value to check if is Array - * @returns {boolean} Is array? - */ -export function isArray(item) { - return (typeof item === 'object' && Array.isArray(item) && item !== null); -} - -/** - * @param {Array.} byteArray Array of bytes to convert to HEX string - * @returns {string} Formated HEX string - */ -export function toHexString(byteArray) { - return Array.from(byteArray, function (byte) { - return ('0' + (byte & 0xFF).toString(16)).slice(-2); - }).join(':'); -} - -/** - * @param {string} typeName Name of NEX type - * @returns {boolean} Is NEX primative? - */ -export function isNEXPrimative(typeName) { - return [ - 'uint8', - 'sint8', - 'uint16', - 'sint16', - 'uint32', - 'sint32', - 'uint64', - 'sint64', - 'Float', - 'Double', - 'boolean', - 'String', - 'PID', // * PID is the same as a uint32 - 'Buffer', - 'qBuffer', - ].includes(typeName); -} - -/** - * @param {object} object Object to check if is empty - * @returns {boolean} Is empty? - */ -export function emptyObject(object) { - return Object.keys(object).length === 0; -} diff --git a/app/index.html b/app/index.html deleted file mode 100644 index c2c523e..0000000 --- a/app/index.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - -
-
- - - - - - - - - - - -
TimeSourceDestinationVersionInfo
-
- -
- -
-
- - - - - - \ No newline at end of file diff --git a/app/index.js b/app/index.js deleted file mode 100644 index 83309de..0000000 --- a/app/index.js +++ /dev/null @@ -1,152 +0,0 @@ -const fs = require('node:fs'); -const path = require('node:path'); -const { app, BrowserWindow, ipcMain, Menu, dialog } = require('electron'); -const NEXParser = require(__dirname + '/../'); - -BigInt.prototype.toJSON = function () { return this.toString(); }; - -app.setName('NEX Viewer'); - -const appUserDataPath = app.getPath('userData'); -const settingsRootPath = path.join(appUserDataPath, 'settings.json'); - -const defaultSettings = { - recent_files: [] -}; - -let settings = defaultSettings; -let rawRMC = false; - -if (!fs.existsSync(settingsRootPath)) { - fs.writeFileSync(settingsRootPath, JSON.stringify(defaultSettings)); -} else { - settings = require(settingsRootPath); -} - -for (const recentFile of settings.recent_files) { - // TODO - Actually store these - app.addRecentDocument(recentFile); -} - -const menuTemplate = [ - { - label: 'File', - id: 'file', - submenu: [ - { - label: 'Open File', - async click(menuItem, browserWindow) { - const result = await dialog.showOpenDialog({ - properties: ['openFile'], - filters: [ - { name: 'Packet Capture', extensions: ['pcapng', 'pcap'] } - ] - }); - - if (result.canceled) { - return; - } - - browserWindow.webContents.send('clear-sections'); - - const filePath = result.filePaths[0]; - - browserWindow.setTitle(`NEX Viewer - ${filePath}`); - - const parser = new NEXParser(); - parser.setRawRMCMode(rawRMC); - - parser.on('packet', packet => { - const serialized = JSON.stringify(packet); - browserWindow.webContents.send('packet', serialized); - }); - - parser.on('connections', connections => { - const serialized = JSON.stringify(connections); - browserWindow.webContents.send('connections', serialized); - }); - - parser.parse(filePath); - } - }, - { - label: 'Open Recent', - role: 'recentdocuments', - submenu: [ - { - label: 'Clear Recent', - role: 'clearrecentdocuments' - } - ] - } - ] - }, - { - label: 'Options', - id: 'options', - submenu: [ - { - label: 'Hide PING packets', - type: 'checkbox', - checked: false, - click(menuItem, browserWindow) { - if (menuItem.checked) { - browserWindow.webContents.send('hide-ping-packets'); - } else { - browserWindow.webContents.send('show-ping-packets'); - } - } - }, - { - label: 'Raw RMC Mode', - type: 'checkbox', - checked: rawRMC, - click(menuItem) { - rawRMC = menuItem.checked; - } - } - ] - } -]; - -const menu = Menu.buildFromTemplate(menuTemplate); - -/** - * Creates the main view window - */ -function createWindow() { - const window = new BrowserWindow({ - width: 800, - height: 600, - webPreferences: { // TODO - Use Electron's contextBridge instead - nodeIntegration: true, - contextIsolation: false - } - }); - - window.webContents.openDevTools(); - - ipcMain.on('renderer-ready', () => { - Menu.setApplicationMenu(menu); - }); - - window.maximize(); - window.loadFile('index.html'); -} - -app.whenReady().then(() => { - Menu.setApplicationMenu(Menu.buildFromTemplate([])); // * Clear menu before frontend loads - createWindow(); - - app.on('activate', () => { - if (BrowserWindow.getAllWindows().length === 0) { - createWindow(); - } - }); -}); - -app.on('window-all-closed', () => { - if (process.platform !== 'darwin') { - app.quit(); - } -}); \ No newline at end of file diff --git a/build_games_list.js b/build_games_list.js deleted file mode 100644 index c7df8a1..0000000 --- a/build_games_list.js +++ /dev/null @@ -1,209 +0,0 @@ -const fs = require('fs'); - -// Data from https://kinnay.github.io/view.html?page=wiiu -const nex = fs.readFileSync('nex/nex.txt').toString(); -const nexRanking = fs.readFileSync('nex/nex_ranking.txt').toString(); -const nexDataStore = fs.readFileSync('nex/nex_datastore.txt').toString(); -const nexMatchMaking = fs.readFileSync('nex/nex_match_making.txt').toString(); -const nexMessaging = fs.readFileSync('nex/nex_messaging.txt').toString(); -const nexUtility = fs.readFileSync('nex/nex_utility.txt').toString(); -const access = fs.readFileSync('./access.txt').toString(); -const titleids = fs.readFileSync('./titleids.txt').toString(); - -const nexLines = nex.split('\n'); -const nexRankingLines = nexRanking.split('\n'); -const nexDataStoreLines = nexDataStore.split('\n'); -const nexMatchMakingLines = nexMatchMaking.split('\n'); -const nexMessagingLines = nexMessaging.split('\n'); -const nexUtilityLines = nexUtility.split('\n'); -const accessLines = access.split('\n'); -const titleIdLines = titleids.split('\n'); - -// * Start the list with the Friends server -// * This is because the Smash 4 access key -// * also works for the friends server -const titles = [ - { - name: 'Friends', - access_key: 'ridfebb9', - nex_version: '1.0.0', - title_ids: [ - '0004013000003202', - '000500301001500A', - '000500301001510A', - '000500301001520A' - ] - } -]; - -// Fill in title NEX details -for (const line of nexLines) { - // Discard empty lines - if (!line) continue; - - const [name, nexVersion] = line.split('|'); - const [major, minor, patch] = nexVersion.trim().split('.'); - - titles.push({ - name: name.trim(), - access_key: '', - nex_version: `${major}.${minor}.${patch}` - }); -} - -// Fill in title NEX additional Ranking versions -for (const line of nexRankingLines) { - // Discard empty lines - if (!line) continue; - - const [name, nexVersion] = line.split('|'); - const [major, minor, patch] = nexVersion.trim().split('.'); - - const game = titles.find(game => game.name === name.trim()); - - if (game) { - game.nex_ranking_version = `${major}.${minor}.${patch}`; - } else { - titles.push({ - name: name.trim(), - access_key: '', - nex_version: '0.0.0', - nex_ranking_version: `${major}.${minor}.${patch}` - }); - } -} - -// Fill in title NEX additional DataStore versions -for (const line of nexDataStoreLines) { - // Discard empty lines - if (!line) continue; - - const [name, nexVersion] = line.split('|'); - const [major, minor, patch] = nexVersion.trim().split('.'); - - const game = titles.find(game => game.name === name.trim()); - - if (game) { - game.nex_datastore_version = `${major}.${minor}.${patch}`; - } else { - titles.push({ - name: name.trim(), - access_key: '', - nex_version: '0.0.0', - nex_datastore_version: `${major}.${minor}.${patch}` - }); - } -} - -// Fill in title NEX additional Matchmaking versions -for (const line of nexMatchMakingLines) { - // Discard empty lines - if (!line) continue; - - const [name, nexVersion] = line.split('|'); - const [major, minor, patch] = nexVersion.trim().split('.'); - - const game = titles.find(game => game.name === name.trim()); - - if (game) { - game.nex_match_making_version = `${major}.${minor}.${patch}`; - } else { - titles.push({ - name: name.trim(), - access_key: '', - nex_version: '0.0.0', - nex_match_making_version: `${major}.${minor}.${patch}` - }); - } -} - -// Fill in title NEX additional Messaging versions -for (const line of nexMessagingLines) { - // Discard empty lines - if (!line) continue; - - const [name, nexVersion] = line.split('|'); - const [major, minor, patch] = nexVersion.trim().split('.'); - - const game = titles.find(game => game.name === name.trim()); - - if (game) { - game.nex_messaging_version = `${major}.${minor}.${patch}`; - } else { - titles.push({ - name: name.trim(), - access_key: '', - nex_version: '0.0.0', - nex_messaging_version: `${major}.${minor}.${patch}` - }); - } -} - -// Fill in title NEX additional Utility versions -for (const line of nexUtilityLines) { - // Discard empty lines - if (!line) continue; - - const [name, nexVersion] = line.split('|'); - const [major, minor, patch] = nexVersion.trim().split('.'); - - const game = titles.find(game => game.name === name.trim()); - - if (game) { - game.nex_utility_version = `${major}.${minor}.${patch}`; - } else { - titles.push({ - name: name.trim(), - access_key: '', - nex_version: '0.0.0', - nex_utility_version: `${major}.${minor}.${patch}` - }); - } -} - -// Match the titles access key -for (const line of accessLines) { - // Discard empty lines - if (!line) continue; - - const [name, accessKey] = line.split('|'); - - const game = titles.find(game => game.name === name.trim()); - - if (game) { - game.access_key = accessKey.trim(); - } else { - titles.push({ - name: name.trim(), - access_key: accessKey.trim(), - nex_version: '0.0.0' - }); - } -} - -// Match the title ids -for (const line of titleIdLines) { - // Discard empty lines - if (!line) continue; - - const [name, titleIdData] = line.split('|'); - - const game = titles.find(game => game.name === name.trim()); - - const titleIdList = titleIdData.trim().split(', '); - - if (game) { - game.title_ids = titleIdList; - } else { - titles.push({ - name: name.trim(), - access_key: '', - title_ids: titleIdList, - nex_version: '0.0.0' - }); - } -} - -fs.writeFileSync('./src/titles.json', JSON.stringify(titles, null, 4)); - -console.log('Title data built'); diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..8e4260d --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,67 @@ +const eslint = require('@eslint/js'); +const tseslint = require('typescript-eslint'); + +module.exports = [ + eslint.configs.recommended, + ...tseslint.configs.recommended, + { + languageOptions: { + globals: { + node: true, + commonjs: true, + es6: true, + BigInt: true + }, + parser: tseslint.parser, + }, + plugins: { + '@typescript-eslint': tseslint.plugin + }, + rules: { + 'require-atomic-updates': 'warn', + 'no-case-declarations': 'off', + 'no-empty': 'off', + 'no-console': 'off', + 'linebreak-style': 'off', + 'no-global-assign': 'off', + 'prefer-const': 'error', + 'no-var': 'error', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + 'argsIgnorePattern': '^_' + } + ], + 'no-extra-semi': 'off', + '@typescript-eslint/no-extra-semi': 'error', + '@typescript-eslint/no-empty-interface': 'warn', + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/explicit-function-return-type': 'error', + '@typescript-eslint/no-explicit-any': 'warn', + 'one-var': [ + 'error', + 'never' + ], + indent: [ + 'error', + 'tab', + { + SwitchCase: 1 + } + ], + quotes: [ + 'error', + 'single' + ], + semi: [ + 'error', + 'always' + ] + }, + ignores: [ + 'dist', + '*.js' + ] + } +]; \ No newline at end of file diff --git a/nex/nex.txt b/nex/nex.txt deleted file mode 100644 index c89681a..0000000 --- a/nex/nex.txt +++ /dev/null @@ -1,69 +0,0 @@ -Angry Birds Star Wars 3DS | 3.2.1 -Angry Birds Trilogy 3DS | 2.7.2 -Animal Crossing: New Leaf | 3.10.1 -Animal Crossing Plaza | 3.5.1 -Axiom Verge | 3.10.0 -Badge Arcade | 3.7.3 -BIOHAZARD REVELATIONS UE | 3.2.1 -Devil's Third | 3.6.1 -Disney INFINITY | 3.5.2 -Disney Infinity [2.0] | 3.5.2 -DISNEY INFINITY 3.0 | 3.9.1 -DKC: Tropical Freeze | 3.4.0 -DuckTales: Remastered | 3.3.0 -FAST Racing NEO | 3.9.1 -FotNS: Ken's Rage 2 | 3.0.1 -Game Party | 3.0.1 -Hyrule Warriors | 3.8.0 -Injustice: Gods Among Us | 3.2.1 -IRONFALL Invasion | 3.7.1 -Legend of Kay | 3.8.3 -LOST REAVERS | 3.10.0 -Mario & Sonic Rio 2016 3DS | 3.9.1 -Mario & Sonic Rio 2016 Wii U | 3.9.1 -MARIO & SONIC SOCHI 2014 | 3.4.0 -MARIO KART 7 | 2.4.3 -MARIO KART 8 | 3.5.4 -Mario Tennis Open | 2.6.1 -Mario Tennis: Ultra Smash | 3.9.1 -Mario vs. DK: Tipping Stars | 3.7.1 -Metroid Prime: FF | 3.9.1 -MH3G HD Ver. | 3.0.5 -MH3U | 3.0.5 -Mighty No. 9 | 3.9.1 -Minecraft: Wii U Edition | 3.10.0 -Nano Assault Neo | 3.0.1 -NINJA GAIDEN 3: Razor's Edge | 3.0.1 -Nova-111 | 3.8.3 -OlliOlli | 3.6.1 -PIKMIN 3 | 3.3.0 -Pokémon Bank | 3.4.12 -Pokémon Rumble World | 3.8.2 -POKKÉN TOURNAMENT | 3.10.0 -Puddle | 3.0.1 -PUYOPUYOTETRIS | 3.5.2 -RESIDENT EVIL REVELATIONS | 3.2.1 -RTK 12 | 3.4.0 -Runner2 | 3.0.1 -SI2 | 3.6.1 -SONIC LOST WORLD | 3.3.0 -Sonic Transformed | 3.0.1 -Splatoon | 3.8.3 -Star Fox Guard | 3.8.2 -Star Fox Guard (Demo) | 3.8.2 -Star Wars Pinball | 3.0.1 -Steel Diver: Sub Wars | 3.7.0 -Super Mario Maker | 3.8.12 -Super Smash Bros. | 3.6.27 -Team Kirby Clash Deluxe | 3.10.1 -TEKKEN TAG 2 Wii U EDITION | 3.0.1 -Terraria | 3.8.3 -Trine 2 | 3.0.1 -WARRIORS OROCHI 3 Hyper | 3.0.1 -Wii Karaoke U | 3.4.0 -Wii Party U | 3.3.0 -Wii Sports Club | 3.4.7 -Xenoblade Chronicles X | 3.5.5 -Yo-kai Watch 2 | 3.6.1 -Zen Pinball 2 | 3.0.1 -役満 鳳凰 | 3.6.14 diff --git a/nex/nex_datastore.txt b/nex/nex_datastore.txt deleted file mode 100644 index c89681a..0000000 --- a/nex/nex_datastore.txt +++ /dev/null @@ -1,69 +0,0 @@ -Angry Birds Star Wars 3DS | 3.2.1 -Angry Birds Trilogy 3DS | 2.7.2 -Animal Crossing: New Leaf | 3.10.1 -Animal Crossing Plaza | 3.5.1 -Axiom Verge | 3.10.0 -Badge Arcade | 3.7.3 -BIOHAZARD REVELATIONS UE | 3.2.1 -Devil's Third | 3.6.1 -Disney INFINITY | 3.5.2 -Disney Infinity [2.0] | 3.5.2 -DISNEY INFINITY 3.0 | 3.9.1 -DKC: Tropical Freeze | 3.4.0 -DuckTales: Remastered | 3.3.0 -FAST Racing NEO | 3.9.1 -FotNS: Ken's Rage 2 | 3.0.1 -Game Party | 3.0.1 -Hyrule Warriors | 3.8.0 -Injustice: Gods Among Us | 3.2.1 -IRONFALL Invasion | 3.7.1 -Legend of Kay | 3.8.3 -LOST REAVERS | 3.10.0 -Mario & Sonic Rio 2016 3DS | 3.9.1 -Mario & Sonic Rio 2016 Wii U | 3.9.1 -MARIO & SONIC SOCHI 2014 | 3.4.0 -MARIO KART 7 | 2.4.3 -MARIO KART 8 | 3.5.4 -Mario Tennis Open | 2.6.1 -Mario Tennis: Ultra Smash | 3.9.1 -Mario vs. DK: Tipping Stars | 3.7.1 -Metroid Prime: FF | 3.9.1 -MH3G HD Ver. | 3.0.5 -MH3U | 3.0.5 -Mighty No. 9 | 3.9.1 -Minecraft: Wii U Edition | 3.10.0 -Nano Assault Neo | 3.0.1 -NINJA GAIDEN 3: Razor's Edge | 3.0.1 -Nova-111 | 3.8.3 -OlliOlli | 3.6.1 -PIKMIN 3 | 3.3.0 -Pokémon Bank | 3.4.12 -Pokémon Rumble World | 3.8.2 -POKKÉN TOURNAMENT | 3.10.0 -Puddle | 3.0.1 -PUYOPUYOTETRIS | 3.5.2 -RESIDENT EVIL REVELATIONS | 3.2.1 -RTK 12 | 3.4.0 -Runner2 | 3.0.1 -SI2 | 3.6.1 -SONIC LOST WORLD | 3.3.0 -Sonic Transformed | 3.0.1 -Splatoon | 3.8.3 -Star Fox Guard | 3.8.2 -Star Fox Guard (Demo) | 3.8.2 -Star Wars Pinball | 3.0.1 -Steel Diver: Sub Wars | 3.7.0 -Super Mario Maker | 3.8.12 -Super Smash Bros. | 3.6.27 -Team Kirby Clash Deluxe | 3.10.1 -TEKKEN TAG 2 Wii U EDITION | 3.0.1 -Terraria | 3.8.3 -Trine 2 | 3.0.1 -WARRIORS OROCHI 3 Hyper | 3.0.1 -Wii Karaoke U | 3.4.0 -Wii Party U | 3.3.0 -Wii Sports Club | 3.4.7 -Xenoblade Chronicles X | 3.5.5 -Yo-kai Watch 2 | 3.6.1 -Zen Pinball 2 | 3.0.1 -役満 鳳凰 | 3.6.14 diff --git a/nex/nex_match_making.txt b/nex/nex_match_making.txt deleted file mode 100644 index c89681a..0000000 --- a/nex/nex_match_making.txt +++ /dev/null @@ -1,69 +0,0 @@ -Angry Birds Star Wars 3DS | 3.2.1 -Angry Birds Trilogy 3DS | 2.7.2 -Animal Crossing: New Leaf | 3.10.1 -Animal Crossing Plaza | 3.5.1 -Axiom Verge | 3.10.0 -Badge Arcade | 3.7.3 -BIOHAZARD REVELATIONS UE | 3.2.1 -Devil's Third | 3.6.1 -Disney INFINITY | 3.5.2 -Disney Infinity [2.0] | 3.5.2 -DISNEY INFINITY 3.0 | 3.9.1 -DKC: Tropical Freeze | 3.4.0 -DuckTales: Remastered | 3.3.0 -FAST Racing NEO | 3.9.1 -FotNS: Ken's Rage 2 | 3.0.1 -Game Party | 3.0.1 -Hyrule Warriors | 3.8.0 -Injustice: Gods Among Us | 3.2.1 -IRONFALL Invasion | 3.7.1 -Legend of Kay | 3.8.3 -LOST REAVERS | 3.10.0 -Mario & Sonic Rio 2016 3DS | 3.9.1 -Mario & Sonic Rio 2016 Wii U | 3.9.1 -MARIO & SONIC SOCHI 2014 | 3.4.0 -MARIO KART 7 | 2.4.3 -MARIO KART 8 | 3.5.4 -Mario Tennis Open | 2.6.1 -Mario Tennis: Ultra Smash | 3.9.1 -Mario vs. DK: Tipping Stars | 3.7.1 -Metroid Prime: FF | 3.9.1 -MH3G HD Ver. | 3.0.5 -MH3U | 3.0.5 -Mighty No. 9 | 3.9.1 -Minecraft: Wii U Edition | 3.10.0 -Nano Assault Neo | 3.0.1 -NINJA GAIDEN 3: Razor's Edge | 3.0.1 -Nova-111 | 3.8.3 -OlliOlli | 3.6.1 -PIKMIN 3 | 3.3.0 -Pokémon Bank | 3.4.12 -Pokémon Rumble World | 3.8.2 -POKKÉN TOURNAMENT | 3.10.0 -Puddle | 3.0.1 -PUYOPUYOTETRIS | 3.5.2 -RESIDENT EVIL REVELATIONS | 3.2.1 -RTK 12 | 3.4.0 -Runner2 | 3.0.1 -SI2 | 3.6.1 -SONIC LOST WORLD | 3.3.0 -Sonic Transformed | 3.0.1 -Splatoon | 3.8.3 -Star Fox Guard | 3.8.2 -Star Fox Guard (Demo) | 3.8.2 -Star Wars Pinball | 3.0.1 -Steel Diver: Sub Wars | 3.7.0 -Super Mario Maker | 3.8.12 -Super Smash Bros. | 3.6.27 -Team Kirby Clash Deluxe | 3.10.1 -TEKKEN TAG 2 Wii U EDITION | 3.0.1 -Terraria | 3.8.3 -Trine 2 | 3.0.1 -WARRIORS OROCHI 3 Hyper | 3.0.1 -Wii Karaoke U | 3.4.0 -Wii Party U | 3.3.0 -Wii Sports Club | 3.4.7 -Xenoblade Chronicles X | 3.5.5 -Yo-kai Watch 2 | 3.6.1 -Zen Pinball 2 | 3.0.1 -役満 鳳凰 | 3.6.14 diff --git a/nex/nex_messaging.txt b/nex/nex_messaging.txt deleted file mode 100644 index c89681a..0000000 --- a/nex/nex_messaging.txt +++ /dev/null @@ -1,69 +0,0 @@ -Angry Birds Star Wars 3DS | 3.2.1 -Angry Birds Trilogy 3DS | 2.7.2 -Animal Crossing: New Leaf | 3.10.1 -Animal Crossing Plaza | 3.5.1 -Axiom Verge | 3.10.0 -Badge Arcade | 3.7.3 -BIOHAZARD REVELATIONS UE | 3.2.1 -Devil's Third | 3.6.1 -Disney INFINITY | 3.5.2 -Disney Infinity [2.0] | 3.5.2 -DISNEY INFINITY 3.0 | 3.9.1 -DKC: Tropical Freeze | 3.4.0 -DuckTales: Remastered | 3.3.0 -FAST Racing NEO | 3.9.1 -FotNS: Ken's Rage 2 | 3.0.1 -Game Party | 3.0.1 -Hyrule Warriors | 3.8.0 -Injustice: Gods Among Us | 3.2.1 -IRONFALL Invasion | 3.7.1 -Legend of Kay | 3.8.3 -LOST REAVERS | 3.10.0 -Mario & Sonic Rio 2016 3DS | 3.9.1 -Mario & Sonic Rio 2016 Wii U | 3.9.1 -MARIO & SONIC SOCHI 2014 | 3.4.0 -MARIO KART 7 | 2.4.3 -MARIO KART 8 | 3.5.4 -Mario Tennis Open | 2.6.1 -Mario Tennis: Ultra Smash | 3.9.1 -Mario vs. DK: Tipping Stars | 3.7.1 -Metroid Prime: FF | 3.9.1 -MH3G HD Ver. | 3.0.5 -MH3U | 3.0.5 -Mighty No. 9 | 3.9.1 -Minecraft: Wii U Edition | 3.10.0 -Nano Assault Neo | 3.0.1 -NINJA GAIDEN 3: Razor's Edge | 3.0.1 -Nova-111 | 3.8.3 -OlliOlli | 3.6.1 -PIKMIN 3 | 3.3.0 -Pokémon Bank | 3.4.12 -Pokémon Rumble World | 3.8.2 -POKKÉN TOURNAMENT | 3.10.0 -Puddle | 3.0.1 -PUYOPUYOTETRIS | 3.5.2 -RESIDENT EVIL REVELATIONS | 3.2.1 -RTK 12 | 3.4.0 -Runner2 | 3.0.1 -SI2 | 3.6.1 -SONIC LOST WORLD | 3.3.0 -Sonic Transformed | 3.0.1 -Splatoon | 3.8.3 -Star Fox Guard | 3.8.2 -Star Fox Guard (Demo) | 3.8.2 -Star Wars Pinball | 3.0.1 -Steel Diver: Sub Wars | 3.7.0 -Super Mario Maker | 3.8.12 -Super Smash Bros. | 3.6.27 -Team Kirby Clash Deluxe | 3.10.1 -TEKKEN TAG 2 Wii U EDITION | 3.0.1 -Terraria | 3.8.3 -Trine 2 | 3.0.1 -WARRIORS OROCHI 3 Hyper | 3.0.1 -Wii Karaoke U | 3.4.0 -Wii Party U | 3.3.0 -Wii Sports Club | 3.4.7 -Xenoblade Chronicles X | 3.5.5 -Yo-kai Watch 2 | 3.6.1 -Zen Pinball 2 | 3.0.1 -役満 鳳凰 | 3.6.14 diff --git a/nex/nex_ranking.txt b/nex/nex_ranking.txt deleted file mode 100644 index c89681a..0000000 --- a/nex/nex_ranking.txt +++ /dev/null @@ -1,69 +0,0 @@ -Angry Birds Star Wars 3DS | 3.2.1 -Angry Birds Trilogy 3DS | 2.7.2 -Animal Crossing: New Leaf | 3.10.1 -Animal Crossing Plaza | 3.5.1 -Axiom Verge | 3.10.0 -Badge Arcade | 3.7.3 -BIOHAZARD REVELATIONS UE | 3.2.1 -Devil's Third | 3.6.1 -Disney INFINITY | 3.5.2 -Disney Infinity [2.0] | 3.5.2 -DISNEY INFINITY 3.0 | 3.9.1 -DKC: Tropical Freeze | 3.4.0 -DuckTales: Remastered | 3.3.0 -FAST Racing NEO | 3.9.1 -FotNS: Ken's Rage 2 | 3.0.1 -Game Party | 3.0.1 -Hyrule Warriors | 3.8.0 -Injustice: Gods Among Us | 3.2.1 -IRONFALL Invasion | 3.7.1 -Legend of Kay | 3.8.3 -LOST REAVERS | 3.10.0 -Mario & Sonic Rio 2016 3DS | 3.9.1 -Mario & Sonic Rio 2016 Wii U | 3.9.1 -MARIO & SONIC SOCHI 2014 | 3.4.0 -MARIO KART 7 | 2.4.3 -MARIO KART 8 | 3.5.4 -Mario Tennis Open | 2.6.1 -Mario Tennis: Ultra Smash | 3.9.1 -Mario vs. DK: Tipping Stars | 3.7.1 -Metroid Prime: FF | 3.9.1 -MH3G HD Ver. | 3.0.5 -MH3U | 3.0.5 -Mighty No. 9 | 3.9.1 -Minecraft: Wii U Edition | 3.10.0 -Nano Assault Neo | 3.0.1 -NINJA GAIDEN 3: Razor's Edge | 3.0.1 -Nova-111 | 3.8.3 -OlliOlli | 3.6.1 -PIKMIN 3 | 3.3.0 -Pokémon Bank | 3.4.12 -Pokémon Rumble World | 3.8.2 -POKKÉN TOURNAMENT | 3.10.0 -Puddle | 3.0.1 -PUYOPUYOTETRIS | 3.5.2 -RESIDENT EVIL REVELATIONS | 3.2.1 -RTK 12 | 3.4.0 -Runner2 | 3.0.1 -SI2 | 3.6.1 -SONIC LOST WORLD | 3.3.0 -Sonic Transformed | 3.0.1 -Splatoon | 3.8.3 -Star Fox Guard | 3.8.2 -Star Fox Guard (Demo) | 3.8.2 -Star Wars Pinball | 3.0.1 -Steel Diver: Sub Wars | 3.7.0 -Super Mario Maker | 3.8.12 -Super Smash Bros. | 3.6.27 -Team Kirby Clash Deluxe | 3.10.1 -TEKKEN TAG 2 Wii U EDITION | 3.0.1 -Terraria | 3.8.3 -Trine 2 | 3.0.1 -WARRIORS OROCHI 3 Hyper | 3.0.1 -Wii Karaoke U | 3.4.0 -Wii Party U | 3.3.0 -Wii Sports Club | 3.4.7 -Xenoblade Chronicles X | 3.5.5 -Yo-kai Watch 2 | 3.6.1 -Zen Pinball 2 | 3.0.1 -役満 鳳凰 | 3.6.14 diff --git a/nex/nex_utility.txt b/nex/nex_utility.txt deleted file mode 100644 index c89681a..0000000 --- a/nex/nex_utility.txt +++ /dev/null @@ -1,69 +0,0 @@ -Angry Birds Star Wars 3DS | 3.2.1 -Angry Birds Trilogy 3DS | 2.7.2 -Animal Crossing: New Leaf | 3.10.1 -Animal Crossing Plaza | 3.5.1 -Axiom Verge | 3.10.0 -Badge Arcade | 3.7.3 -BIOHAZARD REVELATIONS UE | 3.2.1 -Devil's Third | 3.6.1 -Disney INFINITY | 3.5.2 -Disney Infinity [2.0] | 3.5.2 -DISNEY INFINITY 3.0 | 3.9.1 -DKC: Tropical Freeze | 3.4.0 -DuckTales: Remastered | 3.3.0 -FAST Racing NEO | 3.9.1 -FotNS: Ken's Rage 2 | 3.0.1 -Game Party | 3.0.1 -Hyrule Warriors | 3.8.0 -Injustice: Gods Among Us | 3.2.1 -IRONFALL Invasion | 3.7.1 -Legend of Kay | 3.8.3 -LOST REAVERS | 3.10.0 -Mario & Sonic Rio 2016 3DS | 3.9.1 -Mario & Sonic Rio 2016 Wii U | 3.9.1 -MARIO & SONIC SOCHI 2014 | 3.4.0 -MARIO KART 7 | 2.4.3 -MARIO KART 8 | 3.5.4 -Mario Tennis Open | 2.6.1 -Mario Tennis: Ultra Smash | 3.9.1 -Mario vs. DK: Tipping Stars | 3.7.1 -Metroid Prime: FF | 3.9.1 -MH3G HD Ver. | 3.0.5 -MH3U | 3.0.5 -Mighty No. 9 | 3.9.1 -Minecraft: Wii U Edition | 3.10.0 -Nano Assault Neo | 3.0.1 -NINJA GAIDEN 3: Razor's Edge | 3.0.1 -Nova-111 | 3.8.3 -OlliOlli | 3.6.1 -PIKMIN 3 | 3.3.0 -Pokémon Bank | 3.4.12 -Pokémon Rumble World | 3.8.2 -POKKÉN TOURNAMENT | 3.10.0 -Puddle | 3.0.1 -PUYOPUYOTETRIS | 3.5.2 -RESIDENT EVIL REVELATIONS | 3.2.1 -RTK 12 | 3.4.0 -Runner2 | 3.0.1 -SI2 | 3.6.1 -SONIC LOST WORLD | 3.3.0 -Sonic Transformed | 3.0.1 -Splatoon | 3.8.3 -Star Fox Guard | 3.8.2 -Star Fox Guard (Demo) | 3.8.2 -Star Wars Pinball | 3.0.1 -Steel Diver: Sub Wars | 3.7.0 -Super Mario Maker | 3.8.12 -Super Smash Bros. | 3.6.27 -Team Kirby Clash Deluxe | 3.10.1 -TEKKEN TAG 2 Wii U EDITION | 3.0.1 -Terraria | 3.8.3 -Trine 2 | 3.0.1 -WARRIORS OROCHI 3 Hyper | 3.0.1 -Wii Karaoke U | 3.4.0 -Wii Party U | 3.3.0 -Wii Sports Club | 3.4.7 -Xenoblade Chronicles X | 3.5.5 -Yo-kai Watch 2 | 3.6.1 -Zen Pinball 2 | 3.0.1 -役満 鳳凰 | 3.6.14 diff --git a/package-lock.json b/package-lock.json index 5f9af67..24dfa40 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,56 +1,37 @@ { - "name": "nex-viewer", + "name": "nex-viewer-rewrite", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "nex-viewer", + "name": "nex-viewer-rewrite", "version": "1.0.0", - "license": "ISC", + "license": "AGPL-3.0", "dependencies": { - "private-ip": "^2.3.4", - "semver": "^7.5.4" + "fs-extra": "^11.2.0", + "semver": "^7.6.0" }, "devDependencies": { - "electron": "^27.0.3", - "electron-builder": "^24.6.4", - "eslint": "^8.24.0", - "eslint-plugin-jsdoc": "^39.3.6" + "@eslint/js": "^9.1.1", + "@types/fs-extra": "^11.0.4", + "@types/semver": "^7.5.8", + "electron": "^30.0.1", + "eslint": "^8.57.0", + "rimraf": "^5.0.5", + "tsc-alias": "^1.8.8", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.4.5", + "typescript-eslint": "^7.7.1" } }, - "node_modules/@develar/schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, - "dependencies": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/@electron/asar": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.7.tgz", - "integrity": "sha512-8FaSCAIiZGYFWyjeevPQt+0e9xCK9YmJ2Rjg5SXgdsXon6cRnU0Yxnbe6CvJbQn26baifur2Y2G5EBayRIsjyg==", - "dev": true, - "dependencies": { - "commander": "^5.0.0", - "glob": "^7.1.6", - "minimatch": "^3.0.4" - }, - "bin": { - "asar": "bin/asar.js" - }, "engines": { - "node": ">=10.12.0" + "node": ">=0.10.0" } }, "node_modules/@electron/get": { @@ -74,211 +55,81 @@ "global-agent": "^3.0.0" } }, - "node_modules/@electron/get/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@electron/notarize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.1.0.tgz", - "integrity": "sha512-Q02xem1D0sg4v437xHgmBLxI2iz/fc0D4K7fiVWHa/AnW8o7D751xyKNXgziA6HrTOme9ul1JfWN5ark8WH1xA==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "fs-extra": "^9.0.1", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@electron/notarize/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "node_modules/@electron/get/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "dependencies": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=10" + "node": ">=6 <7 || >=8" } }, - "node_modules/@electron/notarize/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/@electron/get/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, - "node_modules/@electron/notarize/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@electron/osx-sign": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.5.tgz", - "integrity": "sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww==", + "node_modules/@electron/get/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "dependencies": { - "compare-version": "^0.1.2", - "debug": "^4.3.4", - "fs-extra": "^10.0.0", - "isbinaryfile": "^4.0.8", - "minimist": "^1.2.6", - "plist": "^3.0.5" - }, "bin": { - "electron-osx-flat": "bin/electron-osx-flat.js", - "electron-osx-sign": "bin/electron-osx-sign.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@electron/osx-sign/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@electron/osx-sign/node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true, - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "node_modules/@electron/osx-sign/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/osx-sign/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" + "semver": "bin/semver.js" } }, - "node_modules/@electron/universal": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.4.1.tgz", - "integrity": "sha512-lE/U3UNw1YHuowNbTmKNs9UlS3En3cPgwM5MI+agIgr/B1hSze9NdOP0qn7boZaI9Lph8IDv3/24g9IxnJP7aQ==", + "node_modules/@electron/get/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, - "dependencies": { - "@electron/asar": "^3.2.1", - "@malept/cross-spawn-promise": "^1.1.0", - "debug": "^4.3.1", - "dir-compare": "^3.0.0", - "fs-extra": "^9.0.1", - "minimatch": "^3.0.4", - "plist": "^3.0.4" - }, "engines": { - "node": ">=8.6" + "node": ">= 4.0.0" } }, - "node_modules/@electron/universal/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/universal/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/universal/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz", - "integrity": "sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ==", + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, - "dependencies": { - "comment-parser": "1.3.1", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "~3.1.0" - }, "engines": { - "node": "^14 || ^16 || ^17 || ^18" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", - "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -292,30 +143,29 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/js": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.1.1.tgz", + "integrity": "sha512-5WoDz3Y19Bg2BnErkZTp0en+c/i9PvgFS7MBe1+m60HjFr0hrphlAGp4yzI7pxpt4xShln4ZyYp4neJm8hmOkQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -330,82 +180,53 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, - "node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" - } - ], "dependencies": { - "cross-spawn": "^7.0.1" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">= 10" + "node": ">=12" } }, - "node_modules/@malept/flatpak-bundler": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", - "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "dependencies": { - "debug": "^4.1.1", - "fs-extra": "^9.0.0", - "lodash": "^4.17.15", - "tmp-promise": "^3.0.2" - }, "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@malept/flatpak-bundler/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "node": ">=12" }, - "engines": { - "node": ">=10" + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@malept/flatpak-bundler/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { - "universalify": "^2.0.0" + "ansi-regex": "^6.0.1" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@malept/flatpak-bundler/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, "engines": { - "node": ">= 10.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/@nodelib/fs.scandir": { @@ -443,6 +264,16 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -467,15 +298,6 @@ "node": ">=10" } }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, "node_modules/@types/cacheable-request": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", @@ -488,30 +310,37 @@ "@types/responselike": "^1.0.0" } }, - "node_modules/@types/debug": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.10.tgz", - "integrity": "sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==", - "dev": true, - "dependencies": { - "@types/ms": "*" - } - }, "node_modules/@types/fs-extra": { - "version": "9.0.13", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", - "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", "dev": true, "dependencies": { + "@types/jsonfile": "*", "@types/node": "*" } }, "node_modules/@types/http-cache-semantics": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz", - "integrity": "sha512-V46MYLFp08Wf2mmaBhvgjStM3tPa+2GAdy/iqoX+noX1//zje2x4XmrIU0cAwyClATsTmahbtoQ2EwP7I5WSiA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "dev": true }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", @@ -521,201 +350,189 @@ "@types/node": "*" } }, - "node_modules/@types/ms": { - "version": "0.7.33", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.33.tgz", - "integrity": "sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ==", - "dev": true - }, "node_modules/@types/node": { - "version": "18.18.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.8.tgz", - "integrity": "sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ==", + "version": "20.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.2.tgz", + "integrity": "sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, - "node_modules/@types/plist": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.4.tgz", - "integrity": "sha512-pTa9xUFQFM9WJGSWHajYNljD+DbVylE1q9IweK1LBhUYJdJ28YNU8j3KZ4Q1Qw+cSl4+QLLLOVmqNjhhvVO8fA==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*", - "xmlbuilder": ">=11.0.1" - } - }, "node_modules/@types/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/4YQT5Kp6HxUDb4yhRkm0bJ7TbjvTddqX7PZ5hz6qV3pxSo72f/6YPRo+Mu2DU307tm9IioO69l7uAwn5XNcFA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", "dev": true, "dependencies": { "@types/node": "*" } }, - "node_modules/@types/verror": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.8.tgz", - "integrity": "sha512-YhUhnxRYs/NiVUbIs3F/EzviDP/NZCEAE2Mx5DUqLdldUmphOhFCVh7Kc+7zlYEExM0P8dzfbJi0yRlNb2Bw5g==", - "dev": true, - "optional": true + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true }, "node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, "optional": true, "dependencies": { "@types/node": "*" } }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.1.tgz", + "integrity": "sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==", "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/type-utils": "7.7.1", + "@typescript-eslint/utils": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, "engines": { - "node": ">=10.0.0" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/7zip-bin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", - "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "node_modules/@typescript-eslint/parser": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.1.tgz", + "integrity": "sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", + "debug": "^4.3.4" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.1.tgz", + "integrity": "sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==", "dev": true, "dependencies": { - "debug": "4" + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1" }, "engines": { - "node": ">= 6.0.0" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@typescript-eslint/type-utils": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.1.tgz", + "integrity": "sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/utils": "7.7.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, "peerDependencies": { - "ajv": "^6.9.1" + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/@typescript-eslint/types": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.1.tgz", + "integrity": "sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==", "dev": true, "engines": { - "node": ">=8" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.1.tgz", + "integrity": "sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": ">=8" + "node": "^18.18.0 || >=20.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/app-builder-bin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz", - "integrity": "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==", - "dev": true - }, - "node_modules/app-builder-lib": { - "version": "24.6.4", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.6.4.tgz", - "integrity": "sha512-m9931WXb83teb32N0rKg+ulbn6+Hl8NV5SUpVDOVz9MWOXfhV6AQtTdftf51zJJvCQnQugGtSqoLvgw6mdF/Rg==", - "dev": true, - "dependencies": { - "@develar/schema-utils": "~2.6.5", - "@electron/notarize": "2.1.0", - "@electron/osx-sign": "1.0.5", - "@electron/universal": "1.4.1", - "@malept/flatpak-bundler": "^0.4.0", - "@types/fs-extra": "9.0.13", - "7zip-bin": "~5.1.1", - "async-exit-hook": "^2.0.1", - "bluebird-lst": "^1.0.9", - "builder-util": "24.5.0", - "builder-util-runtime": "9.2.1", - "chromium-pickle-js": "^0.2.0", - "debug": "^4.3.4", - "ejs": "^3.1.8", - "electron-publish": "24.5.0", - "form-data": "^4.0.0", - "fs-extra": "^10.1.0", - "hosted-git-info": "^4.1.0", - "is-ci": "^3.0.0", - "isbinaryfile": "^5.0.0", - "js-yaml": "^4.1.0", - "lazy-val": "^1.0.5", - "minimatch": "^5.1.1", - "read-config-file": "6.3.2", - "sanitize-filename": "^1.6.3", - "semver": "^7.3.8", - "tar": "^6.1.12", - "temp-file": "^3.4.0" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, - "engines": { - "node": ">=14.0.0" + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/app-builder-lib/node_modules/brace-expansion": { + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", @@ -724,116 +541,156 @@ "balanced-match": "^1.0.0" } }, - "node_modules/app-builder-lib/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/app-builder-lib/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/@typescript-eslint/utils": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.1.tgz", + "integrity": "sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==", "dev": true, "dependencies": { - "universalify": "^2.0.0" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", + "semver": "^7.6.0" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" } }, - "node_modules/app-builder-lib/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.1.tgz", + "integrity": "sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "@typescript-eslint/types": "7.7.1", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/app-builder-lib/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=0.4.0" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "optional": true, "engines": { - "node": ">=0.8" + "node": ">=8" } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "optional": true, + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true - }, - "node_modules/async-exit-hook": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", - "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, "engines": { - "node": ">=0.12.0" + "node": ">= 8" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "engines": { - "node": ">= 4.0.0" + "node": ">=8" } }, "node_modules/balanced-match": { @@ -842,39 +699,16 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/bluebird-lst": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", - "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, - "dependencies": { - "bluebird": "^3.5.5" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/boolean": { @@ -906,31 +740,6 @@ "node": ">=8" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "optional": true, - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -940,121 +749,31 @@ "node": "*" } }, - "node_modules/buffer-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", - "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", "dev": true, "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/builder-util": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.5.0.tgz", - "integrity": "sha512-STnBmZN/M5vGcv01u/K8l+H+kplTaq4PAIn3yeuufUKSpcdro0DhJWxPI81k5XcNfC//bjM3+n9nr8F9uV4uAQ==", - "dev": true, - "dependencies": { - "@types/debug": "^4.1.6", - "7zip-bin": "~5.1.1", - "app-builder-bin": "4.0.0", - "bluebird-lst": "^1.0.9", - "builder-util-runtime": "9.2.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "debug": "^4.3.4", - "fs-extra": "^10.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "is-ci": "^3.0.0", - "js-yaml": "^4.1.0", - "source-map-support": "^0.5.19", - "stat-mode": "^1.0.0", - "temp-file": "^3.4.0" + "node": ">=10.6.0" } }, - "node_modules/builder-util-runtime": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.1.tgz", - "integrity": "sha512-2rLv/uQD2x+dJ0J3xtsmI12AlRyk7p45TEbE/6o/fbb633e/S3pPgm+ct+JHsoY7r39dKHnGEFk/AASRFdnXmA==", + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" }, "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/builder-util/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/builder-util/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/builder-util/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true, - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" + "node": ">=8" } }, "node_modules/callsites": { @@ -1082,65 +801,28 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/chromium-pickle-js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", - "dev": true - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "optional": true, "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">=8" + "node": ">= 8.10.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "url": "https://paulmillr.com/funding/" }, - "engines": { - "node": ">=12" + "optionalDependencies": { + "fsevents": "~2.3.2" } }, "node_modules/clone-response": { @@ -1173,43 +855,13 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/comment-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", - "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", - "dev": true, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/compare-version": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": "^12.20.0 || >=14" } }, "node_modules/concat-map": { @@ -1218,33 +870,6 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/config-file-ts": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.4.tgz", - "integrity": "sha512-cKSW0BfrSaAUnxpgvpXPLaaW/umg4bqg4k3GO1JqlRfpx+d5W0GDXznCMkWotJQek5Mmz1MJVChQnz3IVaeMZQ==", - "dev": true, - "dependencies": { - "glob": "^7.1.6", - "typescript": "^4.0.2" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "optional": true - }, - "node_modules/crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "optional": true, - "dependencies": { - "buffer": "^5.1.0" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1319,18 +944,21 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "optional": true, "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-properties": { @@ -1351,15 +979,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -1367,16 +986,6 @@ "dev": true, "optional": true }, - "node_modules/dir-compare": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", - "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", - "dev": true, - "dependencies": { - "buffer-equal": "^1.0.0", - "minimatch": "^3.0.4" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1389,84 +998,6 @@ "node": ">=8" } }, - "node_modules/dmg-builder": { - "version": "24.6.4", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.6.4.tgz", - "integrity": "sha512-BNcHRc9CWEuI9qt0E655bUBU/j/3wUCYBVKGu1kVpbN5lcUdEJJJeiO0NHK3dgKmra6LUUZlo+mWqc+OCbi0zw==", - "dev": true, - "dependencies": { - "app-builder-lib": "24.6.4", - "builder-util": "24.5.0", - "builder-util-runtime": "9.2.1", - "fs-extra": "^10.1.0", - "iconv-lite": "^0.6.2", - "js-yaml": "^4.1.0" - }, - "optionalDependencies": { - "dmg-license": "^1.0.11" - } - }, - "node_modules/dmg-builder/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/dmg-builder/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/dmg-builder/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/dmg-license": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", - "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "@types/plist": "^3.0.1", - "@types/verror": "^1.10.3", - "ajv": "^6.10.0", - "crc": "^3.8.0", - "iconv-corefoundation": "^1.1.7", - "plist": "^3.0.4", - "smart-buffer": "^4.0.2", - "verror": "^1.10.0" - }, - "bin": { - "dmg-license": "bin/dmg-license.js" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -1479,45 +1010,21 @@ "node": ">=6.0.0" } }, - "node_modules/dotenv": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", - "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, - "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", - "dev": true, - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/electron": { - "version": "27.0.3", - "resolved": "https://registry.npmjs.org/electron/-/electron-27.0.3.tgz", - "integrity": "sha512-VaB9cI1se+mUtz366NP+zxFVnkHLbCBNO4wwouw3FuGyX/m7/Bv1I89JhWOBv78tC+n11ZYMrVD23Jf6EZgVcg==", + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-30.0.1.tgz", + "integrity": "sha512-iwxkI/n2wBd29NH7TH0ZY8aWGzCoKpzJz+D10u7aGSJi1TV6d4MSM3rWyKvT/UkAHkTKOEgYfUyCa2vWQm8L0g==", "dev": true, "hasInstallScript": true, "dependencies": { "@electron/get": "^2.0.0", - "@types/node": "^18.11.18", + "@types/node": "^20.9.0", "extract-zip": "^2.0.1" }, "bin": { @@ -1527,219 +1034,115 @@ "node": ">= 12.20.55" } }, - "node_modules/electron-builder": { - "version": "24.6.4", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.6.4.tgz", - "integrity": "sha512-uNWQoU7pE7qOaIQ6CJHpBi44RJFVG8OHRBIadUxrsDJVwLLo8Nma3K/EEtx5/UyWAQYdcK4nVPYKoRqBb20hbA==", + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "dependencies": { - "app-builder-lib": "24.6.4", - "builder-util": "24.5.0", - "builder-util-runtime": "9.2.1", - "chalk": "^4.1.2", - "dmg-builder": "24.6.4", - "fs-extra": "^10.1.0", - "is-ci": "^3.0.0", - "lazy-val": "^1.0.5", - "read-config-file": "6.3.2", - "simple-update-notifier": "2.0.0", - "yargs": "^17.6.2" - }, - "bin": { - "electron-builder": "cli.js", - "install-app-deps": "install-app-deps.js" - }, - "engines": { - "node": ">=14.0.0" + "once": "^1.4.0" } }, - "node_modules/electron-builder/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, "engines": { - "node": ">=12" + "node": ">=6" } }, - "node_modules/electron-builder/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, + "optional": true, "dependencies": { - "universalify": "^2.0.0" + "get-intrinsic": "^1.2.4" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">= 0.4" } }, - "node_modules/electron-builder/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, + "optional": true, "engines": { - "node": ">= 10.0.0" + "node": ">= 0.4" } }, - "node_modules/electron-publish": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.5.0.tgz", - "integrity": "sha512-zwo70suH15L15B4ZWNDoEg27HIYoPsGJUF7xevLJLSI7JUPC8l2yLBdLGwqueJ5XkDL7ucYyRZzxJVR8ElV9BA==", + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true, - "dependencies": { - "@types/fs-extra": "^9.0.11", - "builder-util": "24.5.0", - "builder-util-runtime": "9.2.1", - "chalk": "^4.1.2", - "fs-extra": "^10.1.0", - "lazy-val": "^1.0.5", - "mime": "^2.5.2" - } + "optional": true }, - "node_modules/electron-publish/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, "engines": { - "node": ">=12" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/electron-publish/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-publish/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "optional": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", - "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.3.2", - "@humanwhocodes/config-array": "^0.10.5", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", - "ajv": "^6.10.0", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", - "grapheme-splitter": "^1.0.4", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-sdsl": "^4.1.4", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -1752,31 +1155,10 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-plugin-jsdoc": { - "version": "39.3.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.6.tgz", - "integrity": "sha512-R6dZ4t83qPdMhIOGr7g2QII2pwCjYyKP+z0tPOfO1bbAbQyKC20Y2Rd6z1te86Lq3T7uM8bNo+VD9YFpE8HU/g==", - "dev": true, - "dependencies": { - "@es-joy/jsdoccomment": "~0.31.0", - "comment-parser": "1.3.1", - "debug": "^4.3.4", - "escape-string-regexp": "^4.0.0", - "esquery": "^1.4.0", - "semver": "^7.3.7", - "spdx-expression-parse": "^3.0.1" - }, - "engines": { - "node": "^14 || ^16 || ^17 || ^18" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -1784,53 +1166,53 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/eslint/node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { - "node": ">=10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=10.13.0" } }, "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1840,9 +1222,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -1901,16 +1283,6 @@ "@types/yauzl": "^2.9.1" } }, - "node_modules/extsprintf": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", - "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "optional": true - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1918,9 +1290,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -1933,18 +1305,6 @@ "node": ">=8.6.0" } }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -1958,9 +1318,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -1987,36 +1347,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2046,74 +1376,87 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">= 6" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "glob": "^7.1.3" }, - "engines": { - "node": ">=6 <7 || >=8" + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", "dev": true, "dependencies": { - "minipass": "^3.0.0" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">= 8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dependencies": { - "yallist": "^4.0.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.14" } }, "node_modules/fs.realpath": { @@ -2122,6 +1465,20 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -2132,27 +1489,22 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "optional": true, "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2173,35 +1525,61 @@ } }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.6", + "minimatch": "^9.0.1", + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "is-glob": "^4.0.3" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=10.13.0" + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/global-agent": { @@ -2223,9 +1601,9 @@ } }, "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -2237,8 +1615,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globalthis": { - "version": "1.0.3", + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, @@ -2312,15 +1702,14 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/has-flag": { @@ -2333,22 +1722,22 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "optional": true, "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "optional": true, "engines": { @@ -2372,9 +1761,9 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "optional": true, "dependencies": { @@ -2384,38 +1773,12 @@ "node": ">= 0.4" } }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/http2-wrapper": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", @@ -2429,73 +1792,10 @@ "node": ">=10.19.0" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/iconv-corefoundation": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", - "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "cli-truncate": "^2.1.0", - "node-addon-api": "^1.6.3" - }, - "engines": { - "node": "^8.11.2 || >=10" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "optional": true - }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -2542,32 +1842,16 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/ip-regex": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", - "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "dependencies": { - "ci-info": "^3.2.0" + "binary-extensions": "^2.0.0" }, - "bin": { - "is-ci": "bin.js" + "engines": { + "node": ">=8" } }, "node_modules/is-extglob": { @@ -2600,17 +1884,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-ip": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", - "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", - "dependencies": { - "ip-regex": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2620,16 +1893,13 @@ "node": ">=0.12.0" } }, - "node_modules/isbinaryfile": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz", - "integrity": "sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" + "node": ">=8" } }, "node_modules/isexe": { @@ -2638,30 +1908,24 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dev": true, "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" + "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2674,15 +1938,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsdoc-type-pratt-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", - "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", - "dev": true, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -2721,10 +1976,12 @@ } }, "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -2738,12 +1995,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/lazy-val": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", - "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", - "dev": true - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -2772,12 +2023,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -2839,39 +2084,6 @@ "node": ">=8.6" } }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", @@ -2903,78 +2115,48 @@ } }, "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/minizlib": { + "node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "node_modules/mylas": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/mylas/-/mylas-2.1.13.tgz", + "integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==", "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, "engines": { - "node": ">=8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" + "node": ">=12.0.0" }, - "engines": { - "node": ">=10" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/raouldeheer" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, "engines": { - "node": ">= 0.4.0" + "node": ">=0.10.0" } }, - "node_modules/node-addon-api": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", - "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", - "dev": true, - "optional": true - }, "node_modules/normalize-url": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", @@ -3007,17 +2189,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -3101,6 +2283,31 @@ "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -3128,18 +2335,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/plist": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", - "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "node_modules/plimit-lit": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/plimit-lit/-/plimit-lit-1.6.1.tgz", + "integrity": "sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==", "dev": true, "dependencies": { - "@xmldom/xmldom": "^0.8.8", - "base64-js": "^1.5.1", - "xmlbuilder": "^15.1.1" + "queue-lit": "^1.5.1" }, "engines": { - "node": ">=10.4.0" + "node": ">=12" } }, "node_modules/prelude-ls": { @@ -3151,17 +2356,6 @@ "node": ">= 0.8.0" } }, - "node_modules/private-ip": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/private-ip/-/private-ip-2.3.4.tgz", - "integrity": "sha512-ts/YFVwfBeLq61f9+KsOhXW6RH0wvY0gU50R6QZYzgFhggyyLK6WDFeYdjfi/HMnBm2hecLvsR3PB3JcRxDk+A==", - "dependencies": { - "ip-regex": "^4.3.0", - "ipaddr.js": "^2.0.1", - "is-ip": "^3.1.0", - "netmask": "^2.0.2" - } - }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -3171,19 +2365,6 @@ "node": ">=0.4.0" } }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -3195,14 +2376,23 @@ } }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" } }, + "node_modules/queue-lit": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.2.tgz", + "integrity": "sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3235,42 +2425,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-config-file": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz", - "integrity": "sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { - "config-file-ts": "^0.2.4", - "dotenv": "^9.0.2", - "dotenv-expand": "^5.1.0", - "js-yaml": "^4.1.0", - "json5": "^2.2.0", - "lazy-val": "^1.0.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" + "picomatch": "^2.2.1" }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8.10.0" } }, "node_modules/resolve-alpn": { @@ -3300,15 +2464,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -3320,17 +2475,20 @@ } }, "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "glob": "^10.3.7" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/esm/bin.mjs" }, - "funding": { + "engines": { + "node": ">=14" + }, + "funding": { "url": "https://github.com/sponsors/isaacs" } }, @@ -3375,31 +2533,10 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sanitize-filename": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", - "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", - "dev": true, - "dependencies": { - "truncate-utf8-bytes": "^1.0.0" - } - }, - "node_modules/sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", - "dev": true - }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -3433,19 +2570,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3467,16 +2591,16 @@ "node": ">=8" } }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/slash": { @@ -3488,104 +2612,92 @@ "node": ">=8" } }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "optional": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", "dev": true, - "optional": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } + "optional": true }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true, - "optional": true - }, - "node_modules/stat-mode": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", - "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, "engines": { - "node": ">= 6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/strip-ansi": { + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", @@ -3597,6 +2709,15 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -3633,114 +2754,65 @@ "node": ">=8" } }, - "node_modules/tar": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", - "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", - "dev": true, - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/temp-file": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", - "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", - "dev": true, - "dependencies": { - "async-exit-hook": "^2.0.1", - "fs-extra": "^10.0.0" - } - }, - "node_modules/temp-file/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/temp-file/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/temp-file/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "dependencies": { - "rimraf": "^3.0.0" + "is-number": "^7.0.0" }, "engines": { - "node": ">=8.17.0" + "node": ">=8.0" } }, - "node_modules/tmp-promise": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", - "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, - "dependencies": { - "tmp": "^0.2.0" + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/tsc-alias": { + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/tsc-alias/-/tsc-alias-1.8.8.tgz", + "integrity": "sha512-OYUOd2wl0H858NvABWr/BoSKNERw3N9GTi3rHPK8Iv4O1UyUXIrTTOAZNHsjlVpXFOhpJBVARI1s+rzwLivN3Q==", "dev": true, "dependencies": { - "is-number": "^7.0.0" + "chokidar": "^3.5.3", + "commander": "^9.0.0", + "globby": "^11.0.4", + "mylas": "^2.1.9", + "normalize-path": "^3.0.0", + "plimit-lit": "^1.2.6" }, - "engines": { - "node": ">=8.0" + "bin": { + "tsc-alias": "dist/bin/index.js" } }, - "node_modules/truncate-utf8-bytes": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, "dependencies": { - "utf8-byte-length": "^1.0.1" + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/type-check": { @@ -3756,10 +2828,11 @@ } }, "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true, + "optional": true, "engines": { "node": ">=10" }, @@ -3768,16 +2841,42 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.7.1.tgz", + "integrity": "sha512-ykEBfa3xx3odjZy6GRED4SCPrjo0rgHwstLlEgLX4EMEuv7QeIDSmfV+S6Kk+XkbsYn4BDEcPvsci1X26lRpMQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "7.7.1", + "@typescript-eslint/parser": "7.7.1", + "@typescript-eslint/utils": "7.7.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/undici-types": { @@ -3787,12 +2886,11 @@ "dev": true }, "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "engines": { - "node": ">= 4.0.0" + "node": ">= 10.0.0" } }, "node_modules/uri-js": { @@ -3804,27 +2902,6 @@ "punycode": "^2.1.0" } }, - "node_modules/utf8-byte-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==", - "dev": true - }, - "node_modules/verror": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", - "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", - "dev": true, - "optional": true, - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3840,16 +2917,25 @@ "node": ">= 8" } }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi": { + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", @@ -3866,62 +2952,76 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">=8.0" + "node": ">=8" } }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", @@ -3944,2964 +3044,5 @@ "url": "https://github.com/sponsors/sindresorhus" } } - }, - "dependencies": { - "@develar/schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", - "dev": true, - "requires": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" - } - }, - "@electron/asar": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.7.tgz", - "integrity": "sha512-8FaSCAIiZGYFWyjeevPQt+0e9xCK9YmJ2Rjg5SXgdsXon6cRnU0Yxnbe6CvJbQn26baifur2Y2G5EBayRIsjyg==", - "dev": true, - "requires": { - "commander": "^5.0.0", - "glob": "^7.1.6", - "minimatch": "^3.0.4" - } - }, - "@electron/get": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", - "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "global-agent": "^3.0.0", - "got": "^11.8.5", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@electron/notarize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.1.0.tgz", - "integrity": "sha512-Q02xem1D0sg4v437xHgmBLxI2iz/fc0D4K7fiVWHa/AnW8o7D751xyKNXgziA6HrTOme9ul1JfWN5ark8WH1xA==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "fs-extra": "^9.0.1", - "promise-retry": "^2.0.1" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } - } - }, - "@electron/osx-sign": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.5.tgz", - "integrity": "sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww==", - "dev": true, - "requires": { - "compare-version": "^0.1.2", - "debug": "^4.3.4", - "fs-extra": "^10.0.0", - "isbinaryfile": "^4.0.8", - "minimist": "^1.2.6", - "plist": "^3.0.5" - }, - "dependencies": { - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } - } - }, - "@electron/universal": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.4.1.tgz", - "integrity": "sha512-lE/U3UNw1YHuowNbTmKNs9UlS3En3cPgwM5MI+agIgr/B1hSze9NdOP0qn7boZaI9Lph8IDv3/24g9IxnJP7aQ==", - "dev": true, - "requires": { - "@electron/asar": "^3.2.1", - "@malept/cross-spawn-promise": "^1.1.0", - "debug": "^4.3.1", - "dir-compare": "^3.0.0", - "fs-extra": "^9.0.1", - "minimatch": "^3.0.4", - "plist": "^3.0.4" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } - } - }, - "@es-joy/jsdoccomment": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz", - "integrity": "sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ==", - "dev": true, - "requires": { - "comment-parser": "1.3.1", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "~3.1.0" - } - }, - "@eslint/eslintrc": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", - "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", - "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.1" - } - }, - "@malept/flatpak-bundler": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", - "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "fs-extra": "^9.0.0", - "lodash": "^4.17.15", - "tmp-promise": "^3.0.2" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true - }, - "@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dev": true, - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, - "@types/debug": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.10.tgz", - "integrity": "sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==", - "dev": true, - "requires": { - "@types/ms": "*" - } - }, - "@types/fs-extra": { - "version": "9.0.13", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", - "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/http-cache-semantics": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz", - "integrity": "sha512-V46MYLFp08Wf2mmaBhvgjStM3tPa+2GAdy/iqoX+noX1//zje2x4XmrIU0cAwyClATsTmahbtoQ2EwP7I5WSiA==", - "dev": true - }, - "@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/ms": { - "version": "0.7.33", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.33.tgz", - "integrity": "sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ==", - "dev": true - }, - "@types/node": { - "version": "18.18.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.8.tgz", - "integrity": "sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ==", - "dev": true, - "requires": { - "undici-types": "~5.26.4" - } - }, - "@types/plist": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.4.tgz", - "integrity": "sha512-pTa9xUFQFM9WJGSWHajYNljD+DbVylE1q9IweK1LBhUYJdJ28YNU8j3KZ4Q1Qw+cSl4+QLLLOVmqNjhhvVO8fA==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*", - "xmlbuilder": ">=11.0.1" - } - }, - "@types/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/4YQT5Kp6HxUDb4yhRkm0bJ7TbjvTddqX7PZ5hz6qV3pxSo72f/6YPRo+Mu2DU307tm9IioO69l7uAwn5XNcFA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/verror": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.8.tgz", - "integrity": "sha512-YhUhnxRYs/NiVUbIs3F/EzviDP/NZCEAE2Mx5DUqLdldUmphOhFCVh7Kc+7zlYEExM0P8dzfbJi0yRlNb2Bw5g==", - "dev": true, - "optional": true - }, - "@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*" - } - }, - "@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", - "dev": true - }, - "7zip-bin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", - "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", - "dev": true - }, - "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "app-builder-bin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz", - "integrity": "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==", - "dev": true - }, - "app-builder-lib": { - "version": "24.6.4", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.6.4.tgz", - "integrity": "sha512-m9931WXb83teb32N0rKg+ulbn6+Hl8NV5SUpVDOVz9MWOXfhV6AQtTdftf51zJJvCQnQugGtSqoLvgw6mdF/Rg==", - "dev": true, - "requires": { - "@develar/schema-utils": "~2.6.5", - "@electron/notarize": "2.1.0", - "@electron/osx-sign": "1.0.5", - "@electron/universal": "1.4.1", - "@malept/flatpak-bundler": "^0.4.0", - "@types/fs-extra": "9.0.13", - "7zip-bin": "~5.1.1", - "async-exit-hook": "^2.0.1", - "bluebird-lst": "^1.0.9", - "builder-util": "24.5.0", - "builder-util-runtime": "9.2.1", - "chromium-pickle-js": "^0.2.0", - "debug": "^4.3.4", - "ejs": "^3.1.8", - "electron-publish": "24.5.0", - "form-data": "^4.0.0", - "fs-extra": "^10.1.0", - "hosted-git-info": "^4.1.0", - "is-ci": "^3.0.0", - "isbinaryfile": "^5.0.0", - "js-yaml": "^4.1.0", - "lazy-val": "^1.0.5", - "minimatch": "^5.1.1", - "read-config-file": "6.3.2", - "sanitize-filename": "^1.6.3", - "semver": "^7.3.8", - "tar": "^6.1.12", - "temp-file": "^3.4.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "optional": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "optional": true - }, - "async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true - }, - "async-exit-hook": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", - "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bluebird-lst": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", - "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", - "dev": true, - "requires": { - "bluebird": "^3.5.5" - } - }, - "boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "optional": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true - }, - "buffer-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", - "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", - "dev": true - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "builder-util": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.5.0.tgz", - "integrity": "sha512-STnBmZN/M5vGcv01u/K8l+H+kplTaq4PAIn3yeuufUKSpcdro0DhJWxPI81k5XcNfC//bjM3+n9nr8F9uV4uAQ==", - "dev": true, - "requires": { - "@types/debug": "^4.1.6", - "7zip-bin": "~5.1.1", - "app-builder-bin": "4.0.0", - "bluebird-lst": "^1.0.9", - "builder-util-runtime": "9.2.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "debug": "^4.3.4", - "fs-extra": "^10.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "is-ci": "^3.0.0", - "js-yaml": "^4.1.0", - "source-map-support": "^0.5.19", - "stat-mode": "^1.0.0", - "temp-file": "^3.4.0" - }, - "dependencies": { - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } - } - }, - "builder-util-runtime": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.1.tgz", - "integrity": "sha512-2rLv/uQD2x+dJ0J3xtsmI12AlRyk7p45TEbE/6o/fbb633e/S3pPgm+ct+JHsoY7r39dKHnGEFk/AASRFdnXmA==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "sax": "^1.2.4" - } - }, - "cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true - }, - "cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "chromium-pickle-js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", - "dev": true - }, - "ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true - }, - "cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "optional": true, - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - } - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true - }, - "comment-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", - "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", - "dev": true - }, - "compare-version": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "config-file-ts": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.4.tgz", - "integrity": "sha512-cKSW0BfrSaAUnxpgvpXPLaaW/umg4bqg4k3GO1JqlRfpx+d5W0GDXznCMkWotJQek5Mmz1MJVChQnz3IVaeMZQ==", - "dev": true, - "requires": { - "glob": "^7.1.6", - "typescript": "^4.0.2" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "optional": true - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": { - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true - } - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true - }, - "define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dev": true, - "optional": true, - "requires": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - } - }, - "define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "optional": true, - "requires": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "optional": true - }, - "dir-compare": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", - "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0", - "minimatch": "^3.0.4" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "dmg-builder": { - "version": "24.6.4", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.6.4.tgz", - "integrity": "sha512-BNcHRc9CWEuI9qt0E655bUBU/j/3wUCYBVKGu1kVpbN5lcUdEJJJeiO0NHK3dgKmra6LUUZlo+mWqc+OCbi0zw==", - "dev": true, - "requires": { - "app-builder-lib": "24.6.4", - "builder-util": "24.5.0", - "builder-util-runtime": "9.2.1", - "dmg-license": "^1.0.11", - "fs-extra": "^10.1.0", - "iconv-lite": "^0.6.2", - "js-yaml": "^4.1.0" - }, - "dependencies": { - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } - } - }, - "dmg-license": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", - "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", - "dev": true, - "optional": true, - "requires": { - "@types/plist": "^3.0.1", - "@types/verror": "^1.10.3", - "ajv": "^6.10.0", - "crc": "^3.8.0", - "iconv-corefoundation": "^1.1.7", - "plist": "^3.0.4", - "smart-buffer": "^4.0.2", - "verror": "^1.10.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dotenv": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", - "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", - "dev": true - }, - "dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", - "dev": true - }, - "ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", - "dev": true, - "requires": { - "jake": "^10.8.5" - } - }, - "electron": { - "version": "27.0.3", - "resolved": "https://registry.npmjs.org/electron/-/electron-27.0.3.tgz", - "integrity": "sha512-VaB9cI1se+mUtz366NP+zxFVnkHLbCBNO4wwouw3FuGyX/m7/Bv1I89JhWOBv78tC+n11ZYMrVD23Jf6EZgVcg==", - "dev": true, - "requires": { - "@electron/get": "^2.0.0", - "@types/node": "^18.11.18", - "extract-zip": "^2.0.1" - } - }, - "electron-builder": { - "version": "24.6.4", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.6.4.tgz", - "integrity": "sha512-uNWQoU7pE7qOaIQ6CJHpBi44RJFVG8OHRBIadUxrsDJVwLLo8Nma3K/EEtx5/UyWAQYdcK4nVPYKoRqBb20hbA==", - "dev": true, - "requires": { - "app-builder-lib": "24.6.4", - "builder-util": "24.5.0", - "builder-util-runtime": "9.2.1", - "chalk": "^4.1.2", - "dmg-builder": "24.6.4", - "fs-extra": "^10.1.0", - "is-ci": "^3.0.0", - "lazy-val": "^1.0.5", - "read-config-file": "6.3.2", - "simple-update-notifier": "2.0.0", - "yargs": "^17.6.2" - }, - "dependencies": { - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "electron-publish": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.5.0.tgz", - "integrity": "sha512-zwo70suH15L15B4ZWNDoEg27HIYoPsGJUF7xevLJLSI7JUPC8l2yLBdLGwqueJ5XkDL7ucYyRZzxJVR8ElV9BA==", - "dev": true, - "requires": { - "@types/fs-extra": "^9.0.11", - "builder-util": "24.5.0", - "builder-util-runtime": "9.2.1", - "chalk": "^4.1.2", - "fs-extra": "^10.1.0", - "lazy-val": "^1.0.5", - "mime": "^2.5.2" - }, - "dependencies": { - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "optional": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", - "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.3.2", - "@humanwhocodes/config-array": "^0.10.5", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", - "@humanwhocodes/module-importer": "^1.0.1", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - } - }, - "eslint-plugin-jsdoc": { - "version": "39.3.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.6.tgz", - "integrity": "sha512-R6dZ4t83qPdMhIOGr7g2QII2pwCjYyKP+z0tPOfO1bbAbQyKC20Y2Rd6z1te86Lq3T7uM8bNo+VD9YFpE8HU/g==", - "dev": true, - "requires": { - "@es-joy/jsdoccomment": "~0.31.0", - "comment-parser": "1.3.1", - "debug": "^4.3.4", - "escape-string-regexp": "^4.0.0", - "esquery": "^1.4.0", - "semver": "^7.3.7", - "spdx-expression-parse": "^3.0.1" - } - }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", - "dev": true, - "requires": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - } - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, - "extsprintf": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", - "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", - "dev": true, - "optional": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "requires": { - "minimatch": "^5.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "optional": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dev": true, - "optional": true, - "requires": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, - "optional": true, - "requires": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - } - }, - "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "optional": true, - "requires": { - "define-properties": "^1.1.3" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "optional": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dev": true, - "requires": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dev": true, - "optional": true, - "requires": { - "get-intrinsic": "^1.2.2" - } - }, - "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, - "optional": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "optional": true - }, - "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dev": true, - "optional": true, - "requires": { - "function-bind": "^1.1.2" - } - }, - "hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true - }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, - "http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "iconv-corefoundation": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", - "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", - "dev": true, - "optional": true, - "requires": { - "cli-truncate": "^2.1.0", - "node-addon-api": "^1.6.3" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "optional": true - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ip-regex": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", - "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==" - }, - "ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==" - }, - "is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, - "requires": { - "ci-info": "^3.2.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-ip": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", - "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", - "requires": { - "ip-regex": "^4.0.0" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "isbinaryfile": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz", - "integrity": "sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", - "dev": true, - "requires": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - } - }, - "js-sdsl": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", - "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jsdoc-type-pratt-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", - "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", - "dev": true - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "optional": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "lazy-val": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", - "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "optional": true, - "requires": { - "escape-string-regexp": "^4.0.0" - } - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==" - }, - "node-addon-api": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", - "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", - "dev": true, - "optional": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "plist": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", - "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", - "dev": true, - "requires": { - "@xmldom/xmldom": "^0.8.8", - "base64-js": "^1.5.1", - "xmlbuilder": "^15.1.1" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "private-ip": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/private-ip/-/private-ip-2.3.4.tgz", - "integrity": "sha512-ts/YFVwfBeLq61f9+KsOhXW6RH0wvY0gU50R6QZYzgFhggyyLK6WDFeYdjfi/HMnBm2hecLvsR3PB3JcRxDk+A==", - "requires": { - "ip-regex": "^4.3.0", - "ipaddr.js": "^2.0.1", - "is-ip": "^3.1.0", - "netmask": "^2.0.2" - } - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "requires": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true - }, - "read-config-file": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz", - "integrity": "sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==", - "dev": true, - "requires": { - "config-file-ts": "^0.2.4", - "dotenv": "^9.0.2", - "dotenv-expand": "^5.1.0", - "js-yaml": "^4.1.0", - "json5": "^2.2.0", - "lazy-val": "^1.0.4" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "requires": { - "lowercase-keys": "^2.0.0" - } - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "dev": true, - "optional": true, - "requires": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sanitize-filename": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", - "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", - "dev": true, - "requires": { - "truncate-utf8-bytes": "^1.0.0" - } - }, - "sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", - "dev": true - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true, - "optional": true - }, - "serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "optional": true, - "requires": { - "type-fest": "^0.13.1" - }, - "dependencies": { - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "optional": true - } - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "requires": { - "semver": "^7.5.3" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "optional": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, - "sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true, - "optional": true - }, - "stat-mode": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", - "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, - "requires": { - "debug": "^4.1.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tar": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", - "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "temp-file": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", - "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", - "dev": true, - "requires": { - "async-exit-hook": "^2.0.1", - "fs-extra": "^10.0.0" - }, - "dependencies": { - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - }, - "tmp-promise": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", - "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", - "dev": true, - "requires": { - "tmp": "^0.2.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "truncate-utf8-bytes": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", - "dev": true, - "requires": { - "utf8-byte-length": "^1.0.1" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true - }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "utf8-byte-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==", - "dev": true - }, - "verror": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", - "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } } } diff --git a/package.json b/package.json index 2185eb3..e7de045 100644 --- a/package.json +++ b/package.json @@ -1,52 +1,32 @@ { - "name": "nex-viewer", + "name": "nex-viewer-rewrite", "version": "1.0.0", "description": "Utility for parsing and viewing NEX connections from packet captures", - "main": "src/parser.js", + "main": "index.js", "scripts": { - "lint": "./node_modules/.bin/eslint .", - "start": "electron ./app/", - "app:dir": "electron-builder --dir", - "app:dist": "electron-builder" + "lint": "./node_modules/.bin/eslint ./src", + "clean": "rimraf ./dist", + "copy-html": "mkdir -p ./dist/renderers/main && cp ./src/renderers/main/index.html ./dist/renderers/main/index.html", + "build": "npm run lint && npm run clean && npx tsc && npx tsc-alias && npm run copy-html", + "start": "electron dist/windows/main/index.js" }, "keywords": [], - "author": { - "name": "Jonathan Barrow", - "email": "jonbarrow1998@gmail.com", - "url": "https://jonbarrow.dev/" - }, - "license": "ISC", - "dependencies": { - "private-ip": "^2.3.4", - "semver": "^7.5.4" - }, + "author": "Pretendo Network", + "license": "AGPL-3.0", "devDependencies": { - "electron": "^27.0.3", - "electron-builder": "^24.6.4", - "eslint": "^8.24.0", - "eslint-plugin-jsdoc": "^39.3.6" + "@eslint/js": "^9.1.1", + "@types/fs-extra": "^11.0.4", + "@types/semver": "^7.5.8", + "electron": "^30.0.1", + "eslint": "^8.57.0", + "rimraf": "^5.0.5", + "tsc-alias": "^1.8.8", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.4.5", + "typescript-eslint": "^7.7.1" }, - "build": { - "productName": "NEX Viewer", - "appId": "network.pretendo.nex-viewer", - "directories": { - "output": "builds" - }, - "linux": { - "target": [ - "AppImage", - "deb" - ], - "category": "Development" - }, - "files": [ - "!builds", - "!test", - "!.gitignore", - "!README.md", - "!access.txt", - "!nex.txt", - "!build_games_list.js" - ] + "dependencies": { + "fs-extra": "^11.2.0", + "semver": "^7.6.0" } } diff --git a/src/byte-stream.ts b/src/byte-stream.ts new file mode 100644 index 0000000..f5e8b99 --- /dev/null +++ b/src/byte-stream.ts @@ -0,0 +1,120 @@ +export default class ByteStream { + private buffer: Buffer; + private offset: number; + + constructor(buffer: Buffer) { + this.buffer = buffer; + this.offset = 0; + } + + public pos(): number { + return this.offset; + } + + public hasDataLeft(): boolean { + return this.pos() < this.buffer.length; + } + + public remaining(): number { + return this.buffer.length - this.pos(); + } + + public skip(value: number): void { + this.offset += value; + } + + public seek(offset: number): void { + this.offset = offset; + } + + public read(len: number): Buffer { + const read = this.buffer.subarray(this.pos(), this.pos() + len); + this.offset += len; + + return read; + } + + public readBytes(len: number): Buffer { + return this.read(len); + } + + public readRest(): Buffer { + return this.readBytes(this.remaining()); + } + + public readUInt8(): number { + return this.readBytes(1).readUInt8(); + } + + public readInt8(): number { + return this.readBytes(1).readInt8(); + } + + public readUInt16BE(): number { + return this.readBytes(2).readUInt16BE(); + } + + public readUInt16LE(): number { + return this.readBytes(2).readUInt16LE(); + } + + public readInt16BE(): number { + return this.readBytes(2).readInt16BE(); + } + + public readInt16LE(): number { + return this.readBytes(2).readInt16LE(); + } + + public readUInt32BE(): number { + return this.readBytes(4).readUInt32BE(); + } + + public readUInt32LE(): number { + return this.readBytes(4).readUInt32LE(); + } + + public readInt32BE(): number { + return this.readBytes(4).readInt32BE(); + } + + public readInt32LE(): number { + return this.readBytes(4).readInt32LE(); + } + + public readUInt64BE(): bigint { + return this.readBytes(8).readBigUInt64BE(); + } + + public readUInt64LE(): bigint { + return this.readBytes(8).readBigUInt64LE(); + } + + public readInt64BE(): bigint { + return this.readBytes(8).readBigInt64BE(); + } + + public readInt64LE(): bigint { + return this.readBytes(8).readBigInt64LE(); + } + + public readDoubleBE(): number { + return this.readBytes(8).readDoubleBE(); + } + + public readDoubleLE(): number { + return this.readBytes(8).readDoubleLE(); + } + + public readFloatBE(): number { + return this.readBytes(4).readFloatBE(); + } + + public readFloatLE(): number { + return this.readBytes(4).readFloatLE(); + } + + public readBoolean(): boolean { + return Boolean(this.readUInt8()); + } +} \ No newline at end of file diff --git a/src/connection.js b/src/connection.js deleted file mode 100644 index 7309f40..0000000 --- a/src/connection.js +++ /dev/null @@ -1,463 +0,0 @@ -/** - * @typedef {import('./packetv0')} PacketV0 - * @typedef {import('./packetv1')} PacketV1 - */ - -const fs = require('fs'); -const os = require('os'); -const crypto = require('crypto'); -const titles = require('./titles.json'); -const Packet = require('./packet'); -const RMCMessage = require('./rmc'); -const Protocols = require('./protocols'); -const kerberos = require('./kerberos'); -const Authentication = require('./protocols/authentication'); -const Stream = require('./stream'); -const FragmentationManager = require('./fragmentation_manager'); -const { md5 } = require('./util'); - -// * Find the NEX keys file path -let NEX_KEYS_FILE_PATH; -if (fs.existsSync(__dirname + '/../nex-keys.txt')) { // check if nex-keys is in the "src" folder - NEX_KEYS_FILE_PATH = __dirname + '/../nex-keys.txt'; -} else if (fs.existsSync(__dirname + '/../../nex-keys.txt')) { // check if nex-keys is in the root folder - NEX_KEYS_FILE_PATH = __dirname + '/../../nex-keys.txt'; -} else if (process.platform === 'win32') { // if neither exist then grab the keys from WireShark on Windows - NEX_KEYS_FILE_PATH = process.env.APPDATA + '/Wireshark/nex-keys.txt'; -} else { // default to assuming OSX/Linux - const home = os.homedir(); - NEX_KEYS_FILE_PATH = `${home}/.config/wireshark/nex-keys.txt`; -} - -if (!fs.existsSync(NEX_KEYS_FILE_PATH)) { - throw new Error('Could not locate nex-keys.txt file'); -} - -// * Parse out the NEX keys -// * Format is one PID:KEY per line -const NEX_KEYS_FILE = fs.readFileSync(NEX_KEYS_FILE_PATH, { encoding: 'utf-8' }); -const NEX_KEYS = Object.fromEntries(NEX_KEYS_FILE.split('\n').filter(line => line).map(combo => { - const parts = combo.split(':'); - const pid = parts.shift(); - const password = parts.join(':'); - - return [pid, password]; -})); - -// * Derive Kerberos keys from passwords -for (let pid in NEX_KEYS) { - const key = NEX_KEYS[pid]; - - if (key.length !== 32) { - NEX_KEYS[pid] = kerberos.deriveKerberosKey(Number(pid), key).toString('hex'); - } -} - -// * Write file back to disk -let NEW_NEX_KEYS = ''; -for (let pid in NEX_KEYS) { - NEW_NEX_KEYS += `${pid}:${NEX_KEYS[pid]}\n`; -} -fs.writeFileSync(NEX_KEYS_FILE_PATH, NEW_NEX_KEYS); - -class Connection { - /** - * - * @param {string} discriminator Unique connection identifer - */ - constructor(discriminator) { - this.discriminator = discriminator; - this.packets = []; - - // * These are used as part of the heuristics during packet parsing - // * to know if a packet is legitimate or not. - // * For example if a CONNECT packet comes in before the SYN packets, - // * of if a DATA packet comes in before the CONNECT packets. These - // * packets will be marked as illegitimate - this.doneClientSyn = false; - this.doneServerSyn = false; - this.doneClientConnect = false; - this.doneServerConnect = false; - - this.reset(); - } - - toJSON() { - return { - discriminator: this.discriminator, - title: this.title, - secure: this.isSecureServer - }; - } - - reset() { - this.prudpVersion = null; - this.accessKey = null; - this.accessKeySum = Buffer.alloc(4); - this.signatureKey = null; - this.sessionKey = Buffer.alloc(0); - this.currentFragmentedPayload = Buffer.alloc(0); - this.clientConnectionSignature = Buffer.alloc(0); - this.serverConnectionSignature = Buffer.alloc(0); - this.rc4CipherToClient = crypto.createDecipheriv('rc4', 'CD&ML', ''); - this.rc4CipherToServer = crypto.createDecipheriv('rc4', 'CD&ML', ''); - - this.clientPID = null; - this.clientNEXPassword = null; - this.secureServerStationURL = null; - this.checkForSecureServer = false; - this.isSecureServer = false; - - this.title = { - name: '', - title_ids: [], - access_key: '', - nex_version: '0.0.0', - nex_ranking_version: '0.0.0', - nex_datastore_version: '0.0.0', - nex_match_making_version: '0.0.0', - nex_messaging_version: '0.0.0', - nex_utility_version: '0.0.0' - }; - - this.clientFragmentationManager = new FragmentationManager(); - this.serverFragmentationManager = new FragmentationManager(); - this.decryptedClientPayloads = {}; - this.decryptedServerPayloads = {}; - - this.clientAddress; - this.serverAddress; - } - - /** - * - * @param {(string|Buffer)} key Crypto key - */ - setRC4Key(key) { - this.rc4CipherToClient = crypto.createDecipheriv('rc4', key, ''); - this.rc4CipherToServer = crypto.createDecipheriv('rc4', key, ''); - } - - /** - * - * @returns {boolean} True if server is friends - */ - isFriendsServer() { - return this.accessKey === 'ridfebb9'; - } - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - handlePacket(packet) { - if (this.prudpVersion === undefined) { - this.prudpVersion = packet.version; - } - - if (packet.isData() && !packet.hasFlagReliable()) { - // * Packet is an unreliable data packet - // * These packets use their own RC4 stream - // * and are not supported - - this.packets.push(packet); - return; - } - - if (packet.hasFlagAck() || packet.hasFlagMultiAck()) { - if (packet.isSyn() && packet.isToClient()) { - // * SYN packet from server - this.serverConnectionSignature = packet.connectionSignature; - } - - // TODO - Parse these for their sequence IDs - - this.packets.push(packet); - return; - } - - if (packet.isPing()) { - // * Ping packets contain no useful information - - this.packets.push(packet); - return; - } - - if (packet.isToServer() && !this.accessKey) { - // * Find access key - for (const title of titles) { - const accessKey = title.access_key; - let found = false; - - if (!accessKey || accessKey.trim() === '') { - continue; - } - - if (packet.version === 0) { - const expectedChecksum = packet.checksum; - const calculatedChecksum = packet.calculateChecksum(accessKey); - - if (expectedChecksum === calculatedChecksum) { - found = true; - } - } else { - const expectedSignature = packet.signature; - const calculatedSignature = packet.calculateSignature(accessKey); - - if (expectedSignature.equals(calculatedSignature)) { - found = true; - } - } - - if (found) { - const keyBuffer = Buffer.from(accessKey); - const signatureBase = keyBuffer.reduce((sum, byte) => sum + byte, 0); - - this.accessKey = accessKey; - this.signatureKey = md5(accessKey); - this.accessKeySum.writeUInt32LE(signatureBase); - - this.title = title; - break; - } - } - } - - if (packet.isConnect() && packet.isToServer()) { - // * CONNECT packet from client - this.clientConnectionSignature = packet.connectionSignature; - } - - if (packet.isData()) { - let fragments; - - if (packet.isToServer()) { - fragments = this.clientFragmentationManager.update(packet); - } else { - fragments = this.serverFragmentationManager.update(packet); - } - - if (packet.fragmentId === 0) { - const payloads = []; - - for (const fragment of fragments) { - if (packet.isToServer() && this.decryptedClientPayloads[fragment.sequenceId]) { - payloads.push(this.decryptedClientPayloads[fragment.sequenceId]); - } else if (packet.isToClient() && this.decryptedServerPayloads[fragment.sequenceId]) { - payloads.push(this.decryptedServerPayloads[fragment.sequenceId]); - } else { - let cipher; - - if (packet.isToServer()) { - // * Use the client->server cipher - cipher = this.rc4CipherToServer; - } else { - // * Use the server->client cipher - cipher = this.rc4CipherToClient; - } - - const decrypted = cipher.update(fragment.payload); - - if (packet.isToServer()) { - this.decryptedClientPayloads[fragment.sequenceId] = decrypted; - } else { - this.decryptedServerPayloads[fragment.sequenceId] = decrypted; - } - - payloads.push(decrypted); - } - } - - const decryptedPayload = Buffer.concat(payloads); - - packet.rmcMessage = new RMCMessage(decryptedPayload); - - // * If the packet has a custom ID, check the protocol list with it - let protocolId; - if (packet.rmcMessage.protocolId === 0x7F) { - protocolId = packet.rmcMessage.customId; - } else { - protocolId = packet.rmcMessage.protocolId; - } - - const protocol = Protocols[protocolId]; - - if (!protocol) { - console.log(`Unknown protocol ID ${protocolId} (0x${protocolId.toString(16)})`); - this.packets.push(packet); - return; - } - - if (!packet.rmcMessage.isRequest() && !packet.rmcMessage.isSuccess()) { - const requestPacket = this.packets.find(p => { - if ( - p.rmcMessage.isRequest() && - p.rmcMessage.protocolId === packet.rmcMessage.protocolId && - p.rmcMessage.callId === packet.rmcMessage.callId - ) { - return true; - } - }); - - if (requestPacket) { - packet.rmcMessage.methodId = requestPacket.rmcMessage.methodId; - } - } else { - try { - protocol.handlePacket(packet); - } catch (error) { - packet.stackTrace = error.stack; - } - } - - if (!packet.rmcData.protocolName) { - packet.rmcData.protocolName = protocol.ProtocolName; - } - - if (!packet.rmcData.methodName) { - packet.rmcData.methodName = protocol.MethodNames[packet.rmcMessage.methodId]; - } - - if (packet.rmcMessage.isResponse() & packet.rmcMessage.isSuccess()) { - if (packet.rmcMessage.protocolId === Authentication.ProtocolID) { - if (packet.rmcMessage.methodId === Authentication.Methods.Login || packet.rmcMessage.methodId === Authentication.Methods.LoginEx) { - if (packet.rmcData.body.retval.isError()) { - return; - } - - this.clientPID = packet.rmcData.body.pidPrincipal; - this.clientNEXPassword = NEX_KEYS[this.clientPID]; - this.secureServerStationURL = packet.rmcData.body.pConnectionData.stationUrl; - - if (!this.clientNEXPassword) { - throw new Error(`No NEX password set for PID ${this.clientPID}!`); - } - - const ticketStream = new Stream(packet.rmcData.body.pbufResponse, this); - const ticket = new kerberos.KerberosTicket(ticketStream); - - if (ticket.targetPID === this.clientPID) { - this.sessionKey = ticket.sessionKey; - this.checkForSecureServer = true; - } - } - - if (packet.rmcMessage.methodId === Authentication.Methods.RequestTicket) { - if (packet.rmcData.body.retval.isError()) { - return; - } - - const ticketStream = new Stream(packet.rmcData.body.bufResponse, this); - const ticket = new kerberos.KerberosTicket(ticketStream); - - this.sessionKey = ticket.sessionKey; - this.checkForSecureServer = true; - } - } - } - } - } - - this.packets.push(packet); - } - - /** - * - * @param {Buffer} data Raw RMC payload data from HokakuCTR - */ - handleRawRMC(data) { - // TODO - Refactor handlePacket to also use this function? To reduce duplicate code? - const stream = new Stream(data, this); - const revision = stream.readUInt8(); - - if (revision !== 1) { - throw new Error(`Found packet with unsupported HokakuCTR version. Expected 1, got ${revision}`); - } - - const titleID = stream.readUInt64LE().toString(16).padStart(16, '0').toUpperCase(); - const flags = stream.readUInt8(); - const message = new RMCMessage(stream.readRest()); - - const isResponseRMCMessage = (flags & 0b00000001) !== 0; - - if (!this.title.name) { - for (const title of titles) { - if (title.title_ids?.includes(titleID)) { - this.title = title; - this.accessKey = title.access_key; - break; - } - } - } - - // * Couldn't find a title - if (!this.title.name) { - throw new Error(`Failed to find title data for ${titleID} in titles.json`); - } - - // * Construct a fake packet for the RMC data - const packet = new Packet(this); - - packet.isRawRMC = true; - packet.rmcMessage = message; - - if (isResponseRMCMessage) { - packet.source = 0xAF; - packet.destination = 0xA1; - } else { - packet.source = 0xA1; - packet.destination = 0xAF; - } - - // * If the packet has a custom ID, check the protocol list with it - let protocolId; - if (packet.rmcMessage.protocolId === 0x7F) { - protocolId = packet.rmcMessage.customId; - } else { - protocolId = packet.rmcMessage.protocolId; - } - - const protocol = Protocols[protocolId]; - - if (!protocol) { - console.log(`Unknown protocol ID ${protocolId} (0x${protocolId.toString(16)})`); - this.packets.push(packet); - return; - } - - if (packet.rmcMessage.isResponse() && !packet.rmcMessage.isSuccess()) { - const requestPacket = this.packets.find(p => { - if ( - p.rmcMessage.isRequest() && - p.rmcMessage.protocolId === packet.rmcMessage.protocolId && - p.rmcMessage.callId === packet.rmcMessage.callId - ) { - return true; - } - }); - - if (requestPacket) { - packet.rmcMessage.methodId = requestPacket.rmcMessage.methodId; - } - } else { - try { - protocol.handlePacket(packet); - } catch (error) { - packet.stackTrace = error.stack; - } - } - - if (!packet.rmcData.protocolName) { - packet.rmcData.protocolName = protocol.ProtocolName; - } - - if (!packet.rmcData.methodName) { - packet.rmcData.methodName = protocol.MethodNames[packet.rmcMessage.methodId]; - } - - this.packets.push(packet); - } -} - - -module.exports = Connection; diff --git a/src/fragmentation_manager.js b/src/fragmentation_manager.js deleted file mode 100644 index ad3f670..0000000 --- a/src/fragmentation_manager.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @typedef {import('./packet')} Packet - * @typedef {import('./packetv0')} PacketV0 - * @typedef {import('./packetv1')} PacketV1 - */ - -class FragmentationManager { - constructor() { - this.fragments = []; - } - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - * @returns {Array} fragments - */ - update(packet) { - // * Some extra fragment - if (packet.fragmentId !== 0) { - this.fragments.push({ - sequenceId: packet.sequenceId, - fragmentId: packet.fragmentId, - nextedExpectedSequenceId: packet.sequenceId+1, - payload: packet.payload - }); - } - - // * End of fragmentation. Start rebuilding - if (packet.fragmentId === 0) { - const fragments = []; - const secondToLastFragment = this.fragments.find(fragment => fragment.nextedExpectedSequenceId === packet.sequenceId); - - if (secondToLastFragment) { - // * Payload was fragmented - const missingFragments = []; - const firstFragment = this.fragments.find(fragment => fragment.sequenceId === secondToLastFragment.sequenceId-secondToLastFragment.fragmentId+1); - - fragments.push(firstFragment); - - let currentFragment = firstFragment; - - for (let i = 0; i < secondToLastFragment.fragmentId-1; i++) { - const nextFragment = this.fragments.find(fragment => fragment.sequenceId === currentFragment.nextedExpectedSequenceId); - if (!nextFragment) { - console.log('MISSING FRAGMENT', currentFragment.nextedExpectedSequenceId); - missingFragments.push(currentFragment.nextedExpectedSequenceId); - - // TODO - Handle and defer this. I don't have any dumps which have missing packets to test! - - // * Fake next fragment, just to keep the loop going - currentFragment = { - nextedExpectedSequenceId: currentFragment.nextedExpectedSequenceId+1 - }; - } else { - currentFragment = nextFragment; - fragments.push(currentFragment); - } - } - } - - // * Reorder the packets from 1-X and add fragment 0 to the end - const sortedFragments = fragments.sort((a, b) => a.fragmentId - b.fragmentId); - sortedFragments.push(packet); - - return sortedFragments; - } - - return []; - } -} - -module.exports = FragmentationManager; \ No newline at end of file diff --git a/src/kerberos.js b/src/kerberos.js deleted file mode 100644 index c89bf89..0000000 --- a/src/kerberos.js +++ /dev/null @@ -1,94 +0,0 @@ -const crypto = require('crypto'); -const Stream = require('./stream'); -const { md5 } = require('./util'); - -class KerberosEncryption { - /** - * - * @param {string} key Crypto key - */ - constructor(key) { - this.key = key; - this.cipher = crypto.createCipheriv('rc4', key, ''); - } - - /** - * - * @param {Buffer} buffer Kerberos encrypted buffer - * @returns {Buffer} Decrypted buffer - */ - decrypt(buffer) { - if (!this.validate(buffer)) { - throw new Error('Kerberos ticket validity check failed'); - } - - const data = buffer.subarray(0, -0x10); - return this.cipher.update(data); - } - - /** - * - * @param {Buffer} buffer Kerberos encrypted buffer - * @returns {boolean} isValid - */ - validate(buffer) { - const data = buffer.subarray(0, -0x10); - const checksum = buffer.subarray(-0x10); - - const hmac = crypto.createHmac('md5', this.key).update(data).digest(); - - return checksum.equals(hmac); - } -} - -class KerberosTicket { - /** - * - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.stream = stream; - this.key = Buffer.from(this.stream.connection.clientNEXPassword, 'hex'); - - this.sessionKey; - this.targetPID; - this.internalTicketData; - - this.decrypt(); - } - - decrypt() { - const encryption = new KerberosEncryption(this.key); - const decrypted = encryption.decrypt(this.stream._buffer); - - const decryptedStream = new Stream(decrypted); - - if (this.stream.connection.isFriendsServer()) { - this.sessionKey = decryptedStream.readBytes(16); - } else { - this.sessionKey = decryptedStream.readBytes(32); - } - - this.targetPID = decryptedStream.readUInt32LE(); - this.internalTicketData = decryptedStream.readNEXBuffer(); - } -} - -/** - * - * @param {number} pid User NEX account PID - * @param {string} password User NEX account password - * @returns {Buffer} Kerberos key - */ -function deriveKerberosKey(pid, password) { - for (let i = 0; i < 65000 + (pid % 1024); i++) { - password = md5(password); - } - - return password; -} - -module.exports = { - KerberosTicket, - deriveKerberosKey -}; \ No newline at end of file diff --git a/src/nex/byte-stream.ts b/src/nex/byte-stream.ts new file mode 100644 index 0000000..f696c96 --- /dev/null +++ b/src/nex/byte-stream.ts @@ -0,0 +1,12 @@ +import ByteStream from '@/byte-stream'; +import type NEXByteStreamSettings from '@/types/nex/byte-stream-settings'; + +export default class NEXByteStream extends ByteStream { + public settings: NEXByteStreamSettings; + + constructor(buffer: Buffer, settings: NEXByteStreamSettings) { + super(buffer); + + this.settings = settings; + } +} \ No newline at end of file diff --git a/src/nex/connection.ts b/src/nex/connection.ts new file mode 100644 index 0000000..97448f3 --- /dev/null +++ b/src/nex/connection.ts @@ -0,0 +1,349 @@ +import os from 'node:os'; +import fs from 'fs-extra'; +import Substream from '@/nex/substream'; +import RMCMessage from '@/nex/rmc-message'; +import { keyDerivationOld, keyDerivationNew, Ticket } from '@/nex/kerberos'; +import getProtocol from '@/nex/protocols/manager'; +import TicketGrantingProtocol from '@/nex/protocols/ticket-granting'; +import type Packet from '@/types/nex/packet'; +import type NEXByteStreamSettings from '@/types/nex/byte-stream-settings'; +import type StationURL from '@/nex/types/station-url'; + +// TODO - Maybe this should be broken out into .ts files for each game? That way a game can define it's own signature calculation functions and such? +import titles from '@/nex/titles.json'; + +// TODO - TypeScript does not allow bigint (the type of PIDs here) to be used as an index type. Update this when TypeScript allows this +const GAME_SERVER_PASSWORDS: Record = {}; + +export function populateGameServerPasswords(): void { + const paths: string[] = []; + const home = os.homedir(); + + // TODO - Support more paths? Old viewer supported more local paths, was this useful? + if (process.platform === 'win32') { + fs.ensureDirSync(`${process.env.APPDATA}/NEXViewer`); + + paths.push(`${process.env.APPDATA}/NEXViewer/game-server-passwords.txt`); + } else { + fs.ensureDirSync(`${home}/.config/nex-viewer`); + + paths.push(`${home}/.config/nex-viewer/game-server-passwords.txt`); + } + + for (const path of paths) { + if (fs.existsSync(path)) { + const credentials = fs.readFileSync(path, { + encoding: 'utf8' + }).split('\n').filter(line => line).map(line => { + const parts = line.split(':'); + const pid = parts.shift(); + const password = parts.join(':'); // * Passwords may contain ":". Need to rejoin just in case + + return { + pid, + password + }; + }); + + for (const credential of credentials) { + const pid = Number(credential.pid); + + GAME_SERVER_PASSWORDS[pid] = credential.password; + } + } + } + + if (Object.keys(GAME_SERVER_PASSWORDS).length === 0) { + // TODO - Better explain the file format? + let error = `Failed to load game server passwords. Populate "${home}/.config/nex-viewer/game-server-passwords.txt"`; + + if (process.platform === 'win32') { + error = `Failed to load game server passwords. Populate "${process.env.APPDATA}/NEXViewer/game-server-passwords.txt"`; + } + + throw new Error(error); + } +} + +// TODO - This should be moved to the main window process, so that the error thrown can be shown as a popup +populateGameServerPasswords(); + +// * Represents an individual connection to a specific game server +export default class Connection { + public clientAddress: string; + public clientPort: number; + public serverAddress: string; + public serverPort: number; + + public clientStreamType: number; + public clientStreamID: number; + public serverStreamType: number; + public serverStreamID: number; + public packets: Packet[] = []; // * Stores all packets in the connection regardless of substream, reliability, etc. Used to display all packets in order as they are sent + + public title: { + name: string; + game_server_id: string; + access_key: string; + library_versions: { + main: string; + ranking: string; + datastore: string; + match_making: string; + messaging: string; + utility: string; + }; + settings: NEXByteStreamSettings; + title_ids: string[]; + }; + + public mainSecureStationTicket: Ticket; + public specialSecureStationTicket: Ticket; // TODO - Currently unused. Also is this even accurate? + public mainSecureStation: StationURL; + public specialSecureStation: StationURL; // TODO - Currently unused + public cipherKey: Buffer | string = 'CD&ML'; + public sessionKey = Buffer.alloc(0); + + private clientSubstreams: Record = {}; + private serverSubstreams: Record = {}; + private serverConnectionSignature = Buffer.alloc(0); + private clientConnectionSignature = Buffer.alloc(0); + private ticketRequestPIDs: Record = {}; // * Track the PIDs of users tickets are requested for with TicketGranting::RequestTicket. Key is the RMC call ID, value is PID + + private reset(): void { + this.cipherKey = 'CD&ML'; + this.sessionKey = Buffer.alloc(0); + + this.clientSubstreams = {}; + this.serverSubstreams = {}; + this.serverConnectionSignature = Buffer.alloc(0); + this.clientConnectionSignature = Buffer.alloc(0); + this.ticketRequestPIDs = {}; + } + + private clientSubstream(substreamID: number): Substream { + return this.substream(substreamID, true); + } + + private serverSubstream(substreamID: number): Substream { + return this.substream(substreamID, false); + } + + private substream(substreamID: number, isClient: boolean): Substream { + const substreams = isClient ? this.clientSubstreams : this.serverSubstreams; + let substream = substreams[substreamID]; + + // TODO - This is wrong. Only the first substream gets the original key. All other substreams get a modified key. Need to properly init these + if (!substream) { + substream = new Substream(); + substream.setKey(this.cipherKey); + + substreams[substreamID] = substream; + } + + return substream; + } + + public processPacket(packet: Packet): void { + if (packet.isTypeSyn() && packet.fromClientToServer && this.mainSecureStationTicket) { + this.reset(); // * Assume a new connection has started + } + + if (packet.isTypeSyn() && packet.fromServerToClient) { + this.serverConnectionSignature = packet.connectionSignature; + } + + if (packet.isTypeConnect() && packet.fromClientToServer) { + this.clientConnectionSignature = packet.connectionSignature; + } + + if (packet.version !== -1 && packet.hasFlagAck() || packet.hasFlagMultiAck()) { + // TODO - Actually handle these? + this.packets.push(packet); + return; + } + + if (packet.version !== -1 && packet.isTypeData() && !packet.hasFlagReliable()) { + // * Packet is an unreliable DATA packet. + // * These packets use their own RC4 stream + // * and are not yet supported. + + this.packets.push(packet); + return; + } + + if (packet.isTypePing()) { + // * Don't worry about handling PING packets + + this.packets.push(packet); + return; + } + + if (!this.title) { + for (const title of titles) { + if (packet.version === -1) { + if (title.title_ids.includes(packet.titleID)) { + this.title = title; + break; + } + } else if (packet.version === 0) { + const expectedChecksum = packet.checksum; + const calculatedChecksum = packet.calculateChecksum(title.access_key); + + if (expectedChecksum === calculatedChecksum) { + this.title = title; + break; + } + } else { + // TODO - Legacy connection signature + const connectionSignature = packet.fromClientToServer ? this.clientConnectionSignature : this.serverConnectionSignature; + const expectedSignature = packet.signature; + const calculatedSignature = packet.calculateSignature(title.access_key, this.sessionKey, connectionSignature); + + if (expectedSignature.equals(calculatedSignature)) { + this.title = title; + break; + } + } + } + } + + let packets: Packet[]; + + if (packet.version !== -1) { + const substream = packet.fromClientToServer ? this.clientSubstream(packet.substreamID) : this.serverSubstream(packet.substreamID); + packets = substream.update(packet); + } else { + packets = [packet]; + } + + for (const packet of packets) { + if (packet.isTypeData()) { + // TODO - This whole section needs to be reworked to support different encryption and compression settings. Currently assumes RC4 and no compression + let defragmentedPayload: Buffer; + + if (packet.version !== -1) { + const substream = this.clientSubstream(packet.substreamID); + defragmentedPayload = substream.addFragment(packet); + } else { + defragmentedPayload = packet.payload; + } + + if (packet.fragmentID === 0) { + packet.defragmentedPayload = defragmentedPayload; + this.processPacketMessage(packet); + } + } + } + + this.packets.push(packet); + } + + private processPacketMessage(packet: Packet): void { + packet.message = new RMCMessage(packet.defragmentedPayload); + packet.message.connection = this; + + const protocol = getProtocol(packet.message); + + if (protocol) { + packet.message.protocolName = protocol.Name; + + if (!packet.message.error) { + protocol.handlePacket(packet); + } else { + const substream = packet.fromClientToServer ? this.clientSubstream(packet.substreamID) : this.serverSubstream(packet.substreamID); + const seenPackets = packet.fromClientToServer ? substream.servertoClientSeenPackets : substream.clientToServerSeenPackets; // * Search packets from the other end + const requestPacket = seenPackets.find(p => { + if ( + p.message.type === RMCMessage.REQUEST && + p.message.protocolID === packet.message.protocolID && + p.message.callID === packet.message.callID + ) { + return true; + } + }); + + if (requestPacket) { + packet.message.methodName = requestPacket.message.methodName; + } else { + packet.message.methodName = 'UnknownMethod'; + } + } + } else { + const protocolID = packet.message.extendedProtocolID ? packet.message.extendedProtocolID : packet.message.protocolID; + + packet.message.protocolName = `UnknownProtocol_0x${protocolID.toString(16).toUpperCase().padStart(2, '0')}`; + packet.message.methodName = `UnknownMethod_0x${packet.message.methodID.toString(16).toUpperCase().padStart(2, '0')}`; + } + + if (packet.message.protocolID === TicketGrantingProtocol.ID && !packet.message.error) { + const methodID = packet.message.methodID; + + if ( + (methodID === TicketGrantingProtocol.Methods.Login || methodID === TicketGrantingProtocol.Methods.LoginEx) && + packet.message.type === RMCMessage.RESPONSE + ) { + if (packet.message.parameters.retval.isSuccess()) { + const sourcePID = packet.message.parameters.pidPrincipal.value; + const ticketData = packet.message.parameters.pbufResponse.value; + + this.mainSecureStation = packet.message.parameters.pConnectionData.m_urlRegularProtocols; + this.specialSecureStation = packet.message.parameters.pConnectionData.m_urlSpecialProtocols; + + this.processKerberosTicket(ticketData, sourcePID, ''); + } + } + + if (methodID === TicketGrantingProtocol.Methods.RequestTicket && packet.message.type === RMCMessage.REQUEST) { + this.ticketRequestPIDs[packet.message.callID] = packet.message.parameters.idSource.value; + } + + if (methodID === TicketGrantingProtocol.Methods.RequestTicket && packet.message.type === RMCMessage.RESPONSE) { + // TODO - Error when not found + // TODO - RequestTicket also has a retval, is it treated the same as Login/LoginEx? + if (this.ticketRequestPIDs[packet.message.callID]) { + const sourcePID = this.ticketRequestPIDs[packet.message.callID]; + const ticketData = packet.message.parameters.bufResponse.value; + const sourceKey = packet.message.parameters.pSourceKey.value ? packet.message.parameters.pSourceKey.value : ''; + + delete this.ticketRequestPIDs[packet.message.callID]; + + this.processKerberosTicket(ticketData, sourcePID, sourceKey); + } + } + } + } + + private processKerberosTicket(ticketData: Buffer, sourcePID: bigint, sourceKey: string): void { + let key = Buffer.from(sourceKey, 'hex'); + + if (key.length === 0) { + // TODO - Remove "as any" when TypeScript updates to allow bigint as an index type + const sourcePassword = GAME_SERVER_PASSWORDS[sourcePID as any]; + + if (!sourcePassword) { + throw new Error(`No password set for PID ${sourcePID}`); + } + + if (this.title.settings.kerberos_key_version === 0) { + key = keyDerivationOld(sourcePID, sourcePassword); + } else { + key = keyDerivationNew(sourcePID, sourcePassword); + } + } + + const ticket = new Ticket(ticketData, key, this.title.settings); + + // TODO - Is this accurate to how special stations are handled? + const mainTarget = BigInt(this.mainSecureStation.getParam('PID') || 0); + const specialTarget = BigInt(this.specialSecureStation.getParam('PID') || 0); + + if (mainTarget === ticket.target.value) { + this.mainSecureStationTicket = ticket; + } + + if (specialTarget === ticket.target.value) { + this.specialSecureStationTicket = ticket; + } + } +} \ No newline at end of file diff --git a/src/nex/counter.ts b/src/nex/counter.ts new file mode 100644 index 0000000..d71673d --- /dev/null +++ b/src/nex/counter.ts @@ -0,0 +1,13 @@ +export default class Counter { + public value: number; + + constructor(initialValue: number) { + this.value = initialValue; + } + + public next(): number { + this.value += 1; + + return this.value; + } +} \ No newline at end of file diff --git a/src/nex/kerberos.ts b/src/nex/kerberos.ts new file mode 100644 index 0000000..c428412 --- /dev/null +++ b/src/nex/kerberos.ts @@ -0,0 +1,62 @@ +import crypto from 'node:crypto'; +import RC4Stream from '@/rc4'; +import NEXByteStream from '@/nex/byte-stream'; +import PID from '@/nex/types/pid'; +import RVBuffer from '@/nex/types/buffer'; +import type NEXByteStreamSettings from '@/types/nex/byte-stream-settings'; + +// * Only define the client ticket, since we can never decrypt the server ticket +export class Ticket { + public sessionKey: Buffer; + public target = new PID(); + + private internal = new RVBuffer(); // TODO - Is this useful to expose? + + constructor(data: Buffer, key: Buffer, settings: NEXByteStreamSettings) { + const decrypted = decrypt(data, key); + + const stream = new NEXByteStream(decrypted, settings); + + this.sessionKey = stream.read(settings.session_key_size); + this.target.extractFrom(stream); + this.internal.extractFrom(stream); + } +} + +export function keyDerivationOld(pid: bigint, password: string): Buffer { + let key = Buffer.from(password); + + for (let i = 0n; i < 65000n + pid % 1024n; i++) { + key = crypto.createHash('md5').update(key).digest(); + } + + return key; +} + +export function keyDerivationNew(pid: bigint, password: string): Buffer { + const passwordHash = crypto.createHash('md5').update(password).digest(); + + const pidBuffer = Buffer.alloc(8); + pidBuffer.writeBigUInt64LE(BigInt(pid), 0); + + return crypto.createHash('md5').update(Buffer.concat([ + passwordHash, + pidBuffer + ])).digest(); +} + +// * We only need to decrypt and only once, so no point in implementing this as a class +function decrypt(data: Buffer, key: Buffer): Buffer { + const checksumData = data.subarray(0, -0x10); + const expectedChecksum = data.subarray(-0x10); + const calculatedChecksum = crypto.createHmac('md5', key).update(checksumData).digest(); + + if (!expectedChecksum.equals(calculatedChecksum)) { + throw new Error('Invalid Kerberos checksum (incorrect password)'); + } + + const encrypted = data.subarray(0, -0x10); + const decipher = new RC4Stream(key); + + return decipher.update(encrypted); +} \ No newline at end of file diff --git a/src/nex/protocols/manager.ts b/src/nex/protocols/manager.ts new file mode 100644 index 0000000..308be63 --- /dev/null +++ b/src/nex/protocols/manager.ts @@ -0,0 +1,18 @@ +import RMCMessage from '@/nex/rmc-message'; +import TicketGrantingProtocol from '@/nex/protocols/ticket-granting'; +import SecureConnectionProtocol from '@/nex/protocols/secure-connection'; +import type ServiceProtocol from '@/types/nex/service-protocol'; + +export default function getProtocol(message: RMCMessage): ServiceProtocol | null { + const protocolID = message.protocolID === 0x7F ? message.extendedProtocolID : message.protocolID; + + switch (protocolID) { + case TicketGrantingProtocol.ID: + return TicketGrantingProtocol; + case SecureConnectionProtocol.ID: + return SecureConnectionProtocol; + + default: + return null; + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/index.ts b/src/nex/protocols/secure-connection/index.ts new file mode 100644 index 0000000..736482e --- /dev/null +++ b/src/nex/protocols/secure-connection/index.ts @@ -0,0 +1,58 @@ +import RMCMessage from '@/nex/rmc-message'; +import * as Requests from '@/nex/protocols/secure-connection/requests'; +import * as Responses from '@/nex/protocols/secure-connection/responses'; +import type Packet from '@/types/nex/packet'; + +export default class SecureConnectionProtocol { + static ID = 0xB; + static Name = 'SecureConnection'; + + static Methods = { + Register: 0x1, + RequestConnectionData: 0x2, + RequestUrls: 0x3, + RegisterEx: 0x4, + TestConnectivity: 0x5, + UpdateURLs: 0x6, + ReplaceURL: 0x7, + SendReport: 0x8 + }; + + private static handlers: Record any> = { + 0x1: SecureConnectionProtocol.Register, + 0x4: SecureConnectionProtocol.RegisterEx + }; + + static handlePacket(packet: Packet): void { + const methodID = packet.message.methodID; + + // TODO - Use Switch names when parsing Switch packets + const handler = SecureConnectionProtocol.handlers[methodID]; + + if (!handler) { + packet.message.methodName = `UnknownMethod_0x${methodID.toString(16).toUpperCase().padStart(2, '0')}`; + return; + } + + const messageDecoder = handler(packet.message); + + packet.message.parameters = new messageDecoder(packet.message); + packet.message.methodName = messageDecoder.Name; + } + + private static Register(message: RMCMessage): typeof Requests.RegisterRequest | typeof Responses.RegisterResponse { + if (message.type === RMCMessage.REQUEST) { + return Requests.RegisterRequest; + } else { + return Responses.RegisterResponse; + } + } + + private static RegisterEx(message: RMCMessage): typeof Requests.RegisterExRequest | typeof Responses.RegisterExResponse { + if (message.type === RMCMessage.REQUEST) { + return Requests.RegisterExRequest; + } else { + return Responses.RegisterExResponse; + } + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/requests/index.ts b/src/nex/protocols/secure-connection/requests/index.ts new file mode 100644 index 0000000..a0965a9 --- /dev/null +++ b/src/nex/protocols/secure-connection/requests/index.ts @@ -0,0 +1,2 @@ +export { default as RegisterRequest } from '@/nex/protocols/secure-connection/requests/register'; +export { default as RegisterExRequest } from '@/nex/protocols/secure-connection/requests/register-ex'; \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/requests/register-ex.ts b/src/nex/protocols/secure-connection/requests/register-ex.ts new file mode 100644 index 0000000..509fbe6 --- /dev/null +++ b/src/nex/protocols/secure-connection/requests/register-ex.ts @@ -0,0 +1,26 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; +import AnyDataHolder from '@/nex/types/any-data-holder'; + +export default class RegisterExRequest { + public static Name = 'RegisterEx'; + + private vecMyURLs = new List(new StationURL()); + private hCustomData = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + + this.vecMyURLs.extractFrom(stream); + this.hCustomData.extractFrom(stream); + } + + public toJSON(): Record { + return { + vecMyURLs: this.vecMyURLs, + hCustomData: this.hCustomData + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/requests/register.ts b/src/nex/protocols/secure-connection/requests/register.ts new file mode 100644 index 0000000..ae62485 --- /dev/null +++ b/src/nex/protocols/secure-connection/requests/register.ts @@ -0,0 +1,22 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; + +export default class RegisterRequest { + public static Name = 'Register'; + + private vecMyURLs = new List(new StationURL()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + + this.vecMyURLs.extractFrom(stream); + } + + public toJSON(): Record { + return { + vecMyURLs: this.vecMyURLs + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/responses/index.ts b/src/nex/protocols/secure-connection/responses/index.ts new file mode 100644 index 0000000..6e0f305 --- /dev/null +++ b/src/nex/protocols/secure-connection/responses/index.ts @@ -0,0 +1,2 @@ +export { default as RegisterResponse } from '@/nex/protocols/secure-connection/responses/register'; +export { default as RegisterExResponse } from '@/nex/protocols/secure-connection/responses/register-ex'; \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/responses/register-ex.ts b/src/nex/protocols/secure-connection/responses/register-ex.ts new file mode 100644 index 0000000..1587b6b --- /dev/null +++ b/src/nex/protocols/secure-connection/responses/register-ex.ts @@ -0,0 +1,33 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import QResult from '@/nex/types/qresult'; +import UInt32 from '@/nex/types/uint32'; +import StationURL from '@/nex/types/station-url'; + +export default class RegisterExResponse { + public static Name = 'RegisterEx'; + + private retval = new QResult(); + private pidConnectionID = new UInt32(); + private urlPublic = new StationURL(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + + this.retval.extractFrom(stream); + + // TODO - Is this handled correctly? + if (this.retval.isSuccess()) { + this.pidConnectionID.extractFrom(stream); + this.urlPublic.extractFrom(stream); + } + } + + public toJSON(): Record { + return { + retval: this.retval, + pidConnectionID: this.pidConnectionID, + urlPublic: this.urlPublic + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/responses/register.ts b/src/nex/protocols/secure-connection/responses/register.ts new file mode 100644 index 0000000..9b38c0a --- /dev/null +++ b/src/nex/protocols/secure-connection/responses/register.ts @@ -0,0 +1,33 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import QResult from '@/nex/types/qresult'; +import UInt32 from '@/nex/types/uint32'; +import StationURL from '@/nex/types/station-url'; + +export default class RegisterResponse { + public static Name = 'Register'; + + private retval = new QResult(); + private pidConnectionID = new UInt32(); + private urlPublic = new StationURL(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + + this.retval.extractFrom(stream); + + // TODO - Is this handled correctly? + if (this.retval.isSuccess()) { + this.pidConnectionID.extractFrom(stream); + this.urlPublic.extractFrom(stream); + } + } + + public toJSON(): Record { + return { + retval: this.retval, + pidConnectionID: this.pidConnectionID, + urlPublic: this.urlPublic + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/index.ts b/src/nex/protocols/ticket-granting/index.ts new file mode 100644 index 0000000..ae53e33 --- /dev/null +++ b/src/nex/protocols/ticket-granting/index.ts @@ -0,0 +1,74 @@ +import RMCMessage from '@/nex/rmc-message'; +import * as Requests from '@/nex/protocols/ticket-granting/requests'; +import * as Responses from '@/nex/protocols/ticket-granting/responses'; +import type Packet from '@/types/nex/packet'; + +export default class TicketGrantingProtocol { + static ID = 0xA; + static Name = 'TicketGranting'; + + static Methods = { + Login: 0x1, + LoginEx: 0x2, + RequestTicket: 0x3, + GetPID: 0x4, + GetName: 0x5, + LoginWithContext: 0x6 + }; + + static MethodsSwitch = { + ValidateAndRequestTicket: 0x1, + ValidateAndRequestTicketWithCustomData: 0x2, + RequestTicket: 0x3, + GetPID: 0x4, + GetName: 0x5, + ValidateAndRequestTicketWithParam: 0x6 + }; + + private static handlers: Record any> = { + 0x1: TicketGrantingProtocol.Login, + 0x2: TicketGrantingProtocol.LoginEx, + 0x3: TicketGrantingProtocol.RequestTicket + }; + + static handlePacket(packet: Packet): void { + const methodID = packet.message.methodID; + + // TODO - Use Switch names when parsing Switch packets + const handler = TicketGrantingProtocol.handlers[methodID]; + + if (!handler) { + packet.message.methodName = `UnknownMethod_0x${methodID.toString(16).toUpperCase().padStart(2, '0')}`; + return; + } + + const messageDecoder = handler(packet.message); + + packet.message.parameters = new messageDecoder(packet.message); + packet.message.methodName = messageDecoder.Name; + } + + private static Login(message: RMCMessage): typeof Requests.LoginRequest | typeof Responses.LoginResponse { + if (message.type === RMCMessage.REQUEST) { + return Requests.LoginRequest; + } else { + return Responses.LoginResponse; + } + } + + private static LoginEx(message: RMCMessage): typeof Requests.LoginExRequest | typeof Responses.LoginExResponse { + if (message.type === RMCMessage.REQUEST) { + return Requests.LoginExRequest; + } else { + return Responses.LoginExResponse; + } + } + + private static RequestTicket(message: RMCMessage): typeof Requests.RequestTicketRequest | typeof Responses.RequestTicketResponse { + if (message.type === RMCMessage.REQUEST) { + return Requests.RequestTicketRequest; + } else { + return Responses.RequestTicketResponse; + } + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/requests/index.ts b/src/nex/protocols/ticket-granting/requests/index.ts new file mode 100644 index 0000000..9660ae0 --- /dev/null +++ b/src/nex/protocols/ticket-granting/requests/index.ts @@ -0,0 +1,3 @@ +export { default as LoginRequest } from '@/nex/protocols/ticket-granting/requests/login'; +export { default as LoginExRequest } from '@/nex/protocols/ticket-granting/requests/login-ex'; +export { default as RequestTicketRequest } from '@/nex/protocols/ticket-granting/requests/request-ticket'; \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/requests/login-ex.ts b/src/nex/protocols/ticket-granting/requests/login-ex.ts new file mode 100644 index 0000000..6dd024d --- /dev/null +++ b/src/nex/protocols/ticket-granting/requests/login-ex.ts @@ -0,0 +1,25 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import RVString from '@/nex/types/string'; +import AnyDataHolder from '@/nex/types/any-data-holder'; + +export default class LoginExRequest { + public static Name = 'LoginEx'; + + private strUserName = new RVString(); + private oExtraData = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + + this.strUserName.extractFrom(stream); + this.oExtraData.extractFrom(stream); + } + + public toJSON(): Record { + return { + strUserName: this.strUserName, + oExtraData: this.oExtraData + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/requests/login.ts b/src/nex/protocols/ticket-granting/requests/login.ts new file mode 100644 index 0000000..39eb9e1 --- /dev/null +++ b/src/nex/protocols/ticket-granting/requests/login.ts @@ -0,0 +1,21 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import RVString from '@/nex/types/string'; + +export default class LoginRequest { + public static Name = 'Login'; + + private strUserName = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + + this.strUserName.extractFrom(stream); + } + + public toJSON(): Record { + return { + strUserName: this.strUserName + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/requests/request-ticket.ts b/src/nex/protocols/ticket-granting/requests/request-ticket.ts new file mode 100644 index 0000000..28edf9a --- /dev/null +++ b/src/nex/protocols/ticket-granting/requests/request-ticket.ts @@ -0,0 +1,24 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import PID from '@/nex/types/pid'; + +export default class RequestTicketRequest { + public static Name = 'RequestTicket'; + + private idSource = new PID(); + private idTarget = new PID(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + + this.idSource.extractFrom(stream); + this.idTarget.extractFrom(stream); + } + + public toJSON(): Record { + return { + idSource: this.idSource, + idTarget: this.idTarget + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/responses/index.ts b/src/nex/protocols/ticket-granting/responses/index.ts new file mode 100644 index 0000000..97c7472 --- /dev/null +++ b/src/nex/protocols/ticket-granting/responses/index.ts @@ -0,0 +1,3 @@ +export { default as LoginResponse } from '@/nex/protocols/ticket-granting/responses/login'; +export { default as LoginExResponse } from '@/nex/protocols/ticket-granting/responses/login-ex'; +export { default as RequestTicketResponse } from '@/nex/protocols/ticket-granting/responses/request-ticket'; \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/responses/login-ex.ts b/src/nex/protocols/ticket-granting/responses/login-ex.ts new file mode 100644 index 0000000..2e6d8e6 --- /dev/null +++ b/src/nex/protocols/ticket-granting/responses/login-ex.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import QResult from '@/nex/types/qresult'; +import PID from '@/nex/types/pid'; +import RVBuffer from '@/nex/types/buffer'; +import RVConnectionData from '@/nex/types/rv-connection-data'; +import RVString from '@/nex/types/string'; + +export default class LoginExResponse { + public static Name = 'LoginEx'; + + private retval = new QResult(); + private pidPrincipal = new PID(); + private pbufResponse = new RVBuffer(); + private pConnectionData = new RVConnectionData(); + private strReturnMsg = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + + this.retval.extractFrom(stream); + + // * Wiki states: + // * "If the username does not exist, the %retval% field is set to RendezVous::InvalidUsername and the other fields are left blank." + // TODO - Is this handled correctly? + if (this.retval.isSuccess()) { + this.pidPrincipal.extractFrom(stream); + this.pbufResponse.extractFrom(stream); + this.pConnectionData.extractFrom(stream); + this.strReturnMsg.extractFrom(stream); + } + } + + public toJSON(): Record { + return { + retval: this.retval, + pidPrincipal: this.pidPrincipal, + pbufResponse: this.pbufResponse, + pConnectionData: this.pConnectionData, + strReturnMsg: this.strReturnMsg.value + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/responses/login.ts b/src/nex/protocols/ticket-granting/responses/login.ts new file mode 100644 index 0000000..0e487cf --- /dev/null +++ b/src/nex/protocols/ticket-granting/responses/login.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import QResult from '@/nex/types/qresult'; +import PID from '@/nex/types/pid'; +import RVBuffer from '@/nex/types/buffer'; +import RVConnectionData from '@/nex/types/rv-connection-data'; +import RVString from '@/nex/types/string'; + +export default class LoginResponse { + public static Name = 'Login'; + + private retval = new QResult(); + private pidPrincipal = new PID(); + private pbufResponse = new RVBuffer(); + private pConnectionData = new RVConnectionData(); + private strReturnMsg = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + + this.retval.extractFrom(stream); + + // * Wiki states: + // * "If the username does not exist, the %retval% field is set to RendezVous::InvalidUsername and the other fields are left blank." + // TODO - Is this handled correctly? + if (this.retval.isSuccess()) { + this.pidPrincipal.extractFrom(stream); + this.pbufResponse.extractFrom(stream); + this.pConnectionData.extractFrom(stream); + this.strReturnMsg.extractFrom(stream); + } + } + + public toJSON(): Record { + return { + retval: this.retval, + pidPrincipal: this.pidPrincipal, + pbufResponse: this.pbufResponse, + pConnectionData: this.pConnectionData, + strReturnMsg: this.strReturnMsg.value + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/responses/request-ticket.ts b/src/nex/protocols/ticket-granting/responses/request-ticket.ts new file mode 100644 index 0000000..ec3190e --- /dev/null +++ b/src/nex/protocols/ticket-granting/responses/request-ticket.ts @@ -0,0 +1,40 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import QResult from '@/nex/types/qresult'; +import RVBuffer from '@/nex/types/buffer'; +import RVString from '@/nex/types/string'; + +export default class RequestTicketResponse { + public static Name = 'RequestTicket'; + + private retval = new QResult(); + private bufResponse = new RVBuffer(); + private pSourceKey = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + + this.retval.extractFrom(stream); + + // * Wiki states: + // * "If the source or target pid is invalid, the %retval% field is set to Core::AccessDenied and the ticket is empty." + // TODO - Is this handled correctly? + if (this.retval.isSuccess()) { + this.bufResponse.extractFrom(stream); + + // * Only on the Switch + // TODO - Is this a good enough check? + if (stream.hasDataLeft()) { + this.pSourceKey.extractFrom(stream); + } + } + } + + public toJSON(): Record { + return { + retval: this.retval, + bufResponse: this.bufResponse, + pSourceKey: this.pSourceKey.value + }; + } +} \ No newline at end of file diff --git a/src/nex/prudp-packet.ts b/src/nex/prudp-packet.ts new file mode 100644 index 0000000..ad2d9a4 --- /dev/null +++ b/src/nex/prudp-packet.ts @@ -0,0 +1,148 @@ +import ByteStream from '@/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import Connection from '@/nex/connection'; + +export default class PRUDPPacket { + public readonly version: number; + + public fromClientToServer: boolean; + public fromServerToClient: boolean; + + public sourceAddress: string; + public sourcePort: number; + public destinationAddress: string; + public destinationPort: number; + + public sourceStreamID: number; + public sourceStreamType: number; + public destinationStreamID: number; + public destinationStreamType: number; + public flags: number; + public type: number; + public sessionID: number; + public signature: Buffer; + public sequenceID: number; + public connectionSignature: Buffer; + public fragmentID: number; + public substreamID: number; + public payload: Buffer; + public decryptedPayload: Buffer; + public defragmentedPayload: Buffer; + public connection: Connection; + public message: RMCMessage; + + protected stream: ByteStream; + + static FLAGS = { + ACK: 0x001, + RELIABLE: 0x002, + NEED_ACK: 0x004, + HAS_SIZE: 0x008, + MULTI_ACK: 0x200, + }; + + static TYPES = { + SYN: 0, + CONNECT: 1, + DATA: 2, + DISCONNECT: 3, + PING: 4, + USER: 5, + }; + + constructor(stream: ByteStream) { + this.stream = stream; + } + + protected validateVirtualPorts(): void { + if (this.sourceStreamType === 0 || this.sourceStreamType > 11) { + throw new Error('Invalid source stream type'); + } + + if (this.sourceStreamID === 0) { + throw new Error('Invalid source stream ID'); + } + + if (this.destinationStreamType === 0 || this.destinationStreamType > 11) { + throw new Error('Invalid destination stream type'); + } + + if (this.destinationStreamID === 0) { + throw new Error('Invalid source stream ID'); + } + + if (this.sourceStreamID === this.destinationStreamID) { + // * Likely a Quazal Net-Z packet + // ! NOTE - This WILL catch valid connections if the client uses 14 connections (making the server and client both use port 1) + throw new Error('Source and destination virtual ports are the same'); + } + + if (this.sourceStreamType === 1) { + throw new Error('Source stream type is DO'); + } + + if (this.sourceStreamType === 5) { + throw new Error('Source stream type is NAT'); + } + + if (this.destinationStreamType === 1) { + throw new Error('Destination stream type is DO'); + } + + if (this.destinationStreamType === 5) { + throw new Error('Destination stream type is NAT'); + } + } + + private isType(type: number): boolean { + return this.type === type; + } + + private hasFlag(flag: number): boolean { + return (this.flags & flag) !== 0; + } + + public isTypeSyn(): boolean { + return this.isType(PRUDPPacket.TYPES.SYN); + } + + public isTypeConnect(): boolean { + return this.isType(PRUDPPacket.TYPES.CONNECT); + } + + public isTypeData(): boolean { + return this.isType(PRUDPPacket.TYPES.DATA); + } + + public isTypeDisconnect(): boolean { + return this.isType(PRUDPPacket.TYPES.DISCONNECT); + } + + public isTypePing(): boolean { + return this.isType(PRUDPPacket.TYPES.PING); + } + + public isTypeUser(): boolean { + return this.isType(PRUDPPacket.TYPES.USER); + } + + public hasFlagAck(): boolean { + return this.hasFlag(PRUDPPacket.FLAGS.ACK); + } + + public hasFlagReliable(): boolean { + return this.hasFlag(PRUDPPacket.FLAGS.RELIABLE); + } + + public hasFlagNeedAck(): boolean { + return this.hasFlag(PRUDPPacket.FLAGS.NEED_ACK); + } + + public hasFlagHasSize(): boolean { + return this.hasFlag(PRUDPPacket.FLAGS.HAS_SIZE); + } + + public hasFlagMultiAck(): boolean { + return this.hasFlag(PRUDPPacket.FLAGS.MULTI_ACK); + } +} \ No newline at end of file diff --git a/src/nex/prudp-packetv0.ts b/src/nex/prudp-packetv0.ts new file mode 100644 index 0000000..bfb751e --- /dev/null +++ b/src/nex/prudp-packetv0.ts @@ -0,0 +1,96 @@ +import ByteStream from '@/byte-stream'; +import PRUDPPacket from '@/nex/prudp-packet'; + +export default class PRUDPPacketV0 extends PRUDPPacket { + public readonly version = 0; + + private _checksum: number; + private packetData: Buffer; // * Used for the checksum calculation + + public get checksum(): number { + return this._checksum; + } + + constructor(stream: ByteStream) { + super(stream); + + this.substreamID = 0; + this.parse(); + } + + private parse(): void { + const start = this.stream.pos(); + + const source = this.stream.readUInt8(); + const destination = this.stream.readUInt8(); + + this.sourceStreamType = source >> 4; + this.sourceStreamID = source & 0xF; + this.destinationStreamType = destination >> 4; + this.destinationStreamID = destination & 0xF; + + this.validateVirtualPorts(); + + // TODO - Quazal encoding? How do we tell the decoder the size BEFORE decoding? + const typeAndFlags = this.stream.readUInt16LE(); + + this.flags = typeAndFlags >> 4; + this.type = typeAndFlags & 0xF; + this.sessionID = this.stream.readUInt8(); + this.signature = this.stream.readBytes(0x4); + this.sequenceID = this.stream.readUInt16LE(); + + if (this.isTypeSyn() || this.isTypeConnect()) { + this.connectionSignature = this.stream.readBytes(0x4); + } + + if (this.isTypeData()) { + this.fragmentID = this.stream.readUInt8(); + } + + let payloadSize = 0; + + if (this.hasFlagHasSize()) { + payloadSize = this.stream.readUInt16LE(); + } else { + payloadSize = this.stream.remaining() - 1; + } + + if (payloadSize > (this.stream.remaining() - 1)) { + throw new Error(`Packet payload too large. Payload space left is ${this.stream.remaining() - 1}, got ${payloadSize}`); + } + + this.payload = this.stream.readBytes(payloadSize); + + const end = this.stream.pos(); + + this.stream.seek(start); + this.packetData = this.stream.read(end-start); + + // TODO - Quazal encoding? How do we tell the decoder the size BEFORE decoding? + // TODO - Validate this + this._checksum = this.stream.readUInt8(); + } + + public calculateChecksum(key: string): number { + let checksum = Buffer.from(key).reduce((sum, byte) => sum + byte, 0); + + const data = this.packetData; + + const numWords = Math.floor(data.length / 4); + const words = []; + + for (let i = 0; i < numWords; i++) { + words.push(data.readUInt32LE(i * 4)); + } + + const temp = words.reduce((sum, byte) => sum + byte, 0) >>> 0; // * Truncate to 32-bit integer + + const buffer = Buffer.alloc(4); + buffer.writeUInt32LE(temp); + + checksum = checksum + data.subarray(data.length & ~3).reduce((sum, byte) => sum + byte, 0) + buffer.reduce((sum, byte) => sum + byte, 0); + + return checksum & 0xFF; + } +} \ No newline at end of file diff --git a/src/nex/prudp-packetv1.ts b/src/nex/prudp-packetv1.ts new file mode 100644 index 0000000..6cd91e3 --- /dev/null +++ b/src/nex/prudp-packetv1.ts @@ -0,0 +1,161 @@ +import crypto from 'node:crypto'; +import ByteStream from '@/byte-stream'; +import PRUDPPacket from '@/nex/prudp-packet'; + +export default class PRUDPPacketV1 extends PRUDPPacket { + public readonly version = 1; + + private optionsLength: number; + private payloadLength: number; + private headerBytes: Buffer; // * Used for the signature calculation + private optionsBytes: Buffer; // * Used for the signature calculation + + static Magic = Buffer.from([0xEA, 0xD0]); + + constructor(stream: ByteStream) { + super(stream); + + this.substreamID = 0; + this.parse(); + } + + private parse(): void { + const magic = this.stream.readBytes(0x2); + + if (!magic.equals(PRUDPPacketV1.Magic)) { + throw new Error('Invalid PRUDPv1 magic'); + } + + this.parseHeader(); + this.signature = this.stream.readBytes(0x10); + this.parseOptions(); + this.payload = this.stream.readBytes(this.payloadLength); + } + + private parseHeader(): void { + this.headerBytes = this.stream.read(0xC); + this.stream.skip(-0xC); + + const version = this.stream.readUInt8(); + + if (version !== 1) { + throw new Error('Invalid PRUDPv1 version'); + } + + this.optionsLength = this.stream.readUInt8(); + this.payloadLength = this.stream.readUInt16LE(); + + const source = this.stream.readUInt8(); + const destination = this.stream.readUInt8(); + + this.sourceStreamType = source >> 4; + this.sourceStreamID = source & 0xF; + this.destinationStreamType = destination >> 4; + this.destinationStreamID = destination & 0xF; + + this.validateVirtualPorts(); + + // TODO - Quazal encoding? How do we tell the decoder the size BEFORE decoding? + const typeAndFlags = this.stream.readUInt16LE(); + + this.flags = typeAndFlags >> 4; + this.type = typeAndFlags & 0xF; + + this.sessionID = this.stream.readUInt8(); + this.substreamID = this.stream.readUInt8(); + this.sequenceID = this.stream.readUInt16LE(); + } + + private parseOptions(): void { + this.optionsBytes = this.stream.read(this.optionsLength); + this.stream.skip(-this.optionsLength); + + const optionsStream = new ByteStream(this.stream.readBytes(this.optionsLength)); + + while (optionsStream.hasDataLeft()) { + const optionID = optionsStream.readUInt8(); + const optionSize = optionsStream.readUInt8(); + + if (optionID > 4) { + throw new Error('Invalid PRUDPv1 option ID'); + } + + if (optionID == 0 || optionID == 1 || optionID == 4) { + if (!this.isTypeSyn() && !this.isTypeConnect()) { + throw new Error('Invalid PRUDPv1 option ID'); + } + } + + if (optionID == 2 && !this.isTypeData()) { + throw new Error('Invalid PRUDPv1 option ID'); + } + + if (optionID == 3 && !this.isTypeConnect()) { + throw new Error('Invalid PRUDPv1 option ID'); + } + + if (optionID === 0) { + if (optionSize !== 4) { + throw new Error('Invalid PRUDPv1 option ID'); + } + + // * Supported functions. Not needed here + optionsStream.skip(optionSize); + } + + if (optionID === 1) { + if (optionSize !== 16) { + throw new Error('Invalid PRUDPv1 option ID'); + } + + this.connectionSignature = optionsStream.readBytes(optionSize); + } + + if (optionID === 2) { + if (optionSize !== 1) { + throw new Error('Invalid PRUDPv1 option ID'); + } + + this.fragmentID = optionsStream.readUInt8(); + } + + if (optionID === 3) { + if (optionSize !== 2) { + throw new Error('Invalid PRUDPv1 option ID'); + } + + // * Initial sequence id for unreliable data packets. Not needed here + optionsStream.skip(optionSize); + } + + if (optionID === 4) { + if (optionSize !== 1) { + throw new Error('Invalid PRUDPv1 option ID'); + } + + // * Maximum substream ID. Not needed here + optionsStream.skip(optionSize); + } + } + } + + public calculateSignature(accessKey: string, sessionKey: Buffer, connectionSignature: Buffer): Buffer { + const accessKeyBytes = Buffer.from(accessKey); + + const accessKeySum = accessKeyBytes.reduce((sum, byte) => sum + byte, 0); + const accessKeySumBytes = Buffer.alloc(4); + accessKeySumBytes.writeUInt32LE(accessKeySum, 0); + + const key = crypto.createHash('md5').update(accessKeyBytes).digest(); + const mac = crypto.createHmac('md5', key); + + mac.update(this.headerBytes.subarray(4)); + mac.update(sessionKey); + mac.update(accessKeySumBytes); + mac.update(connectionSignature); + mac.update(this.optionsBytes); + mac.update(this.payload); + + return mac.digest(); + } +} \ No newline at end of file diff --git a/src/nex/raw-rmc-packet.ts b/src/nex/raw-rmc-packet.ts new file mode 100644 index 0000000..cc0223f --- /dev/null +++ b/src/nex/raw-rmc-packet.ts @@ -0,0 +1,48 @@ +import ByteStream from '@/byte-stream'; +import PRUDPPacket from '@/nex/prudp-packet'; + +export default class RawRMCPacket extends PRUDPPacket { + public readonly version = -1; + + public titleID: string; + + constructor(stream: ByteStream) { + super(stream); + + this.parse(); + } + + private parse(): void { + const version = this.stream.readUInt8(); + + if (version !== 1) { + throw new Error('Bad HokakuCTR version'); + } + + this.titleID = this.stream.readUInt64LE().toString(16).toUpperCase().padStart(16, '0'); + this.flags = this.stream.readUInt8(); + this.payload = this.stream.readRest(); + + if (this.payload[0x4] === 0) { + // * Invalid protocol ID. Likely a Net-Z packet + throw new Error('Invalid raw RMC packet'); + } + + this.type = PRUDPPacket.TYPES.DATA; // TODO - Is this a good assumption? + this.fragmentID = 0; // TODO - Is this a good assumption? + this.substreamID = 0; // TODO - Is this a good assumption? + + this.fromServerToClient = (this.flags & 0b00000001) !== 0; + this.fromClientToServer = !this.fromServerToClient; + + this.sourceAddress = this.fromServerToClient ? 'server' : 'client'; + this.sourcePort = -1; + this.sourceStreamType = -1; + this.sourceStreamID = -1; + + this.destinationAddress = this.fromServerToClient ? 'client' : 'server'; + this.destinationPort = -1; + this.destinationStreamType = -1; + this.destinationStreamID = -1; + } +} \ No newline at end of file diff --git a/src/nex/rmc-message.ts b/src/nex/rmc-message.ts new file mode 100644 index 0000000..674aba7 --- /dev/null +++ b/src/nex/rmc-message.ts @@ -0,0 +1,118 @@ +import ByteStream from '@/byte-stream'; +import QResult from '@/nex/types/qresult'; +import type Connection from '@/nex/connection'; + +export default class RMCMessage { + static readonly REQUEST = 0; + static readonly RESPONSE = 1; + + private _type: 0 | 1; + private _protocolID: number; + private _extendedProtocolID?: number; + private _methodID: number; + private _callID: number; + private _error?: QResult; + private _parametersData: Buffer; + + public parameters?: any; + public methodName: string; + public protocolName: string; + public connection: Connection; + + get type(): 0 | 1 { + return this._type; + } + + get protocolID(): number { + return this._protocolID; + } + + get extendedProtocolID(): number | undefined { + return this._extendedProtocolID; + } + + get methodID(): number { + return this._methodID; + } + + get callID(): number { + return this._callID; + } + + get error(): QResult | undefined { + return this._error; + } + + get parametersData(): Buffer { + return this._parametersData; + } + + constructor(data: Buffer) { + this.parse(data); + } + + private parse(data: Buffer): void { + // TODO - Support verbose RMC like seen in WATCH_DOGS + + const stream = new ByteStream(data); + + const size = stream.readUInt32LE(); + const message = stream.readBytes(size); + + const messageStream = new ByteStream(message); + + this._protocolID = messageStream.readUInt8(); + + if (this._protocolID & 0x80) { + this._type = RMCMessage.REQUEST; + + this._protocolID = this._protocolID & ~0x80; // * Get original protocol ID + } else { + this._type = RMCMessage.RESPONSE; + } + + if (this._protocolID === 0x7F) { + this._extendedProtocolID = messageStream.readUInt16LE(); + } + + if (this._type === RMCMessage.REQUEST) { + this.parseRequest(messageStream); + } else { + this.parseResponse(messageStream); + } + } + + private parseRequest(stream: ByteStream): void { + this._callID = stream.readUInt32LE(); + this._methodID = stream.readUInt32LE(); + this._parametersData = stream.readRest(); + } + + private parseResponse(stream: ByteStream): void { + const success = stream.readBoolean(); + + if (success) { + this._callID = stream.readUInt32LE(); + this._methodID = stream.readUInt32LE() & ~0x8000; + this._parametersData = stream.readRest(); + } else { + this._error = new QResult(); + this._error.extractFrom(stream); + this._callID = stream.readUInt32LE(); + } + } + + public toJSON(): Record { + const json: Record = { + type: this._type, + protocolID: this._protocolID, + protocolName: this.protocolName, + methodID: this._methodID, + methodName: this.methodName, + callID: this._callID, + parameters: this.parameters + }; + + return json; + } +} \ No newline at end of file diff --git a/src/nex/session.ts b/src/nex/session.ts new file mode 100644 index 0000000..fd019eb --- /dev/null +++ b/src/nex/session.ts @@ -0,0 +1,297 @@ +import EventEmitter from 'node:events'; +import path from 'node:path'; +import fs from 'fs-extra'; +import ByteStream from '@/byte-stream'; +import PCAPParser from '@/pcap-parser'; +import PCAPNGParser from '@/pcap-parser'; +import Connection from '@/nex/connection'; +import PRUDPPacketV1 from '@/nex/prudp-packetv1'; +import PRUDPPacketV0 from '@/nex/prudp-packetv0'; +import RawRMCPacket from '@/nex/raw-rmc-packet'; +import type Frame from '@/types/frame'; +import type Packet from '@/types/nex/packet'; +import type UDPPacket from '@/types/nex/udp-packet'; + +function int2ip(int: number): string { + return `${int >>> 24}.${int >> 16 & 255}.${int >> 8 & 255}.${int & 255}`; +} + +// * Parses network dumps for NEX/Rendez-Vous connections +export default class Session extends EventEmitter { + private connections: Connection[] = []; + private rawRMCMode = false; + + constructor() { + super(); + } + + public parse(capturePath: string): void { + const extension = path.extname(capturePath); + + if (extension !== '.pcapng' && extension !== '.pcap') { + throw new Error(`Invalid file type. Got ${extension}, expected .pcapng or .pcap`); + } + + const captureData = fs.readFileSync(capturePath); + let parser; + + const magic = captureData.readUInt32LE(); + + if (magic === 0xA1B2C3D4 || magic === 0xD4C3B2A1) { + parser = new PCAPParser(captureData); + } else if (magic === 0x0A0D0D0A) { + parser = new PCAPNGParser(captureData); + } else { + throw new Error('Invalid capture'); + } + + for (const packet of parser.packets()) { + this.handlePacket(packet); + } + + this.emit('finished', this.connections); + } + + private handlePacket(frame: Frame): void { + // * HokakuCTR produces dumps whose payloads are: + // * - u8 Revision (1) + // * - u64 Title ID + // * By checking if the first byte is a supported + // * revision and that the following u64 is a 3DS + // * title we can be reasonably sure the dump is + // * a HokakuCTR dump. + // * We only need the first 3 bytes of the u64 + if (!this.rawRMCMode && frame.data[0] === 1 && (frame.data.readBigUInt64LE(1) & 0xFFFFFF0000000000n) === 0x0004000000000000n) { + this.rawRMCMode = true; + } + + const packets = this.filterValidPackets(frame); + + for (const packet of packets) { + this.processPacket(packet); + } + } + + private filterValidPackets(frame: Frame): Packet[] { + // * Not all packets in the network dumps are packets we care about + const packets: Packet[] = []; + + try { + if (this.rawRMCMode) { + // * Raw RMC packets only include one packet per frame + packets.push(new RawRMCPacket(new ByteStream(frame.data))); + } else { + const udpPacket = this.parseUDPPacket(frame.data); + + if (!udpPacket) { + return packets; + } + + const stream = new ByteStream(udpPacket.payload); + + // * Some PRUDP packets are bundled together. Need to split them apart + while (stream.hasDataLeft()) { + let packet: Packet; + + const magic = stream.readBytes(0x2); + stream.skip(-0x2); // * Skip back to realign the stream position + + if (magic.equals(PRUDPPacketV1.Magic)) { + packet = new PRUDPPacketV1(stream); + } else { + // * Assume packet is v0 and just Try It + // * + // * THIS IS *EXPECTED* TO FAIL OFTEN! + // * PRUDPv0 DOES NOT HAVE A MAGIC LIKE v1! + // * OUR BEST OPTION IS TO JUST GUESS + + packet = new PRUDPPacketV0(stream); + } + + packet.sourceAddress = udpPacket.source; + packet.sourcePort = udpPacket.sourcePort; + packet.destinationAddress = udpPacket.destination; + packet.destinationPort = udpPacket.destinationPort; + + packets.push(packet); + } + } + } catch { + // * Eat errors + } + + return packets; + } + + private parseUDPPacket(data: Buffer): UDPPacket | undefined { + const stream = new ByteStream(data); + + const versionAndHeaderLength = stream.readUInt8(); + const version = (versionAndHeaderLength >> 4) & 0x0F; + + // * All packets we care about are + // * assumed to be IPv4 + if (version !== 4) { + return; + } + + const headerLength = (versionAndHeaderLength & 0x0F) * 4; + + stream.skip(1); // * Service type + const totalLength = stream.readUInt16BE(); + stream.skip(2); // * Identification + stream.skip(2); // * Flags and fragment offset. Fragment offset is the last 13 bits (& 0x1FFF) + stream.skip(1); // * Time to live + const protocol = stream.readUInt8(); + stream.skip(2); // * Checksum + + const source = int2ip(stream.readUInt32BE()); + const destination = int2ip(stream.readUInt32BE()); + + // TODO - Add this back with the new offsets + //if (frame.subarray(17, 20).equals(XID_MAGIC)) { + // return; + //} + + // * UDP protocol + if (protocol !== 0x11) { + return; + } + + const udpLength = totalLength - headerLength; + const udpStream = new ByteStream(stream.readBytes(udpLength)); + + // * Parse UDP header + const sourcePort = udpStream.readUInt16BE(); + const destinationPort = udpStream.readUInt16BE(); + const udpPacketLength = udpStream.readUInt16BE(); + + if (udpPacketLength !== udpLength) { + throw new Error(`Got bad UDP packet length. Expected ${udpLength}, got ${udpPacketLength}`); + } + + udpStream.skip(0x2); // * Checksum + + const payload = udpStream.readBytes(udpLength - 0x8); + + return { + source, + destination, + sourcePort, + destinationPort, + payload + }; + } + + private processPacket(packet: Packet): void { + let connection = this.findConnection(packet); + + if (!connection) { + if (packet.version !== -1 && !packet.isTypeSyn()) { + // * If we find a new connection on a packet besides the SYN, + // * assume only part of the connection is present and ignore + return; + } + + if (packet.version !== -1 && packet.isTypeSyn() && packet.hasFlagAck()) { + // * If the packet is a SYN but is the *ACK* of the SYN, + // * assume only part of the connection is present and ignore + return; + } + + connection = new Connection(); + + connection.clientAddress = packet.sourceAddress; + connection.clientPort = packet.sourcePort; + connection.serverAddress = packet.destinationAddress; + connection.serverPort = packet.destinationPort; + + connection.clientStreamType = packet.sourceStreamType; + connection.clientStreamID = packet.sourceStreamID; + connection.serverStreamType = packet.destinationStreamType; + connection.serverStreamID = packet.destinationStreamID; + + // TODO - Link special secure station as well, not just the main secure station + for (const otherConnection of this.connections) { + if (otherConnection.mainSecureStation && otherConnection.mainSecureStationTicket) { + const address = otherConnection.mainSecureStation.getParam('address'); + const port = Number(otherConnection.mainSecureStation.getParam('port')); + const streamType = Number(otherConnection.mainSecureStation.getParam('stream')); + const streamID = Number(otherConnection.mainSecureStation.getParam('sid')); + + if (isNaN(port)) { + continue; + } + + if (isNaN(streamType)) { + continue; + } + + if (isNaN(streamID)) { + continue; + } + + if (connection.serverAddress !== address) { + continue; + } + + if (connection.serverPort !== port) { + continue; + } + + if (connection.serverStreamType !== streamType) { + continue; + } + + if (connection.serverStreamID !== streamID) { + continue; + } + + connection.title = otherConnection.title; + connection.cipherKey = otherConnection.mainSecureStationTicket.sessionKey; + connection.sessionKey = otherConnection.mainSecureStationTicket.sessionKey; + } + } + + this.connections.push(connection); + } + + packet.connection = connection; + + connection.processPacket(packet); + } + + private findConnection(packet: Packet): Connection | undefined { + return this.connections.find(connection => { + if ( + connection.clientAddress === packet.sourceAddress && + connection.clientPort === packet.sourcePort && + connection.serverAddress === packet.destinationAddress && + connection.serverPort === packet.destinationPort && + connection.clientStreamType === packet.sourceStreamType && + connection.clientStreamID === packet.sourceStreamID && + connection.serverStreamType === packet.destinationStreamType && + connection.serverStreamID === packet.destinationStreamID + ) { + packet.fromClientToServer = true; + packet.fromServerToClient = false; + return connection; + } + + if ( + connection.clientAddress === packet.destinationAddress && + connection.clientPort === packet.destinationPort && + connection.serverAddress === packet.sourceAddress && + connection.serverPort === packet.sourcePort && + connection.clientStreamType === packet.destinationStreamType && + connection.clientStreamID === packet.destinationStreamID && + connection.serverStreamType === packet.sourceStreamType && + connection.serverStreamID === packet.sourceStreamID + ) { + packet.fromClientToServer = false; + packet.fromServerToClient = true; + return connection; + } + }); + } +} \ No newline at end of file diff --git a/src/nex/substream.ts b/src/nex/substream.ts new file mode 100644 index 0000000..12864fd --- /dev/null +++ b/src/nex/substream.ts @@ -0,0 +1,90 @@ +import RC4Stream from '@/rc4'; +import Counter from '@/nex/counter'; +import type Packet from '@/types/nex/packet'; + +export default class Substream { + private pendingClientToServerPackets: Record = {}; + private pendingservertoClientPackets: Record = {}; + private clientToServerSequenceIDCounter = new Counter(1); + private servertoClientSequenceIDCounter = new Counter(1); + private clientToServerFragmentedPayload = Buffer.alloc(0); + private servertoClientFragmentedPayload = Buffer.alloc(0); + + public clientToServerSeenPackets: Packet[] = []; + public servertoClientSeenPackets: Packet[] = []; + + public clientToServerCipher: RC4Stream; + public servertoClientCipher: RC4Stream; + + public setKey(key: Buffer | string): void { + // TODO - Support more than just RC4 + this.clientToServerCipher = new RC4Stream(key); + this.servertoClientCipher = new RC4Stream(key); + } + + public update(packet: Packet): Packet[] { + // * Keep track of the packet order and reorder them if need be + const packets: Packet[] = []; + const pendingPackets = packet.fromClientToServer ? this.pendingClientToServerPackets : this.pendingservertoClientPackets; + const sequenceIDCounter = packet.fromClientToServer ? this.clientToServerSequenceIDCounter : this.servertoClientSequenceIDCounter; + + if (!(packet.sequenceID < sequenceIDCounter.value || pendingPackets[packet.sequenceID])) { + pendingPackets[packet.sequenceID] = packet; + + while (pendingPackets[sequenceIDCounter.value]) { + packets.push(pendingPackets[sequenceIDCounter.value]); + + delete pendingPackets[sequenceIDCounter.value]; + + sequenceIDCounter.next(); + } + } + + return packets; + } + + public addFragment(packet: Packet): Buffer { + const seenPackets = packet.fromClientToServer ? this.clientToServerSeenPackets : this.servertoClientSeenPackets; + const fragmentedPayload = packet.fromClientToServer ? this.clientToServerFragmentedPayload : this.servertoClientFragmentedPayload; + const seenPacket = seenPackets.findIndex(({ sequenceID }) => packet.sequenceID === sequenceID); + + if (seenPacket !== -1) { + // * Already seen packet, ignore it + return fragmentedPayload; + } + + const cipher = packet.fromClientToServer ? this.clientToServerCipher : this.servertoClientCipher; + let payload = packet.payload; + + // * Raw RMC packets and PRUDP Lite do not encrypt payloads + if (packet.version === 0 || packet.version === 1) { + payload = cipher.update(payload); + } + + packet.decryptedPayload = payload; + + payload = Buffer.concat([ + fragmentedPayload, + payload, + ]); + + seenPackets.push(packet); + + // TODO - This is ugly + if (packet.fragmentID === 0) { + if (packet.fromClientToServer) { + this.clientToServerFragmentedPayload = Buffer.alloc(0); + } else { + this.servertoClientFragmentedPayload = Buffer.alloc(0); + } + } else { + if (packet.fromClientToServer) { + this.clientToServerFragmentedPayload = payload; + } else { + this.servertoClientFragmentedPayload = payload; + } + } + + return payload; + } +} \ No newline at end of file diff --git a/src/nex/titles.json b/src/nex/titles.json new file mode 100644 index 0000000..ccd0e94 --- /dev/null +++ b/src/nex/titles.json @@ -0,0 +1,2273 @@ +[ + { + "name": "Friends (Nintendo)", + "game_server_id": "", + "access_key": "ridfebb9", + "library_versions": { + "main": "1.0.0", + "ranking": "1.0.0", + "datastore": "1.0.0", + "match_making": "1.0.0", + "messaging": "1.0.0", + "utility": "1.0.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 16, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004013000003202", + "000500301001500A", + "000500301001510A", + "000500301001520A" + ] + }, + { + "name": "Angry Birds Star Wars 3DS", + "game_server_id": "", + "access_key": "fbae7416", + "library_versions": { + "main": "3.2.1", + "ranking": "3.2.1", + "datastore": "3.2.1", + "match_making": "3.2.1", + "messaging": "3.2.1", + "utility": "3.2.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000000F2200", + "00040000000F7A00" + ] + }, + { + "name": "Angry Birds Trilogy 3DS", + "game_server_id": "", + "access_key": "ac4fbf0d", + "library_versions": { + "main": "2.7.2", + "ranking": "2.7.2", + "datastore": "2.7.2", + "match_making": "2.7.2", + "messaging": "2.7.2", + "utility": "2.7.2" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000000AE200", + "00040000000AF400" + ] + }, + { + "name": "Worcle Worlds", + "game_server_id": "", + "access_key": "d373e4dc", + "library_versions": { + "main": "3.10.1", + "ranking": "3.10.1", + "datastore": "3.10.1", + "match_making": "3.10.1", + "messaging": "3.10.1", + "utility": "3.10.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000187400", + "0004000000187300" + ] + }, + { + "name": "sushi", + "game_server_id": "", + "access_key": "06fb3395", + "library_versions": { + "main": "4.3.1", + "ranking": "4.3.1", + "datastore": "4.3.1", + "match_making": "4.3.1", + "messaging": "4.3.1", + "utility": "4.3.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000001C1C00", + "00040000001C1D00" + ] + }, + { + "name": "Animal Crossing: New Leaf", + "game_server_id": "", + "access_key": "d6f08b40", + "library_versions": { + "main": "3.10.1", + "ranking": "3.10.1", + "datastore": "3.10.1", + "match_making": "3.10.1", + "messaging": "3.10.1", + "utility": "3.10.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000086300", + "0004000000086400", + "0004000000198E00", + "0004000000198F00", + "0004000000199000" + ] + }, + { + "name": "Animal Crossing Plaza", + "game_server_id": "", + "access_key": "7b9b09cb", + "library_versions": { + "main": "3.5.1", + "ranking": "3.5.1", + "datastore": "3.5.1", + "match_making": "3.5.1", + "messaging": "3.5.1", + "utility": "3.5.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010145600" + ] + }, + { + "name": "Axiom Verge", + "game_server_id": "", + "access_key": "24e0a63b", + "library_versions": { + "main": "3.10.0", + "ranking": "3.10.0", + "datastore": "3.10.0", + "match_making": "3.10.0", + "messaging": "3.10.0", + "utility": "3.10.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00050000101F7900", + "0005000010200800" + ] + }, + { + "name": "Badge Arcade", + "game_server_id": "", + "access_key": "82d5962d", + "library_versions": { + "main": "3.7.3", + "ranking": "3.7.3", + "datastore": "3.7.3", + "match_making": "3.7.3", + "messaging": "3.7.3", + "utility": "3.7.3" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000153500", + "0004000000153600" + ] + }, + { + "name": "BIOHAZARD REVELATIONS UE", + "game_server_id": "", + "access_key": "59d539a9", + "library_versions": { + "main": "3.2.1", + "ranking": "3.2.1", + "datastore": "3.2.1", + "match_making": "3.2.1", + "messaging": "3.2.1", + "utility": "3.2.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010113100" + ] + }, + { + "name": "Devil's Third", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.6.1", + "ranking": "3.6.1", + "datastore": "3.6.1", + "match_making": "3.6.1", + "messaging": "3.6.1", + "utility": "3.6.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010138F00", + "0005000010177600", + "0005000010177700", + "0005000010197D00" + ] + }, + { + "name": "Disney INFINITY", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.5.2", + "ranking": "3.5.2", + "datastore": "3.5.2", + "match_making": "3.5.2", + "messaging": "3.5.2", + "utility": "3.5.2" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010132900", + "0005000010136F00", + "0005000010137000", + "000500001015A300" + ] + }, + { + "name": "Disney Infinity [2.0]", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.5.2", + "ranking": "3.5.2", + "datastore": "3.5.2", + "match_making": "3.5.2", + "messaging": "3.5.2", + "utility": "3.5.2" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001016DC00", + "0005000010188C00", + "0005000010188D00" + ] + }, + { + "name": "DISNEY INFINITY 3.0", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.9.1", + "ranking": "3.9.1", + "datastore": "3.9.1", + "match_making": "3.9.1", + "messaging": "3.9.1", + "utility": "3.9.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00050000101AC900", + "00050000101B3D00", + "00050000101B3E00", + "00050000101DDC00" + ] + }, + { + "name": "DKC: Tropical Freeze", + "game_server_id": "", + "access_key": "7fcf384a", + "library_versions": { + "main": "3.4.0", + "ranking": "3.4.0", + "datastore": "3.4.0", + "match_making": "3.4.0", + "messaging": "3.4.0", + "utility": "3.4.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010137F00", + "0005000010138300", + "0005000010144800" + ] + }, + { + "name": "DuckTales: Remastered", + "game_server_id": "", + "access_key": "1294a96c", + "library_versions": { + "main": "3.3.0", + "ranking": "3.3.0", + "datastore": "3.3.0", + "match_making": "3.3.0", + "messaging": "3.3.0", + "utility": "3.3.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010129000", + "0005000010129200" + ] + }, + { + "name": "FAST Racing NEO", + "game_server_id": "", + "access_key": "811aa39f", + "library_versions": { + "main": "3.9.1", + "ranking": "3.9.1", + "datastore": "3.9.1", + "match_making": "3.9.1", + "messaging": "3.9.1", + "utility": "3.9.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001012F000", + "00050000101D6000", + "00050000101E4100", + "00050000101FED00" + ] + }, + { + "name": "FotNS: Ken's Rage 2", + "game_server_id": "", + "access_key": "9994e29c", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010116600", + "000500001012B800", + "000500001012B900" + ] + }, + { + "name": "Game Party", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001010E400", + "000500001010FF00" + ] + }, + { + "name": "Hyrule Warriors", + "game_server_id": "", + "access_key": "7fcc1f7c", + "library_versions": { + "main": "3.8.0", + "ranking": "3.8.0", + "datastore": "3.8.0", + "match_making": "3.8.0", + "messaging": "3.8.0", + "utility": "3.8.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001017CD00", + "000500001017D800", + "000500001017D900" + ] + }, + { + "name": "Injustice: Gods Among Us", + "game_server_id": "", + "access_key": "65e9f4d6", + "library_versions": { + "main": "3.2.1", + "ranking": "3.2.1", + "datastore": "3.2.1", + "match_making": "3.2.1", + "messaging": "3.2.1", + "utility": "3.2.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010111700", + "0005000010111A00", + "0005000010140700" + ] + }, + { + "name": "IRONFALL Invasion", + "game_server_id": "", + "access_key": "feb81c7c", + "library_versions": { + "main": "3.7.1", + "ranking": "3.7.1", + "datastore": "3.7.1", + "match_making": "3.7.1", + "messaging": "3.7.1", + "utility": "3.7.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000400000015B100", + "000400000015D800", + "000400000017BF00", + "000400000017D000" + ] + }, + { + "name": "Legend of Kay", + "game_server_id": "", + "access_key": "478232f3", + "library_versions": { + "main": "3.8.3", + "ranking": "3.8.3", + "datastore": "3.8.3", + "match_making": "3.8.3", + "messaging": "3.8.3", + "utility": "3.8.3" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010193300", + "0005000010193400" + ] + }, + { + "name": "LOST REAVERS", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.10.0", + "ranking": "3.10.0", + "datastore": "3.10.0", + "match_making": "3.10.0", + "messaging": "3.10.0", + "utility": "3.10.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001018D900", + "00050000101A4800", + "00050000101B9900" + ] + }, + { + "name": "Mario & Sonic Rio 2016 3DS", + "game_server_id": "", + "access_key": "a2dbfa39", + "library_versions": { + "main": "3.9.1", + "ranking": "3.9.1", + "datastore": "3.9.1", + "match_making": "3.9.1", + "messaging": "3.9.1", + "utility": "3.9.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000400000014A400", + "000400000017E200", + "000400000017E300", + "0004000000191C00", + "0004000000191D00", + "0004000000192400" + ] + }, + { + "name": "Mario & Sonic Rio 2016 Wii U", + "game_server_id": "", + "access_key": "63fecb0f", + "library_versions": { + "main": "3.9.1", + "ranking": "3.9.1", + "datastore": "3.9.1", + "match_making": "3.9.1", + "messaging": "3.9.1", + "utility": "3.9.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010190300", + "00050000101E5300", + "00050000101E5400" + ] + }, + { + "name": "MARIO & SONIC SOCHI 2014", + "game_server_id": "", + "access_key": "585214a5", + "library_versions": { + "main": "3.4.0", + "ranking": "3.4.0", + "datastore": "3.4.0", + "match_making": "3.4.0", + "messaging": "3.4.0", + "utility": "3.4.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010106900", + "000500001010C700", + "000500001010C800" + ] + }, + { + "name": "MARIO KART 7", + "game_server_id": "", + "access_key": "6181dff1", + "library_versions": { + "main": "2.4.3", + "ranking": "2.4.3", + "datastore": "2.4.3", + "match_making": "2.4.3", + "messaging": "2.4.3", + "utility": "2.4.3" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000030600", + "0004000000030700", + "0004000000030800", + "0004000000030A00", + "000400000008B400" + ] + }, + { + "name": "MARIO KART 8", + "game_server_id": "", + "access_key": "25dbf96a", + "library_versions": { + "main": "3.5.4", + "ranking": "3.5.4", + "datastore": "3.5.4", + "match_making": "3.5.4", + "messaging": "3.5.4", + "utility": "3.5.4" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001010EB00", + "000500001010EC00", + "000500001010ED00" + ] + }, + { + "name": "Mario Tennis Open", + "game_server_id": "", + "access_key": "0fabeff2", + "library_versions": { + "main": "2.6.1", + "ranking": "2.6.1", + "datastore": "2.6.1", + "match_making": "2.6.1", + "messaging": "2.6.1", + "utility": "2.6.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000064D00", + "000400000007C700", + "000400000007C800", + "00040000000B8800", + "00040000000B9100" + ] + }, + { + "name": "Mario Tennis: Ultra Smash", + "game_server_id": "", + "access_key": "c69b92a0", + "library_versions": { + "main": "3.9.1", + "ranking": "3.9.1", + "datastore": "3.9.1", + "match_making": "3.9.1", + "messaging": "3.9.1", + "utility": "3.9.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010199000", + "00050000101A3500", + "00050000101A3600" + ] + }, + { + "name": "Mario vs. DK: Tipping Stars", + "game_server_id": "", + "access_key": "d8927c3f", + "library_versions": { + "main": "3.7.1", + "ranking": "3.7.1", + "datastore": "3.7.1", + "match_making": "3.7.1", + "messaging": "3.7.1", + "utility": "3.7.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000400000012C800", + "000400000012CA00", + "0005000010149300", + "0005000010178E00", + "0005000010179200" + ] + }, + { + "name": "Metroid Prime: FF", + "game_server_id": "", + "access_key": "f79fb3c5", + "library_versions": { + "main": "3.9.1", + "ranking": "3.9.1", + "datastore": "3.9.1", + "match_making": "3.9.1", + "messaging": "3.9.1", + "utility": "3.9.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000400000016CE00", + "000400000016E300", + "0004000000175200" + ] + }, + { + "name": "MH3G HD Ver.", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.0.5", + "ranking": "3.0.5", + "datastore": "3.0.5", + "match_making": "3.0.5", + "messaging": "3.0.5", + "utility": "3.0.5" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000048100", + "0005000010104D00" + ] + }, + { + "name": "MH3U", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.0.5", + "ranking": "3.0.5", + "datastore": "3.0.5", + "match_making": "3.0.5", + "messaging": "3.0.5", + "utility": "3.0.5" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000000AE400", + "00040000000B1D00", + "00040000000D2E00", + "0005000010117200", + "0005000010118300" + ] + }, + { + "name": "Mighty No. 9", + "game_server_id": "", + "access_key": "bb980c2e", + "library_versions": { + "main": "3.9.1", + "ranking": "3.9.1", + "datastore": "3.9.1", + "match_making": "3.9.1", + "messaging": "3.9.1", + "utility": "3.9.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00050000101C5A00", + "00050000101C9600", + "00050000101DD900" + ] + }, + { + "name": "Minecraft: Wii U Edition", + "game_server_id": "", + "access_key": "f1b61c8e", + "library_versions": { + "main": "3.10.0", + "ranking": "3.10.0", + "datastore": "3.10.0", + "match_making": "3.10.0", + "messaging": "3.10.0", + "utility": "3.10.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00050000101D7500", + "00050000101D9D00", + "00050000101DBE00" + ] + }, + { + "name": "Nano Assault Neo", + "game_server_id": "", + "access_key": "7e484a8e", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010110100", + "0005000010110600", + "0005000010136400" + ] + }, + { + "name": "NINJA GAIDEN 3: Razor's Edge", + "game_server_id": "", + "access_key": "f857b4bd", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010110900", + "0005000010110A00", + "0005000010110B00", + "0005000010139B00" + ] + }, + { + "name": "Nova-111", + "game_server_id": "", + "access_key": "bafe9856", + "library_versions": { + "main": "3.8.3", + "ranking": "3.8.3", + "datastore": "3.8.3", + "match_making": "3.8.3", + "messaging": "3.8.3", + "utility": "3.8.3" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00050000101C0700", + "00050000101C0A00" + ] + }, + { + "name": "OlliOlli", + "game_server_id": "", + "access_key": "60e5df12", + "library_versions": { + "main": "3.6.1", + "ranking": "3.6.1", + "datastore": "3.6.1", + "match_making": "3.6.1", + "messaging": "3.6.1", + "utility": "3.6.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000400000015A200", + "000400000015A400", + "00050000101A5E00", + "00050000101A6900" + ] + }, + { + "name": "PIKMIN 3", + "game_server_id": "", + "access_key": "f6accfc1", + "library_versions": { + "main": "3.3.0", + "ranking": "3.3.0", + "datastore": "3.3.0", + "match_making": "3.3.0", + "messaging": "3.3.0", + "utility": "3.3.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001012BC00", + "000500001012BD00", + "000500001012BE00", + "0005000010185300" + ] + }, + { + "name": "Pokémon Bank", + "game_server_id": "", + "access_key": "9a2961d8", + "library_versions": { + "main": "3.4.12", + "ranking": "3.4.12", + "datastore": "3.4.12", + "match_making": "3.4.12", + "messaging": "3.4.12", + "utility": "3.4.12" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000000C9B00" + ] + }, + { + "name": "Pokémon Rumble World", + "game_server_id": "", + "access_key": "844f1d0c", + "library_versions": { + "main": "3.8.2", + "ranking": "3.8.2", + "datastore": "3.8.2", + "match_making": "3.8.2", + "messaging": "3.8.2", + "utility": "3.8.2" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000164600", + "0004000000185A00" + ] + }, + { + "name": "POKKÉN TOURNAMENT", + "game_server_id": "", + "access_key": "6ef3adf1", + "library_versions": { + "main": "3.10.0", + "ranking": "3.10.0", + "datastore": "3.10.0", + "match_making": "3.10.0", + "messaging": "3.10.0", + "utility": "3.10.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00050000101C5800", + "00050000101DF400", + "00050000101DF500" + ] + }, + { + "name": "Puddle", + "game_server_id": "", + "access_key": "afcffb5c", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001010FB00", + "0005000010110500", + "00050000101A2700" + ] + }, + { + "name": "PUYOPUYOTETRIS", + "game_server_id": "", + "access_key": "4eb0ca36", + "library_versions": { + "main": "3.5.2", + "ranking": "3.5.2", + "datastore": "3.5.2", + "match_making": "3.5.2", + "messaging": "3.5.2", + "utility": "3.5.2" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000101200", + "000500001014D900" + ] + }, + { + "name": "RESIDENT EVIL REVELATIONS", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.2.1", + "ranking": "3.2.1", + "datastore": "3.2.1", + "match_making": "3.2.1", + "messaging": "3.2.1", + "utility": "3.2.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000053B00", + "000400000005EE00", + "000500001012B400", + "000500001012CF00" + ] + }, + { + "name": "RTK 12", + "game_server_id": "", + "access_key": "bfede098", + "library_versions": { + "main": "3.4.0", + "ranking": "3.4.0", + "datastore": "3.4.0", + "match_making": "3.4.0", + "messaging": "3.4.0", + "utility": "3.4.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010111C00", + "0005000010149000" + ] + }, + { + "name": "Runner2", + "game_server_id": "", + "access_key": "1084452a", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001011AF00", + "0005000010136300", + "00050000101DD600" + ] + }, + { + "name": "SI2", + "game_server_id": "", + "access_key": "44adeb87", + "library_versions": { + "main": "3.6.1", + "ranking": "3.6.1", + "datastore": "3.6.1", + "match_making": "3.6.1", + "messaging": "3.6.1", + "utility": "3.6.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010173300", + "0005000010176500" + ] + }, + { + "name": "SONIC LOST WORLD", + "game_server_id": "", + "access_key": "69a9fc95", + "library_versions": { + "main": "3.3.0", + "ranking": "3.3.0", + "datastore": "3.3.0", + "match_making": "3.3.0", + "messaging": "3.3.0", + "utility": "3.3.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000000C5400", + "00040000000C8C00", + "00040000000CB400", + "000400000010CF00", + "0005000010128F00", + "000500001012B100", + "0005000010135700" + ] + }, + { + "name": "Sonic Transformed", + "game_server_id": "", + "access_key": "b26a3421", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000400000008FC00", + "00040000000B3500", + "000500001010B300", + "0005000010111F00", + "000500001015B400" + ] + }, + { + "name": "Splatoon", + "game_server_id": "", + "access_key": "6f599f81", + "library_versions": { + "main": "3.8.3", + "ranking": "3.8.3", + "datastore": "3.8.3", + "match_making": "3.8.3", + "messaging": "3.8.3", + "utility": "3.8.3" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010162B00", + "0005000010176900", + "0005000010176A00", + "000500001017E300", + "00050000101CDB00", + "00050000101CDC00", + "00050000101CDD00", + "00050000101CDE00", + "00050000101D6A00", + "00050000101D6B00", + "00050000101D6C00" + ] + }, + { + "name": "Star Fox Guard", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.8.2", + "ranking": "3.8.2", + "datastore": "3.8.2", + "match_making": "3.8.2", + "messaging": "3.8.2", + "utility": "3.8.2" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00050000101BEB00", + "00050000101BEC00", + "00050000101BED00" + ] + }, + { + "name": "Star Fox Guard (Demo)", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.8.2", + "ranking": "3.8.2", + "datastore": "3.8.2", + "match_making": "3.8.2", + "messaging": "3.8.2", + "utility": "3.8.2" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00050000101DCC00", + "00050000101DCD00", + "00050000101DCE00" + ] + }, + { + "name": "Star Wars Pinball", + "game_server_id": "", + "access_key": "ecd0e530", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000000D4A00", + "00040000000E6800", + "0005000010132A00", + "0005000010135200" + ] + }, + { + "name": "Steel Diver: Sub Wars", + "game_server_id": "", + "access_key": "fb9537fe", + "library_versions": { + "main": "3.7.0", + "ranking": "3.7.0", + "datastore": "3.7.0", + "match_making": "3.7.0", + "messaging": "3.7.0", + "utility": "3.7.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000000D7D00", + "00040000000D7E00" + ] + }, + { + "name": "Super Mario Maker", + "game_server_id": "", + "access_key": "9f2b4678", + "library_versions": { + "main": "3.8.12", + "ranking": "3.8.12", + "datastore": "3.8.12", + "match_making": "3.8.12", + "messaging": "3.8.12", + "utility": "3.8.12" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000001A0300", + "00040000001A0400", + "00040000001A0500", + "00040000001BB800", + "000500001018DB00", + "000500001018DC00", + "000500001018DD00" + ] + }, + { + "name": "Super Smash Bros.", + "game_server_id": "", + "access_key": "2869ba38", + "library_versions": { + "main": "3.6.27", + "ranking": "3.6.27", + "datastore": "3.6.27", + "match_making": "3.6.27", + "messaging": "3.6.27", + "utility": "3.6.27" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000000B8B00", + "00040000000EDF00", + "00040000000EE000", + "0004000000167C00", + "0005000010110E00", + "0005000010144F00", + "0005000010145000" + ] + }, + { + "name": "Team Kirby Clash Deluxe", + "game_server_id": "", + "access_key": "e0c85605", + "library_versions": { + "main": "3.10.1", + "ranking": "3.10.1", + "datastore": "3.10.1", + "match_making": "3.10.1", + "messaging": "3.10.1", + "utility": "3.10.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000001A8B00", + "00040000001AB800", + "00040000001AB900", + "00040000001C2200", + "00040000001CAA00", + "00040000001CAD00" + ] + }, + { + "name": "TEKKEN TAG 2 Wii U EDITION", + "game_server_id": "", + "access_key": "0f037f64", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010100600", + "000500001010F800", + "0005000010110000" + ] + }, + { + "name": "Terraria", + "game_server_id": "", + "access_key": "3d37fbdb", + "library_versions": { + "main": "3.8.3", + "ranking": "3.8.3", + "datastore": "3.8.3", + "match_making": "3.8.3", + "messaging": "3.8.3", + "utility": "3.8.3" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000400000016A600", + "000400000016A900", + "00040000001B3200", + "0005000010198F00", + "000500001019C300", + "00050000101F3A00" + ] + }, + { + "name": "Trine 2", + "game_server_id": "", + "access_key": "f9c35adc", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010112200", + "0005000010128A00", + "000500001014D600" + ] + }, + { + "name": "WARRIORS OROCHI 3 Hyper", + "game_server_id": "", + "access_key": "d74bb27d", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001010EA00", + "0005000010110200", + "0005000010112B00" + ] + }, + { + "name": "Wii Karaoke U", + "game_server_id": "", + "access_key": "dfc5a4ac", + "library_versions": { + "main": "3.4.0", + "ranking": "3.4.0", + "datastore": "3.4.0", + "match_making": "3.4.0", + "messaging": "3.4.0", + "utility": "3.4.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010100D00", + "0005000010102500", + "0005000010149600" + ] + }, + { + "name": "Wii Party U", + "game_server_id": "", + "access_key": "a5b77314", + "library_versions": { + "main": "3.3.0", + "ranking": "3.3.0", + "datastore": "3.3.0", + "match_making": "3.3.0", + "messaging": "3.3.0", + "utility": "3.3.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001011A800", + "0005000010137D00", + "0005000010137E00" + ] + }, + { + "name": "Wii Sports Club", + "game_server_id": "", + "access_key": "4d324052", + "library_versions": { + "main": "3.4.7", + "ranking": "3.4.7", + "datastore": "3.4.7", + "match_making": "3.4.7", + "messaging": "3.4.7", + "utility": "3.4.7" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000500001012F100", + "0005000010144D00", + "0005000010144E00", + "0005000010171E00" + ] + }, + { + "name": "Xenoblade Chronicles X", + "game_server_id": "", + "access_key": "59d7be84", + "library_versions": { + "main": "3.5.5", + "ranking": "3.5.5", + "datastore": "3.5.5", + "match_making": "3.5.5", + "messaging": "3.5.5", + "utility": "3.5.5" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010116100", + "00050000101C4C00", + "00050000101C4D00" + ] + }, + { + "name": "Yo-kai Watch 2", + "game_server_id": "", + "access_key": "7ab183bb", + "library_versions": { + "main": "3.6.1", + "ranking": "3.6.1", + "datastore": "3.6.1", + "match_making": "3.6.1", + "messaging": "3.6.1", + "utility": "3.6.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "000400000012F800", + "000400000012F900", + "0004000000155100", + "000400000019A900", + "000400000019AA00", + "000400000019AE00", + "000400000019AF00", + "00040000001B2700", + "00040000001B2A00", + "00040000001B7100", + "00040000001BB500" + ] + }, + { + "name": "Zen Pinball 2", + "game_server_id": "", + "access_key": "2ff15f7e", + "library_versions": { + "main": "3.0.1", + "ranking": "3.0.1", + "datastore": "3.0.1", + "match_making": "3.0.1", + "messaging": "3.0.1", + "utility": "3.0.1" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010113800", + "0005000010115F00" + ] + }, + { + "name": "役満 鳳凰", + "game_server_id": "", + "access_key": "23aab2d3", + "library_versions": { + "main": "3.6.14", + "ranking": "3.6.14", + "datastore": "3.6.14", + "match_making": "3.6.14", + "messaging": "3.6.14", + "utility": "3.6.14" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0005000010149700" + ] + }, + { + "name": "Kid Icarus Uprising", + "game_server_id": "", + "access_key": "58a7e494", + "library_versions": { + "main": "0.0.0", + "ranking": "0.0.0", + "datastore": "0.0.0", + "match_making": "0.0.0", + "messaging": "0.0.0", + "utility": "0.0.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000030000", + "0004000000030100", + "0004000000030200" + ] + }, + { + "name": "Luigi's Mansion 2", + "game_server_id": "", + "access_key": "3861a9f8", + "library_versions": { + "main": "0.0.0", + "ranking": "0.0.0", + "datastore": "0.0.0", + "match_making": "0.0.0", + "messaging": "0.0.0", + "utility": "0.0.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000055F00", + "0004000000076400", + "0004000000076500" + ] + }, + { + "name": "Pokémon X/Y", + "game_server_id": "", + "access_key": "876138df", + "library_versions": { + "main": "0.0.0", + "ranking": "0.0.0", + "datastore": "0.0.0", + "match_making": "0.0.0", + "messaging": "0.0.0", + "utility": "0.0.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000055D00" + ] + }, + { + "name": "TLoZ: Tri Force Heroes", + "game_server_id": "", + "access_key": "c1621b84", + "library_versions": { + "main": "0.0.0", + "ranking": "0.0.0", + "datastore": "0.0.0", + "match_making": "0.0.0", + "messaging": "0.0.0", + "utility": "0.0.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0004000000176E00", + "0004000000176F00", + "0004000000177000", + "0004000000182200", + "0004000000182300" + ] + }, + { + "name": "Mario Kart 8 Deluxe", + "game_server_id": "2b309e01", + "access_key": "09c1c475", + "library_versions": { + "main": "4.3.2", + "ranking": "4.3.2", + "datastore": "4.3.2", + "match_making": "4.3.2", + "messaging": "4.3.2", + "utility": "4.3.2" + }, + "settings": { + "pid_size": 8, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "0100152000022000" + ] + }, + { + "name": "Super Mario Maker 2", + "game_server_id": "22306d00", + "access_key": "fdf6617f", + "library_versions": { + "main": "4.6.25", + "ranking": "4.6.25", + "datastore": "4.6.25", + "match_making": "4.6.25", + "messaging": "4.6.25", + "utility": "4.6.25" + }, + "settings": { + "pid_size": 8, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "01009B90006DC000" + ] + }, + { + "name": "Miitopia (3DS)", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.10.2", + "ranking": "3.10.2", + "datastore": "3.10.2", + "match_making": "3.10.2", + "messaging": "3.10.2", + "utility": "3.10.2" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": true, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000001B4E00", + "00040000001B4F00", + "0004000000178800" + ] + }, + { + "name": "KORG M01D", + "game_server_id": "", + "access_key": "", + "library_versions": { + "main": "3.3.0", + "ranking": "3.3.0", + "datastore": "3.3.0", + "match_making": "3.3.0", + "messaging": "3.3.0", + "utility": "3.3.0" + }, + "settings": { + "pid_size": 4, + "string_length_size": 2, + "use_structure_header": false, + "session_key_size": 32, + "kerberos_key_version": 0, + "kerberos_ticket_version": 0, + "checksum_size": 4, + "flags_and_type_size": 2 + }, + "title_ids": [ + "00040000000F1600", + "00040000000F0800" + ] + } +] \ No newline at end of file diff --git a/src/nex/types/any-data-holder.ts b/src/nex/types/any-data-holder.ts new file mode 100644 index 0000000..7dd03eb --- /dev/null +++ b/src/nex/types/any-data-holder.ts @@ -0,0 +1,48 @@ +import NEXByteStream from '@/nex/byte-stream'; +import Structure from '@/nex/types/structure'; +import RVString from '@/nex/types/string'; +import UInt32 from '@/nex/types/uint32'; +import type RVType from '@/nex/types/rv-type'; + +export default class AnyDataHolder extends Structure { + public static Classes: Record RVType> = {}; + + public readonly typeName = 'AnyDataHolder'; + + private name = new RVString(); + private length1 = new UInt32(); + private length2 = new UInt32(); + private objectData: RVType; + + public extractFrom(stream: NEXByteStream): void { + this.name.extractFrom(stream); + this.length1.extractFrom(stream); + this.length2.extractFrom(stream); + + const objectStream = new NEXByteStream(stream.read(this.length2.value), stream.settings); + + if (AnyDataHolder.Classes[this.name.value]) { + this.objectData = new AnyDataHolder.Classes[this.name.value](); + + this.objectData.extractFrom(objectStream); + } + + // TODO - Error if not found + } + + public new(): AnyDataHolder { + return new AnyDataHolder(); + } + + private displayTypeName(): string { + return `AnyDataHolder<${this.name.value}>`; + } + + public toJSON(): Record { + return { + __displayTypeName: this.displayTypeName(), + __typeName: this.typeName, + __value: this.objectData + }; + } +} \ No newline at end of file diff --git a/src/nex/types/bool.ts b/src/nex/types/bool.ts new file mode 100644 index 0000000..16a9c90 --- /dev/null +++ b/src/nex/types/bool.ts @@ -0,0 +1,23 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class Bool { + public readonly typeName = 'Bool'; + + public value: boolean; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readBoolean(); + } + + public new(): Bool { + return new Bool(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/buffer.ts b/src/nex/types/buffer.ts new file mode 100644 index 0000000..5cfdb47 --- /dev/null +++ b/src/nex/types/buffer.ts @@ -0,0 +1,26 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +// * Real name is Buffer, but this conflicts with JavaScript +export default class RVBuffer { + public readonly typeName = 'Buffer'; + + public value: Buffer; + + public extractFrom(stream: NEXByteStream): void { + const length = stream.readUInt32LE(); + + this.value = stream.read(length); + } + + public new(): RVBuffer { + return new RVBuffer(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/data.ts b/src/nex/types/data.ts new file mode 100644 index 0000000..ec5daeb --- /dev/null +++ b/src/nex/types/data.ts @@ -0,0 +1,24 @@ +import Structure from '@/nex/types/structure'; +import type NEXByteStream from '@/nex/byte-stream'; + +// * Data has no fields itself. +// * This is the parent class for all types which are allowed in AnyDataHolder +export default class Data extends Structure { + public readonly typeName = 'Data'; + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + } + + public new(): Data { + return new Data(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName + }; + } +} \ No newline at end of file diff --git a/src/nex/types/datetime.ts b/src/nex/types/datetime.ts new file mode 100644 index 0000000..9db52ca --- /dev/null +++ b/src/nex/types/datetime.ts @@ -0,0 +1,58 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class DateTime { + public readonly typeName = 'DateTime'; + + private value: bigint; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readInt64LE(); + } + + private getSeconds(): number { + return Number(this.value & 63n); + } + + private getMinutes(): number { + return Number((this.value >> 6n) & 63n); + } + + private getHours(): number { + return Number((this.value >> 12n) & 31n); + } + + public getDay(): number { + return Number((this.value >> 17n) & 31n); + } + + private getMonth(): number { + return Number((this.value >> 22n) & 15n) - 1; + } + + private getYear(): number { + return Number(this.value >> 26n); + } + + private standard(): Date { + return new Date(Date.UTC( + this.getYear(), + this.getMonth(), + this.getDay(), + this.getHours(), + this.getMinutes(), + this.getSeconds() + )); + } + + public new(): DateTime { + return new DateTime(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: `${this.standard()} (${this.value})` + }; + } +} \ No newline at end of file diff --git a/src/nex/types/double.ts b/src/nex/types/double.ts new file mode 100644 index 0000000..307f0a5 --- /dev/null +++ b/src/nex/types/double.ts @@ -0,0 +1,23 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class Double { + public readonly typeName = 'Double'; + + public value: number; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readDoubleLE(); + } + + public new(): Double { + return new Double(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/float.ts b/src/nex/types/float.ts new file mode 100644 index 0000000..75b99cb --- /dev/null +++ b/src/nex/types/float.ts @@ -0,0 +1,23 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class Float { + public readonly typeName = 'Float'; + + public value: number; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readFloatLE(); + } + + public new(): Float { + return new Float(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/int16.ts b/src/nex/types/int16.ts new file mode 100644 index 0000000..87315fa --- /dev/null +++ b/src/nex/types/int16.ts @@ -0,0 +1,23 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class Int16 { + public readonly typeName = 'Int16'; + + public value: number; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readInt16LE(); + } + + public new(): Int16 { + return new Int16(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/int32.ts b/src/nex/types/int32.ts new file mode 100644 index 0000000..19b16bc --- /dev/null +++ b/src/nex/types/int32.ts @@ -0,0 +1,23 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class Int32 { + public readonly typeName = 'Int32'; + + public value: number; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readInt32LE(); + } + + public new(): Int32 { + return new Int32(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/int64.ts b/src/nex/types/int64.ts new file mode 100644 index 0000000..d8166fa --- /dev/null +++ b/src/nex/types/int64.ts @@ -0,0 +1,23 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class Int64 { + public readonly typeName = 'Int64'; + + public value: bigint; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readInt64LE(); + } + + public new(): Int64 { + return new Int64(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/int8.ts b/src/nex/types/int8.ts new file mode 100644 index 0000000..2885e4a --- /dev/null +++ b/src/nex/types/int8.ts @@ -0,0 +1,23 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class Int8 { + public readonly typeName = 'Int8'; + + public value: number; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readInt8(); + } + + public new(): Int8 { + return new Int8(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/list.ts b/src/nex/types/list.ts new file mode 100644 index 0000000..17bce4d --- /dev/null +++ b/src/nex/types/list.ts @@ -0,0 +1,38 @@ +import type RVType from '@/nex/types/rv-type'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class List { + private readonly typeName = 'List'; + + private list: T[] = []; + + constructor(private type: T) {} + + public extractFrom(stream: NEXByteStream): void { + const length = stream.readUInt32LE(); + + for (let i = 0; i < length; i++) { + const element = this.type.new(); + + element.extractFrom(stream); + + this.list.push(element); + } + } + + public new(): List { + return new List(this.type.new()); + } + + private displayTypeName(): string { + return `List<${this.type.typeName}>`; + } + + public toJSON(): Record { + return { + __displayTypeName: this.displayTypeName(), + __typeName: this.typeName, + __value: this.list + }; + } +} \ No newline at end of file diff --git a/src/nex/types/map.ts b/src/nex/types/map.ts new file mode 100644 index 0000000..0cb801f --- /dev/null +++ b/src/nex/types/map.ts @@ -0,0 +1,48 @@ +import type RVType from '@/nex/types/rv-type'; +import type NEXByteStream from '@/nex/byte-stream'; + +// * Real name is Map, but this conflicts with JavaScript +export default class RVMap { + public readonly typeName = 'Map'; + + private keys: K[] = []; + private values: V[] = []; + + constructor(private keyType: K, private valueType: V) {} + + public extractFrom(stream: NEXByteStream): void { + const length = stream.readUInt32LE(); + + for (let i = 0; i < length; i++) { + const key = this.keyType.new(); + const value = this.valueType.new(); + + key.extractFrom(stream); + value.extractFrom(stream); + + this.keys.push(key); + this.values.push(value); + } + } + + public new(): RVMap { + return new RVMap(this.keyType.new(), this.valueType.new()); + } + + private displayTypeName(): string { + return `Map<${this.keyType.typeName}, ${this.valueType.typeName}>`; + } + + public toJSON(): Record { + return { + __displayTypeName: this.displayTypeName(), + __typeName: this.typeName, + __value: this.keys.map((key, i) => { + return { + key: key, + value: this.values[i] + }; + }) + }; + } +} \ No newline at end of file diff --git a/src/nex/types/pid.ts b/src/nex/types/pid.ts new file mode 100644 index 0000000..9df0dd5 --- /dev/null +++ b/src/nex/types/pid.ts @@ -0,0 +1,31 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class PID { + public readonly typeName = 'PID'; + + public value: bigint; + + private size: number; + + public extractFrom(stream: NEXByteStream): void { + if (stream.settings.pid_size === 8) { + this.value = stream.readUInt64LE(); + } else { + this.value = BigInt(stream.readUInt32LE()); + } + + this.size = stream.settings.pid_size; + } + + public new(): PID { + return new PID(); + } + + public toJSON(): Record { + return { + __displayTypeName: `PID (${this.size})`, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/qbuffer.ts b/src/nex/types/qbuffer.ts new file mode 100644 index 0000000..ef49d26 --- /dev/null +++ b/src/nex/types/qbuffer.ts @@ -0,0 +1,25 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class QBuffer { + public readonly typeName = 'QBuffer'; + + private value: Buffer; + + public extractFrom(stream: NEXByteStream): void { + const length = stream.readUInt16LE(); + + this.value = stream.read(length); + } + + public new(): QBuffer { + return new QBuffer(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/qresult.ts b/src/nex/types/qresult.ts new file mode 100644 index 0000000..9236eec --- /dev/null +++ b/src/nex/types/qresult.ts @@ -0,0 +1,340 @@ +import type ByteStream from '@/byte-stream'; + +const ERROR_MASK = 1 << 31; + +const names: Record = { + 0x00010001: 'Core::Unknown', + 0x00010002: 'Core::NotImplemented', + 0x00010003: 'Core::InvalidPointer', + 0x00010004: 'Core::OperationAborted', + 0x00010005: 'Core::Exception', + 0x00010006: 'Core::AccessDenied', + 0x00010007: 'Core::InvalidHandle', + 0x00010008: 'Core::InvalidIndex', + 0x00010009: 'Core::OutOfMemory', + 0x0001000A: 'Core::InvalidArgument', + 0x0001000B: 'Core::Timeout', + 0x0001000C: 'Core::InitializationFailure', + 0x0001000D: 'Core::CallInitiationFailure', + 0x0001000E: 'Core::RegistrationError', + 0x0001000F: 'Core::BufferOverflow', + 0x00010010: 'Core::InvalidLockState', + 0x00010011: 'Core::InvalidSequence', + 0x00010012: 'Core::SystemError', + 0x00010013: 'Core::Cancelled', + + 0x00020001: 'DDL::InvalidSignature', + 0x00020002: 'DDL::IncorrectVersion', + + 0x00030001: 'RendezVous::ConnectionFailure', + 0x00030002: 'RendezVous::NotAuthenticated', + + 0x00030064: 'RendezVous::InvalidUsername', + 0x00030065: 'RendezVous::InvalidPassword', + 0x00030066: 'RendezVous::UsernameAlreadyExists', + 0x00030067: 'RendezVous::AccountDisabled', + 0x00030068: 'RendezVous::AccountExpired', + 0x00030069: 'RendezVous::ConcurrentLoginDenied', + 0x0003006A: 'RendezVous::EncryptionFailure', + 0x0003006B: 'RendezVous::InvalidPID', + 0x0003006C: 'RendezVous::MaxConnectionsReached', + 0x0003006D: 'RendezVous::InvalidGID', + 0x0003006E: 'RendezVous::InvalidControlScriptID', + 0x0003006F: 'RendezVous::InvalidOperationInLiveEnvironment', + 0x00030070: 'RendezVous::DuplicateEntry', + 0x00030071: 'RendezVous::ControlScriptFailure', + 0x00030072: 'RendezVous::ClassNotFound', + 0x00030073: 'RendezVous::SessionVoid', + 0x00030075: 'RendezVous::DDLMismatch', + 0x00030076: 'RendezVous::InvalidConfiguration', + + 0x000300C8: 'RendezVous::SessionFull', + 0x000300C9: 'RendezVous::InvalidGatheringPassword', + 0x000300CA: 'RendezVous::WithoutParticipationPeriod', + 0x000300CB: 'RendezVous::PersistentGatheringCreationMax', + 0x000300CC: 'RendezVous::PersistentGatheringParticipationMax', + 0x000300CD: 'RendezVous::DeniedByParticipants', + 0x000300CE: 'RendezVous::ParticipantInBlackList', + 0x000300CF: 'RendezVous::GameServerMaintenance', + 0x000300D0: 'RendezVous::OperationPostpone', + 0x000300D1: 'RendezVous::OutOfRatingRange', + 0x000300D2: 'RendezVous::ConnectionDisconnected', + 0x000300D3: 'RendezVous::InvalidOperation', + 0x000300D4: 'RendezVous::NotParticipatedGathering', + 0x000300D5: 'RendezVous::MatchmakeSessionUserPasswordUnmatch', + 0x000300D6: 'RendezVous::MatchmakeSessionSystemPasswordUnmatch', + 0x000300D7: 'RendezVous::UserIsOffline', + 0x000300D8: 'RendezVous::AlreadyParticipatedGathering', + 0x000300D9: 'RendezVous::PermissionDenied', + 0x000300DA: 'RendezVous::NotFriend', + 0x000300DB: 'RendezVous::SessionClosed', + 0x000300DC: 'RendezVous::DatabaseTemporarilyUnavailable', + 0x000300DD: 'RendezVous::InvalidUniqueId', + 0x000300DE: 'RendezVous::MatchmakingWithdrawn', + 0x000300DF: 'RendezVous::LimitExceeded', + 0x000300E0: 'RendezVous::AccountTemporarilyDisabled', + 0x000300E1: 'RendezVous::PartiallyServiceClosed', + 0x000300E2: 'RendezVous::ConnectionDisconnectedForConcurrentLogin', + + 0x00040001: 'PythonCore::Exception', + 0x00040002: 'PythonCore::TypeError', + 0x00040003: 'PythonCore::IndexError', + 0x00040004: 'PythonCore::InvalidReference', + 0x00040005: 'PythonCore::CallFailure', + 0x00040006: 'PythonCore::MemoryError', + 0x00040007: 'PythonCore::KeyError', + 0x00040008: 'PythonCore::OperationError', + 0x00040009: 'PythonCore::ConversionError', + 0x0004000A: 'PythonCore::ValidationError', + + 0x00050001: 'Transport::Unknown', + 0x00050002: 'Transport::ConnectionFailure', + 0x00050003: 'Transport::InvalidUrl', + 0x00050004: 'Transport::InvalidKey', + 0x00050005: 'Transport::InvalidURLType', + 0x00050006: 'Transport::DuplicateEndpoint', + 0x00050007: 'Transport::IOError', + 0x00050008: 'Transport::Timeout', + 0x00050009: 'Transport::ConnectionReset', + 0x0005000A: 'Transport::IncorrectRemoteAuthentication', + 0x0005000B: 'Transport::ServerRequestError', + 0x0005000C: 'Transport::DecompressionFailure', + 0x0005000D: 'Transport::ReliableSendBufferFullFatal', + 0x0005000E: 'Transport::UPnPCannotInit', + 0x0005000F: 'Transport::UPnPCannotAddMapping', + 0x00050010: 'Transport::NatPMPCannotInit', + 0x00050011: 'Transport::NatPMPCannotAddMapping', + 0x00050013: 'Transport::UnsupportedNAT', + 0x00050014: 'Transport::DnsError', + 0x00050015: 'Transport::ProxyError', + 0x00050016: 'Transport::DataRemaining', + 0x00050017: 'Transport::NoBuffer', + 0x00050018: 'Transport::NotFound', + 0x00050019: 'Transport::TemporaryServerError', + 0x0005001A: 'Transport::PermanentServerError', + 0x0005001B: 'Transport::ServiceUnavailable', + 0x0005001C: 'Transport::ReliableSendBufferFull', + 0x0005001D: 'Transport::InvalidStation', + 0x0005001E: 'Transport::InvalidSubStreamID', + 0x0005001F: 'Transport::PacketBufferFull', + 0x00050020: 'Transport::NatTraversalError', + 0x00050021: 'Transport::NatCheckError', + + 0x00060001: 'DOCore::StationNotReached', + 0x00060002: 'DOCore::TargetStationDisconnect', + 0x00060003: 'DOCore::LocalStationLeaving', + 0x00060004: 'DOCore::ObjectNotFound', + 0x00060005: 'DOCore::InvalidRole', + 0x00060006: 'DOCore::CallTimeout', + 0x00060007: 'DOCore::RMCDispatchFailed', + 0x00060008: 'DOCore::MigrationInProgress', + 0x00060009: 'DOCore::NoAuthority', + 0x0006000A: 'DOCore::NoTargetStationSpecified', + 0x0006000B: 'DOCore::JoinFailed', + 0x0006000C: 'DOCore::JoinDenied', + 0x0006000D: 'DOCore::ConnectivityTestFailed', + 0x0006000E: 'DOCore::Unknown', + 0x0006000F: 'DOCore::UnfreedReferences', + 0x00060010: 'DOCore::JobTerminationFailed', + 0x00060011: 'DOCore::InvalidState', + 0x00060012: 'DOCore::FaultRecoveryFatal', + 0x00060013: 'DOCore::FaultRecoveryJobProcessFailed', + 0x00060014: 'DOCore::StationInconsitency', + 0x00060015: 'DOCore::AbnormalMasterState', + 0x00060016: 'DOCore::VersionMismatch', + + 0x00650000: 'FPD::NotInitialized', + 0x00650001: 'FPD::AlreadyInitialized', + 0x00650002: 'FPD::NotConnected', + 0x00650003: 'FPD::Connected', + 0x00650004: 'FPD::InitializationFailure', + 0x00650005: 'FPD::OutOfMemory', + 0x00650006: 'FPD::RmcFailed', + 0x00650007: 'FPD::InvalidArgument', + 0x00650008: 'FPD::InvalidLocalAccountID', + 0x00650009: 'FPD::InvalidPrincipalID', + 0x0065000A: 'FPD::InvalidLocalFriendCode', + 0x0065000B: 'FPD::LocalAccountNotExists', + 0x0065000C: 'FPD::LocalAccountNotLoaded', + 0x0065000D: 'FPD::LocalAccountAlreadyLoaded', + 0x0065000E: 'FPD::FriendAlreadyExists', + 0x0065000F: 'FPD::FriendNotExists', + 0x00650010: 'FPD::FriendNumMax', + 0x00650011: 'FPD::NotFriend', + 0x00650012: 'FPD::FileIO', + 0x00650013: 'FPD::P2PInternetProhibited', + 0x00650014: 'FPD::Unknown', + 0x00650015: 'FPD::InvalidState', + 0x00650017: 'FPD::AddFriendProhibited', + 0x00650019: 'FPD::InvalidAccount', + 0x0065001A: 'FPD::BlacklistedByMe', + 0x0065001C: 'FPD::FriendAlreadyAdded', + 0x0065001D: 'FPD::MyFriendListLimitExceed', + 0x0065001E: 'FPD::RequestLimitExceed', + 0x0065001F: 'FPD::InvalidMessageID', + 0x00650020: 'FPD::MessageIsNotMine', + 0x00650021: 'FPD::MessageIsNotForMe', + 0x00650022: 'FPD::FriendRequestBlocked', + 0x00650023: 'FPD::NotInMyFriendList', + 0x00650024: 'FPD::FriendListedByMe', + 0x00650025: 'FPD::NotInMyBlacklist', + 0x00650026: 'FPD::IncompatibleAccount', + 0x00650027: 'FPD::BlockSettingChangeNotAllowed', + 0x00650028: 'FPD::SizeLimitExceeded', + 0x00650029: 'FPD::OperationNotAllowed', + 0x0065002A: 'FPD::NotNetworkAccount', + 0x0065002B: 'FPD::NotificationNotFound', + 0x0065002C: 'FPD::PreferenceNotInitialized', + 0x0065002D: 'FPD::FriendRequestNotAllowed', + + 0x00670001: 'Ranking::NotInitialized', + 0x00670002: 'Ranking::InvalidArgument', + 0x00670003: 'Ranking::RegistrationError', + 0x00670005: 'Ranking::NotFound', + 0x00670006: 'Ranking::InvalidScore', + 0x00670007: 'Ranking::InvalidDataSize', + 0x00670009: 'Ranking::PermissionDenied', + 0x0067000A: 'Ranking::Unknown', + 0x0067000B: 'Ranking::NotImplemented', + + 0x00680001: 'Authentication::NASAuthenticateError', + 0x00680002: 'Authentication::TokenParseError', + 0x00680003: 'Authentication::HttpConnectionError', + 0x00680004: 'Authentication::HttpDNSError', + 0x00680005: 'Authentication::HttpGetProxySetting', + 0x00680006: 'Authentication::TokenExpired', + 0x00680007: 'Authentication::ValidationFailed', + 0x00680008: 'Authentication::InvalidParam', + 0x00680009: 'Authentication::PrincipalIdUnmatched', + 0x0068000A: 'Authentication::MoveCountUnmatch', + 0x0068000B: 'Authentication::UnderMaintenance', + 0x0068000C: 'Authentication::UnsupportedVersion', + 0x0068000D: 'Authentication::ServerVersionIsOld', + 0x0068000E: 'Authentication::Unknown', + 0x0068000F: 'Authentication::ClientVersionIsOld', + 0x00680010: 'Authentication::AccountLibraryError', + 0x00680011: 'Authentication::ServiceNoLongerAvailable', + 0x00680012: 'Authentication::UnknownApplication', + 0x00680013: 'Authentication::ApplicationVersionIsOld', + 0x00680014: 'Authentication::OutOfService', + 0x00680015: 'Authentication::NetworkServiceLicenseRequired', + 0x00680016: 'Authentication::NetworkServiceLicenseSystemError', + 0x00680017: 'Authentication::NetworkServiceLicenseError3', + 0x00680018: 'Authentication::NetworkServiceLicenseError4', + + 0x00690001: 'DataStore::Unknown', + 0x00690002: 'DataStore::InvalidArgument', + 0x00690003: 'DataStore::PermissionDenied', + 0x00690004: 'DataStore::NotFound', + 0x00690005: 'DataStore::AlreadyLocked', + 0x00690006: 'DataStore::UnderReviewing', + 0x00690007: 'DataStore::Expired', + 0x00690008: 'DataStore::InvalidCheckToken', + 0x00690009: 'DataStore::SystemFileError', + 0x0069000A: 'DataStore::OverCapacity', + 0x0069000B: 'DataStore::OperationNotAllowed', + 0x0069000C: 'DataStore::InvalidPassword', + 0x0069000D: 'DataStore::ValueNotEqual', + + 0x006C0001: 'ServiceItem::Unknown', + 0x006C0002: 'ServiceItem::InvalidArgument', + 0x006C0003: 'ServiceItem::EShopUnknownHttpError', + 0x006C0004: 'ServiceItem::EShopResponseParseError', + 0x006C0005: 'ServiceItem::NotOwned', + 0x006C0006: 'ServiceItem::InvalidLimitationType', + 0x006C0007: 'ServiceItem::ConsumptionRightShortage', + + 0x006F0001: 'MatchmakeReferee::Unknown', + 0x006F0002: 'MatchmakeReferee::InvalidArgument', + 0x006F0003: 'MatchmakeReferee::AlreadyExists', + 0x006F0004: 'MatchmakeReferee::NotParticipatedGathering', + 0x006F0005: 'MatchmakeReferee::NotParticipatedRound', + 0x006F0006: 'MatchmakeReferee::StatsNotFound', + 0x006F0007: 'MatchmakeReferee::RoundNotFound', + 0x006F0008: 'MatchmakeReferee::RoundArbitrated', + 0x006F0009: 'MatchmakeReferee::RoundNotArbitrated', + + 0x00700001: 'Subscriber::Unknown', + 0x00700002: 'Subscriber::InvalidArgument', + 0x00700003: 'Subscriber::OverLimit', + 0x00700004: 'Subscriber::PermissionDenied', + + 0x00710001: 'Ranking2::Unknown', + 0x00710002: 'Ranking2::InvalidArgument', + 0x00710003: 'Ranking2::InvalidScore', + + 0x00720001: 'SmartDeviceVoiceChat::Unknown', + 0x00720002: 'SmartDeviceVoiceChat::InvalidArgument', + 0x00720003: 'SmartDeviceVoiceChat::InvalidResponse', + 0x00720004: 'SmartDeviceVoiceChat::InvalidAccessToken', + 0x00720005: 'SmartDeviceVoiceChat::Unauthorized', + 0x00720006: 'SmartDeviceVoiceChat::AccessError', + 0x00720007: 'SmartDeviceVoiceChat::UserNotFound', + 0x00720008: 'SmartDeviceVoiceChat::RoomNotFound', + 0x00720009: 'SmartDeviceVoiceChat::RoomNotActivated', + 0x0072000A: 'SmartDeviceVoiceChat::ApplicationNotSupported', + 0x0072000B: 'SmartDeviceVoiceChat::InternalServerError', + 0x0072000C: 'SmartDeviceVoiceChat::ServiceUnavailable', + 0x0072000D: 'SmartDeviceVoiceChat::UnexpectedError', + 0x0072000E: 'SmartDeviceVoiceChat::UnderMaintenance', + 0x0072000F: 'SmartDeviceVoiceChat::ServiceNoLongerAvailable', + 0x00720010: 'SmartDeviceVoiceChat::AccountTemporarilyDisabled', + 0x00720011: 'SmartDeviceVoiceChat::PermissionDenied', + 0x00720012: 'SmartDeviceVoiceChat::NetworkServiceLicenseRequired', + 0x00720013: 'SmartDeviceVoiceChat::AccountLibraryError', + 0x00720014: 'SmartDeviceVoiceChat::GameModeNotFound', + + 0x00730001: 'Screening::Unknown', + 0x00730002: 'Screening::InvalidArgument', + 0x00730003: 'Screening::NotFound', + + 0x00740001: 'Custom::Unknown', + + 0x00750001: 'Ess::Unknown', + 0x00750002: 'Ess::GameSessionError', + 0x00750003: 'Ess::GameSessionMaintenance' +}; + +export default class QResult { + public readonly typeName = 'QResult'; + + public code: number; + + public extractFrom(stream: ByteStream): void { + this.code = stream.readInt32LE(); + } + + public isSuccess(): boolean { + return (this.code & (1 << 31)) === 0; + } + + public isError(): boolean { + return (this.code & (1 << 31)) !== 0; + } + + public name(): string { + if (this.isSuccess()) { + return 'Success'; + } + + const code = this.code & ~ERROR_MASK; + + if (!names[code]) { + return `Unknown Error (0x${code.toString(16)})`; + } + + return names[code]; + } + + public new(): QResult { + return new QResult(); + } + + public toJSON(): Record { + return { + __displayTypeName: `QResult (${this.name()})`, + __typeName: this.typeName, + __value: this.code + }; + } +} \ No newline at end of file diff --git a/src/nex/types/result-range.ts b/src/nex/types/result-range.ts new file mode 100644 index 0000000..bfa4f43 --- /dev/null +++ b/src/nex/types/result-range.ts @@ -0,0 +1,33 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class ResultRange extends Structure { + public readonly typeName = 'ResultRange'; + + private m_uiOffset = new UInt32(); + private m_uiSize = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_uiOffset.extractFrom(stream); + this.m_uiSize.extractFrom(stream); + } + + public new(): ResultRange { + return new ResultRange(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_uiOffset: this.m_uiOffset, + m_uiSize: this.m_uiSize + } + }; + } +} \ No newline at end of file diff --git a/src/nex/types/rv-connection-data.ts b/src/nex/types/rv-connection-data.ts new file mode 100644 index 0000000..2b8b3ca --- /dev/null +++ b/src/nex/types/rv-connection-data.ts @@ -0,0 +1,51 @@ +import Structure from '@/nex/types/structure'; +import StationURL from '@/nex/types/station-url'; +import List from '@/nex/types/list'; +import UInt8 from '@/nex/types/uint8'; +import DateTime from '@/nex/types/datetime'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class RVConnectionData extends Structure { + public readonly typeName = 'RVConnectionData'; + + private m_urlRegularProtocols = new StationURL(); + private m_lstSpecialProtocols = new List(new UInt8()); + private m_urlSpecialProtocols = new StationURL(); + private m_currentUTCTime: DateTime; + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_urlRegularProtocols.extractFrom(stream); + this.m_lstSpecialProtocols.extractFrom(stream); + this.m_urlSpecialProtocols.extractFrom(stream); + + if (this.structureVersion <= 1) { + this.m_currentUTCTime = new DateTime(); + this.m_currentUTCTime.extractFrom(stream); + } + } + + public new(): RVConnectionData { + return new RVConnectionData(); + } + + public toJSON(): Record { + const json: Record = { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_urlRegularProtocols: this.m_urlRegularProtocols, + m_lstSpecialProtocols: this.m_lstSpecialProtocols, + m_urlSpecialProtocols: this.m_urlSpecialProtocols + } + }; + + if (this.m_currentUTCTime) { + json.__fields.m_currentUTCTime = this.m_currentUTCTime; + } + + return json; + } +} \ No newline at end of file diff --git a/src/nex/types/rv-type.ts b/src/nex/types/rv-type.ts new file mode 100644 index 0000000..be74c06 --- /dev/null +++ b/src/nex/types/rv-type.ts @@ -0,0 +1,8 @@ +import type ByteStream from '@/byte-stream'; + +export default abstract class RVType { + public readonly typeName: string; + + abstract extractFrom(stream: ByteStream): void; + abstract new(): any; +} \ No newline at end of file diff --git a/src/nex/types/station-url.ts b/src/nex/types/station-url.ts new file mode 100644 index 0000000..0236717 --- /dev/null +++ b/src/nex/types/station-url.ts @@ -0,0 +1,36 @@ +import RVString from '@/nex/types/string'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class StationURL { + public readonly typeName = 'StationURL'; + + private url = new RVString(); + private parameters: Record = {}; + + public extractFrom(stream: NEXByteStream): void { + this.url.extractFrom(stream); + + const data = this.url.value.split(':/'); + + if (data.length >= 2) { + // TODO - Support parameters with extra data + this.parameters = Object.fromEntries(data.slice(1).join(':/').split(';').map(parameter => parameter.split('='))); + } + } + + public getParam(name: string): string | undefined { + return this.parameters[name]; + } + + public new(): StationURL { + return new StationURL(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.url + }; + } +} \ No newline at end of file diff --git a/src/nex/types/string.ts b/src/nex/types/string.ts new file mode 100644 index 0000000..75aa976 --- /dev/null +++ b/src/nex/types/string.ts @@ -0,0 +1,32 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +// * Real name is String, but this conflicts with JavaScript +export default class RVString { + public readonly typeName = 'String'; + + public value: string; + + public extractFrom(stream: NEXByteStream): void { + let length = 0; + + if (stream.settings.string_length_size === 4) { + length = stream.readUInt32LE(); + } else { + length = stream.readUInt16LE(); + } + + this.value = stream.readBytes(length).toString().slice(0, -1); + } + + public new(): RVString { + return new RVString(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/structure.ts b/src/nex/types/structure.ts new file mode 100644 index 0000000..257d041 --- /dev/null +++ b/src/nex/types/structure.ts @@ -0,0 +1,16 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class Structure { + private _structureVersion: number; + + get structureVersion(): number { + return this._structureVersion; + } + + protected extractHeaderFrom(stream: NEXByteStream): void { + if (stream.settings.use_structure_header) { + this._structureVersion = stream.readUInt8(); + stream.skip(4); // * Ignore the size + } + } +} \ No newline at end of file diff --git a/src/nex/types/uint16.ts b/src/nex/types/uint16.ts new file mode 100644 index 0000000..17cd8cb --- /dev/null +++ b/src/nex/types/uint16.ts @@ -0,0 +1,23 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class UInt16 { + public readonly typeName = 'UInt16'; + + public value: number; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readUInt16LE(); + } + + public new(): UInt16 { + return new UInt16(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/uint32.ts b/src/nex/types/uint32.ts new file mode 100644 index 0000000..5810c66 --- /dev/null +++ b/src/nex/types/uint32.ts @@ -0,0 +1,23 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class UInt32 { + public readonly typeName = 'UInt32'; + + public value: number; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readUInt32LE(); + } + + public new(): UInt32 { + return new UInt32(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/uint64.ts b/src/nex/types/uint64.ts new file mode 100644 index 0000000..8fb6d5b --- /dev/null +++ b/src/nex/types/uint64.ts @@ -0,0 +1,23 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class UInt64 { + public readonly typeName = 'UInt64'; + + public value: bigint; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readUInt64LE(); + } + + public new(): UInt64 { + return new UInt64(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/uint8.ts b/src/nex/types/uint8.ts new file mode 100644 index 0000000..944444a --- /dev/null +++ b/src/nex/types/uint8.ts @@ -0,0 +1,23 @@ +import type NEXByteStream from '@/nex/byte-stream'; + +export default class UInt8 { + public readonly typeName = 'UInt8'; + + public value: number; + + public extractFrom(stream: NEXByteStream): void { + this.value = stream.readUInt8(); + } + + public new(): UInt8 { + return new UInt8(); + } + + public toJSON(): Record { + return { + __displayTypeName: this.typeName, + __typeName: this.typeName, + __value: this.value + }; + } +} \ No newline at end of file diff --git a/src/nex/types/variant.ts b/src/nex/types/variant.ts new file mode 100644 index 0000000..d9a6e56 --- /dev/null +++ b/src/nex/types/variant.ts @@ -0,0 +1,53 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt8 from '@/nex/types/uint8'; +import Int64 from '@/nex/types/int64'; +import Double from '@/nex/types/double'; +import Bool from '@/nex/types/bool'; +import RVString from '@/nex/types/string'; +import DateTime from '@/nex/types/datetime'; +import UInt64 from '@/nex/types/uint64'; +import type RVType from '@/nex/types/rv-type'; + +export default class Variant { + public static Classes: Record RVType> = { + 1: Int64, + 2: Double, + 3: Bool, + 4: RVString, + 5: DateTime, + 6: UInt64, + }; + + public readonly typeName = 'Variant'; + + private typeID = new UInt8(); + private objectData: RVType; + + public extractFrom(stream: NEXByteStream): void { + this.typeID.extractFrom(stream); + + if (this.typeID.value !== 0 && Variant.Classes[this.typeID.value]) { + this.objectData = new Variant.Classes[this.typeID.value](); + + this.objectData.extractFrom(stream); + } + + // TODO - Error if not found + } + + public new(): Variant { + return new Variant(); + } + + private displayTypeName(): string { + return `Variant<${this.objectData.typeName}>`; + } + + public toJSON(): Record { + return { + __displayTypeName: this.displayTypeName(), + __typeName: this.typeName, + __value: this.objectData + }; + } +} \ No newline at end of file diff --git a/src/packet.js b/src/packet.js deleted file mode 100644 index 57cc157..0000000 --- a/src/packet.js +++ /dev/null @@ -1,297 +0,0 @@ -/** - * @typedef {import('./connection')} Connection - * @typedef {import('./stream')} Stream - */ - -class Packet { - static FLAGS = { - ACK: 0x001, - RELIABLE: 0x002, - NEED_ACK: 0x004, - HAS_SIZE: 0x008, - MULTI_ACK: 0x200, - }; - - static TYPES = { - SYN: 0, - CONNECT: 1, - DATA: 2, - DISCONNECT: 3, - PING: 4, - USER: 5, - }; - - /** - * - * @param {Connection} connection NEX connection - * @param {Stream} stream Packet data stream - */ - constructor(connection, stream) { - this.connection = connection; - this.stream = stream; - this.isRawRMC = false; - - this.version; - this.source; - this.destination; - this.flags; - this.sessionId; - this.signature; - this.sequenceId; - this.connectionSignature; - this.fragmentId; - this.rmcMessage = { - isRequest() { - // * Stub for broken packets - return undefined; - }, - isSuccess() { - // * Stub for broken packets - return undefined; - } - }; - this.rmcData = {}; // * Decoded RMC body - this.stackTrace; // * Contains possible decoding errors - this.date = 0; - - if (this.decode && this.stream) { - this.decode(); - } - } - - /** - * @returns {object} JSON serialized data - */ - toJSON() { - const serialized = { - rawRMC: this.isRawRMC, - flags: [], - rmc: { - protocolName: this.rmcData.protocolName, - methodName: this.rmcData.methodName, - protocolId: this.rmcMessage.protocolId, - customId: this.rmcMessage.customId, - methodId: this.rmcMessage.methodId, - callId: this.rmcMessage.callId, - errorCode: this.rmcMessage.errorCode, - body: this.rmcData.body - }, - stackTrace: this.stackTrace - }; - - if (this.isRawRMC) { - serialized.server = this.connection.isSecureServer ? 'secure' : 'authentication'; - serialized.type = 'DATA'; - serialized.fragmentId = 0; - - serialized.rmc.isRequest = this.rmcMessage.isRequest(); - - if (serialized.rmc.isRequest === false) { - serialized.rmc.isSuccess = this.rmcMessage.isSuccess(); - } - } else { - serialized.version = this.version; - serialized.source = this.source; - serialized.destination = this.destination; - serialized.sessionId = this.sessionId; - serialized.signature = this.signature.toString('hex'); - serialized.sequenceId = this.sequenceId; - serialized.fragmentId = this.fragmentId; - serialized.checksum = this.checksum; - serialized.date = this.date; - - if (this.isToClient()) { - serialized.sourceAddress = this.connection.serverAddress; - serialized.destinationAddress = this.connection.clientAddress; - } else { - serialized.sourceAddress = this.connection.clientAddress; - serialized.destinationAddress = this.connection.serverAddress; - } - - if (this.isSyn()) { - serialized.type = 'SYN'; - } - - if (this.isConnect()) { - serialized.type = 'CONNECT'; - } - - if (this.isData()) { - serialized.type = 'DATA'; - serialized.fragmentId = this.fragmentId; - - serialized.rmc.isRequest = this.rmcMessage.isRequest(); - - if (serialized.fragmentId === 0 && serialized.rmc.isRequest === false) { - serialized.rmc.isSuccess = this.rmcMessage.isSuccess(); - } - } - - if (this.isDisconnect()) { - serialized.type = 'DISCONNECT'; - } - - if (this.isPing()) { - serialized.type = 'PING'; - } - - if (this.isUser()) { - serialized.type = 'USER'; - } - - if (this.hasFlagAck()) { - serialized.flags.push('ACK'); - } - - if (this.hasFlagReliable()) { - serialized.flags.push('RELIABLE'); - } - - if (this.hasFlagNeedAck()) { - serialized.flags.push('NEED_ACK'); - } - - if (this.hasFlagHasSize()) { - serialized.flags.push('HAS_SIZE'); - } - - if (this.hasFlagMultiAck()) { - serialized.flags.push('MULTI_ACK'); - } - } - - return serialized; - } - - /** - * - * @param {number} type NEX packet type - * @returns {boolean} True if is type - */ - isType(type) { - return this.type === type; - } - - /** - * - * @param {number} flag NEX packet flag - * @returns {boolean} True if has flag - */ - hasFlag(flag) { - return (this.flags & flag) !== 0; - } - - /** - * - * @returns {boolean} True if is type - */ - isSyn() { - return this.isType(Packet.TYPES.SYN); - } - - /** - * - * @returns {boolean} True if is type - */ - isConnect() { - return this.isType(Packet.TYPES.CONNECT); - } - - /** - * - * @returns {boolean} True if is type - */ - isData() { - return this.isType(Packet.TYPES.DATA); - } - - /** - * - * @returns {boolean} True if is type - */ - isDisconnect() { - return this.isType(Packet.TYPES.DISCONNECT); - } - - /** - * - * @returns {boolean} True if is type - */ - isPing() { - return this.isType(Packet.TYPES.PING); - } - - /** - * - * @returns {boolean} True if is type - */ - isUser() { - return this.isType(Packet.TYPES.USER); - } - - /** - * - * @returns {boolean} True if has flag - */ - hasFlagAck() { - return this.hasFlag(Packet.FLAGS.ACK); - } - - /** - * - * @returns {boolean} True if has flag - */ - hasFlagReliable() { - return this.hasFlag(Packet.FLAGS.RELIABLE); - } - - /** - * - * @returns {boolean} True if has flag - */ - hasFlagNeedAck() { - return this.hasFlag(Packet.FLAGS.NEED_ACK); - } - - /** - * - * @returns {boolean} True if has flag - */ - hasFlagHasSize() { - return this.hasFlag(Packet.FLAGS.HAS_SIZE); - } - - /** - * - * @returns {boolean} True if has flag - */ - hasFlagMultiAck() { - return this.hasFlag(Packet.FLAGS.MULTI_ACK); - } - - /** - * - * @returns {boolean} True if has flag - */ - isToClient() { - return (this.source & 0xF) === 0x1; - } - - /** - * - * @returns {boolean} True if has flag - */ - isToServer() { - return (this.source & 0xF) === 0xF; - } - - /** - * - * @returns {boolean} True if has flag - */ - hasFragments() { - return this.fragmentId !== 0; - } -} - -module.exports = Packet; diff --git a/src/packetv0.js b/src/packetv0.js deleted file mode 100644 index aceccd5..0000000 --- a/src/packetv0.js +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @typedef {import('./connection')} Connection - */ - -const Packet = require('./packet'); -const Stream = require('./stream'); - -class PacketV0 extends Packet { - /** - * - * @param {Connection} connection NEX connection - * @param {Stream} stream Packet data stream - */ - constructor(connection, stream) { - super(connection, stream); - - this.version = 0; - - this.checksum; - this.packetData; // * Used for easy checksum generation - } - - decode() { - const start = this.stream.pos(); - - this.source = this.stream.readUInt8(); - this.destination = this.stream.readUInt8(); - - // * Skip Quazal Net-Z packets - if ((this.source & 0xF) === (this.destination & 0xF)) { // * The source and destination ports are the same - throw new Error(`Source and destination ports are the same. Source ${this.source}, destination ${this.destination}`); - } - - if ((this.source & 0xF0) === 0x10) { // * Source uses DO stream type - throw new Error(`Source stream type is DO. Source ${this.source}`); - } - - if ((this.source & 0xF0) === 0x50) { // * Source uses NAT stream type - throw new Error(`Source stream type is NAT. Source ${this.source}`); - } - - if ((this.destination & 0xF0) === 0x10) { // * Destination uses DO stream type - throw new Error(`Destination stream type is DO. Destination ${this.destination}`); - } - - if ((this.destination & 0xF0) === 0x50) { // * Destination uses NAT stream type - throw new Error(`Destination stream type is DO. Destination ${this.destination}`); - } - - const typeAndFlags = this.stream.readUInt16LE(); - - this.flags = typeAndFlags >> 4; - this.type = typeAndFlags & 0xF; - - if (this.type > 4) { - throw new Error(`Invalid packet type. Expected 1-4, got ${this.type}`); - } - - if (this.flags > 15) { - throw new Error(`Invalid packet flags. Expected 0-15, got ${this.flags}`); - } - - this.sessionId = this.stream.readUInt8(); - this.signature = this.stream.readBytes(0x4); - this.sequenceId = this.stream.readUInt16LE(); - - if (this.isSyn() || this.isConnect()) { - this.connectionSignature = this.stream.readBytes(0x4); - } - - if (this.isData()) { - this.fragmentId = this.stream.readUInt8(); - } - - let payloadSize = 0; - - if (this.hasFlagHasSize()) { - payloadSize = this.stream.readUInt16LE(); - } else { - payloadSize = this.stream.remaining() - 1; - } - - if (payloadSize > (this.stream.remaining() - 1)) { - throw new Error(`Packet payload too large. Payload space left is ${this.stream.remaining() - 1}, got ${payloadSize}`); - } - - this.payload = this.stream.readBytes(payloadSize); - - const end = this.stream.pos(); - - // * Quick hack to be used in packet calculation - // * so we don't have to build this buffer again - this.packetData = this.stream._buffer.subarray(start, end); - - this.checksum = this.stream.readUInt8(); - - if (this.isSyn() && this.isToServer()) { - if (!this.connection.isSecureServer) { - this.connection.reset(); - } else { - this.connection.serverConnectionSignature = Buffer.alloc(0); - this.connection.clientConnectionSignature = Buffer.alloc(0); - } - } - - if (this.connection.accessKey) { - // * Found access key, can now check packet checksum - const calculatedChecksum = this.calculateChecksum(); - if (calculatedChecksum !== this.checksum) { - throw new Error(`Invalid PRUDPv0 packet checksum. Expected ${this.checksum}, got ${calculatedChecksum}`); - } - } - } - - calculateChecksum(key) { - /** - * - * @param {Buffer} buffer Buffer to sum - * @returns {number} sum - */ - function sum(buffer) { - return buffer.reduce((sum, byte) => sum + byte, 0); - } - - let base = this.connection.accessKeySum.readUint32LE(); - - if (key) { - // * If key is set, use that instead - base = sum(Buffer.from(key)); - } - - const data = this.packetData; - - const numWords = Math.floor(data.length / 4); - const words = []; - - for (let i = 0; i < numWords; i++) { - words.push(data.readUInt32LE(i * 4)); - } - - const temp = sum(words) >>> 0; // Truncate to 32-bit integer - - const buffer = Buffer.alloc(4); - buffer.writeUInt32LE(temp); - - const checksum = base + sum(data.subarray(data.length & ~3)) + sum(buffer); - - return checksum & 0xFF; - } -} - -module.exports = PacketV0; diff --git a/src/packetv1.js b/src/packetv1.js deleted file mode 100644 index ff14895..0000000 --- a/src/packetv1.js +++ /dev/null @@ -1,186 +0,0 @@ -/** - * @typedef {import('./connection')} Connection - */ - -const crypto = require('crypto'); -const Packet = require('./packet'); -const Stream = require('./stream'); -const { md5 } = require('./util'); - -const OPTION_SUPPORTED_FUNCTIONS = 0; -const OPTION_CONNECTION_SIGNATURE = 1; -const OPTION_FRAGMENT_ID = 2; -const OPTION_INITIAL_SEQUENCE_ID = 3; -const OPTION_MAX_SUBSTREAM_ID = 4; - -class PacketV1 extends Packet { - /** - * - * @param {Connection} connection NEX connection - * @param {Stream} stream Packet data stream - */ - constructor(connection, stream) { - super(connection, stream); - - this.version = 1; - this.headerStream; // * Used for easy signature generation - this.substreamId; - this.prudpProtocolMinorVersion; - this.supportedFunctions; - this.initialSequenceId; - this.maximumSubstreamId; - this.packetSpecificData; - } - - decode() { - this.stream.skip(0x2); // * Skip the magic - - this.headerStream = new Stream(this.stream.readBytes(0xC)); - - this.headerStream.skip(0x1); // * Skip the PRUDP version, always 1 - - const packetSpecificDataLength = this.headerStream.readUInt8(); - const payloadSize = this.headerStream.readUInt16LE(); - - this.source = this.headerStream.readUInt8(); - this.destination = this.headerStream.readUInt8(); - - // * Skip Quazal Net-Z packets - if ((this.source & 0xF) === (this.destination & 0xF)) { // * The source and destination ports are the same - throw new Error(`Source and destination ports are the same. Source ${this.source}, destination ${this.destination}`); - } - - if ((this.source & 0xF0) === 0x10) { // * Source uses DO stream type - throw new Error(`Source stream type is DO. Source ${this.source}`); - } - - if ((this.source & 0xF0) === 0x50) { // * Source uses NAT stream type - throw new Error(`Source stream type is NAT. Source ${this.source}`); - } - - if ((this.destination & 0xF0) === 0x10) { // * Destination uses DO stream type - throw new Error(`Destination stream type is DO. Destination ${this.destination}`); - } - - if ((this.destination & 0xF0) === 0x50) { // * Destination uses NAT stream type - throw new Error(`Destination stream type is DO. Destination ${this.destination}`); - } - - const typeAndFlags = this.headerStream.readUInt16LE(); - - this.flags = typeAndFlags >> 4; - this.type = typeAndFlags & 0xF; - - this.sessionId = this.headerStream.readUInt8(); - this.substreamId = this.headerStream.readUInt8(); - this.sequenceId = this.headerStream.readUInt16LE(); - - this.signature = this.stream.readBytes(0x10); - this.packetSpecificData = this.stream.readBytes(packetSpecificDataLength); - - this.parsePacketSpecificData(); - - this.payload = this.stream.readBytes(payloadSize); - - if (this.isSyn() && this.isToServer()) { - if (!this.connection.isSecureServer) { - this.connection.reset(); - } else { - this.connection.serverConnectionSignature = Buffer.alloc(0); - this.connection.clientConnectionSignature = Buffer.alloc(0); - } - } - - if (this.connection.accessKey) { - // * Found access key, can now check packet signature - const calculatedSignature = this.calculateSignature(); - if (!calculatedSignature.equals(this.signature)) { - throw new Error(`Invalid PRUDPv1 packet signature. Expected ${this.signature}, got ${calculatedSignature}`); - } - } - } - - parsePacketSpecificData() { - const packetSpecificDataStream = new Stream(this.packetSpecificData); - - while (packetSpecificDataStream.hasDataLeft()) { - const optionId = packetSpecificDataStream.readUInt8(); - const optionSize = packetSpecificDataStream.readUInt8(); - - switch (optionId) { - case OPTION_SUPPORTED_FUNCTIONS: { - const optionData = packetSpecificDataStream.readUInt32LE(); - this.prudpProtocolMinorVersion = optionData & 0xFF; - this.supportedFunctions = optionData >> 8; - break; - } - case OPTION_CONNECTION_SIGNATURE: - this.connectionSignature = packetSpecificDataStream.readBytes(optionSize); - break; - case OPTION_FRAGMENT_ID: - this.fragmentId = packetSpecificDataStream.readUInt8(); - break; - case OPTION_INITIAL_SEQUENCE_ID: - this.initialSequenceId = packetSpecificDataStream.readUInt16LE(); - break; - case OPTION_MAX_SUBSTREAM_ID: - this.maximumSubstreamId = packetSpecificDataStream.readUInt8(); - break; - } - } - } - - /** - * - * @param {string} [key] Optional access key - * @returns {Buffer} PRUDPv1 packet signature - */ - calculateSignature(key) { - let signatureKey = this.connection.signatureKey; - let accessKeySum = this.connection.accessKeySum; - let sessionKey = this.connection.sessionKey; - let connectionSignature; - - if (!this.connection.isSecureServer || this.isSyn() || this.isConnect()) { - // * Assume authentication server - // * Session key not used in auth server - - // * Also don't use if SYN or CONN packet, - // * but this is not standard. It's a hack - sessionKey = Buffer.alloc(0); - } - - if (key) { - // * If key is set, use that instead - signatureKey = md5(key); - accessKeySum = Buffer.alloc(4); - - const keyBuffer = Buffer.from(key); - const accessKeySumInt = keyBuffer.reduce((sum, byte) => sum + byte, 0); - accessKeySum.writeUInt32LE(accessKeySumInt); - } - - if (this.isToServer()) { - // * client->server packet - // * Verify using the *SERVER* connection signature - connectionSignature = this.connection.serverConnectionSignature; - } else { - // * server->client packet - // * Verify using the *CLIENT* connection signature - connectionSignature = this.connection.clientConnectionSignature; - } - - const hmac = crypto.createHmac('md5', signatureKey); - - hmac.update(this.headerStream._buffer.subarray(0x4, 0xC)); - hmac.update(sessionKey); - hmac.update(accessKeySum); - hmac.update(connectionSignature); - hmac.update(this.packetSpecificData); - hmac.update(this.payload); - - return hmac.digest(); - } -} - -module.exports = PacketV1; diff --git a/src/parser.js b/src/parser.js deleted file mode 100644 index b7061fb..0000000 --- a/src/parser.js +++ /dev/null @@ -1,365 +0,0 @@ -const EventEmitter = require('node:events'); -const path = require('node:path'); -const fs = require('node:fs'); -const isPrivateIP = require('private-ip'); -const PCAPParser = require('./pcap-parser'); -const PCAPNGParser = require('./pcapng-parser'); -const PacketV0 = require('./packetv0'); -const PacketV1 = require('./packetv1'); -const Connection = require('./connection'); -const Authentication = require('./protocols/authentication'); -const Stream = require('./stream'); - -// ! NOTE - -// ! PRUDPv0 does not have magics -// ! Nintendo uses standardized source/destinations with NEX -// ! Checking the source/destination can tell us if it's v0 -const PRUDP_V1_MAGIC = Buffer.from([0xEA, 0xD0]); - -// * Magics to check for when parsing UDP packets -//const XID_MAGIC = Buffer.from([0x81, 0x01, 0x0]); - -class NEXParser extends EventEmitter { - constructor() { - super(); - - this.connections = []; - this.rawRMCMode = false; - this.rawRMCPackets = []; - this.rawRMCDummyConnection = new Connection(); // * Used for creating fake packets - this.rawRMCAuthenticationConnection = new Connection(); // * Used to store packets to the authentication server - this.rawRMCAuthenticationConnection.discriminator = 'authentication'; - this.rawRMCSecureConnection = new Connection(); // * Used to store packets to the secure server - this.rawRMCSecureConnection.isSecureServer = true; - this.rawRMCSecureConnection.discriminator = 'secure'; - } - - setRawRMCMode(enabled) { - this.rawRMCMode = enabled; - } - - /** - * - * @param {string} capturePath Path to the PCAP(NG) capture file - */ - parse(capturePath) { - const extension = path.extname(capturePath); - - if (extension !== '.pcapng' && extension !== '.pcap') { - throw new Error(`Invalid file type. Got ${extension}, expected .pcapng or .pcap`); - } - - const captureData = fs.readFileSync(capturePath); - let parser; - - const magic = captureData.readUInt32LE(); - - if (magic === 0xA1B2C3D4 || magic === 0xD4C3B2A1) { - parser = new PCAPParser(captureData); - } else if (magic === 0x0A0D0D0A) { - parser = new PCAPNGParser(captureData); - } else { - throw new Error('Invalid capture'); - } - - for (const packet of parser.packets()) { - this.handlePacket(packet); - } - - this.parserEnd(); - } - - /** - * Ran when the pcap(ng) parser is finished - */ - parserEnd() { - if (this.rawRMCMode) { - this.connections = [ - this.rawRMCAuthenticationConnection, - this.rawRMCSecureConnection, - ]; - } - - this.emit('connections', this.connections); - } - - /** - * - * @param {object} raw Raw network packet - */ - handlePacket(raw) { - // * HokakuCTR produces dumps whose payloads are: - // * - u8 Revision (1) - // * - u64 Title ID - // * By checking if the first byte is a supported - // * revision and that the following u64 is a 3DS - // * title we can be reasonably sure the dump is - // * a HokakuCTR dump. - // * We only need the first 3 bytes of the u64 - if (raw.data[0] === 1 && (raw.data.readBigUInt64LE(1) & 0xFFFFFF0000000000n) === 0x0004000000000000n) { - this.setRawRMCMode(true); - this.handleRawRMC(raw.data); - return; - } - - const udpPacket = this.parsePacketFrame(raw.data); - - if (!udpPacket) { - return; - } - - // TODO - ON RARE OCCASIONS UDP PACKETS WHICH ARE NOT NEX BUT HAVE THE SAME HEADERS GET THROUGH - // ! FIND A WAY TO GET RID OF THESE - // ? For example, the following packet is an XID broadcast packet - // * 0000 ff ff ff ff ff ff fe e6 bf 25 b3 cd 00 06 00 01 - // * 0010 af 81 01 00 40 00 15 11 1e cd 34 26 51 eb c0 a8 - // * 0020 00 0d e9 fd f3 28 00 26 2e 52 ea d0 01 00 0f 16 - // * 0030 53 c0 88 42 e9 00 c2 00 1a 5c 1a 52 - // ? When decoded this packet has byte 24 set to 0x11 indicating a UDP packet - // ? Bytes 42-45 are also set to ea:d0:01, which just so happens to be the PRUDPv1 magic - // ? This packet gets treated as a PRUDPv1 packet as a result, even though it is not - - let discriminator; - let clientAddress; - let serverAddress; - - if (isPrivateIP(udpPacket.source)) { - // * client->server packet - discriminator = `${udpPacket.destination}:${udpPacket.destinationPort}`; - clientAddress = `${udpPacket.source}:${udpPacket.sourcePort}`; - serverAddress = discriminator; - } else { - // * server->client packet - discriminator = `${udpPacket.source}:${udpPacket.sourcePort}`; - clientAddress = `${udpPacket.destination}:${udpPacket.destinationPort}`; - serverAddress = discriminator; - } - - // * Find the latest connection to avoid broken packets - // * when disconnecting and reconnecting to the same server. - let connection = this.connections.findLast(connection => connection.discriminator === discriminator); - let newConnection = false; - - if (!connection) { - connection = new Connection(discriminator); - connection.clientAddress = clientAddress; - connection.serverAddress = serverAddress; - - newConnection = true; - } - - const stream = new Stream(udpPacket.payload); - - // * PRUDP may send multiple packets in a single UDP packet, so we read the UDP payload recursively - while (stream.hasDataLeft()) { - let packet; - - const magic = stream.readBytes(0x2); - stream.skip(-0x2); - - if (magic.equals(PRUDP_V1_MAGIC)) { - try { - packet = new PacketV1(connection, stream); - } catch (error) { - stream.readRest(); // * Dispose of the rest of the data in the stream - return; - } - } else { - // * Assume packet is v0 and just Try It - try { - // * THIS IS *EXPECTED* TO FAIL OFTEN! - // * PRUDPv0 DOES NOT HAVE A MAGIC LIKE v1! - // * OUR BEST OPTION IS TO GUESS - packet = new PacketV0(connection, stream); - } catch (error) { - stream.readRest(); // * Dispose of the rest of the data in the stream - return; - } - } - - if (packet.isSyn()) { - if (packet.isToClient() && !connection.doneClientSyn) { - // * SYN packet from the server without seeing one from the client yet - return; - } - - if (packet.isToServer()) { - connection.doneClientSyn = true; - } - - if (packet.isToClient()) { - connection.doneServerSyn = true; - } - } - - if (packet.isConnect()) { - if (!connection.doneClientSyn || !connection.doneServerSyn) { - // * CONNECT packet without completing the SYN sequence - return; - } - - if (packet.isToServer()) { - connection.doneClientConnect = true; - } - - if (packet.isToClient()) { - connection.doneServerConnect = true; - } - } - - if (packet.isData()) { - if (!connection.doneClientConnect || !connection.doneServerConnect) { - // * DATA packet without completing the CONNECT sequence - return; - } - } - - // * Add conenctions after packet validation - if (newConnection) { - this.connections.push(connection); - this.emit('connection', connection); - } - - connection.handlePacket(packet); - - if (connection.secureServerStationURL && connection.checkForSecureServer) { - const secureIP = connection.secureServerStationURL.address; - const securePort = connection.secureServerStationURL.port; - const secureDiscriminator = `${secureIP}:${securePort}`; - - if (connection.discriminator !== secureDiscriminator) { - // * Secure server on different address, make a new connection - const secureConnection = new Connection(secureDiscriminator); - - secureConnection.setRC4Key(connection.sessionKey); - secureConnection.accessKey = connection.accessKey; - secureConnection.accessKeySum = connection.accessKeySum; - secureConnection.signatureKey = connection.signatureKey; - secureConnection.sessionKey = connection.sessionKey; - secureConnection.prudpVersion = connection.prudpVersion; - secureConnection.title = connection.title; - secureConnection.isSecureServer = true; - - secureConnection.clientAddress = connection.clientAddress; - secureConnection.serverAddress = secureDiscriminator; - - this.connections.push(secureConnection); - } else { - // * Secure server is at the same address, just update key - connection.isSecureServer = true; - connection.setRC4Key(connection.sessionKey); - } - - connection.checkForSecureServer = false; - } - - packet.date = new Date(raw.timestamp.seconds * 1000); - - this.emit('packet', packet); - } - } - - /** - * - * @param {Buffer} data Raw RMC payload data from HokakuCTR - */ - handleRawRMC(data) { - // * Gonna use some shitty heuristics here - - // * Handle the data once in the dummy connection - this.rawRMCDummyConnection.handleRawRMC(data); - - let dummyPacket = this.rawRMCDummyConnection.packets[this.rawRMCDummyConnection.packets.length-1]; - let connection; - - // * Put the packet back into the right connection. - // * The authentication server ONLY provides the - // * Authentication protocol - if (dummyPacket.rmcMessage.protocolId === Authentication.ProtocolID) { - connection = this.rawRMCAuthenticationConnection; - } else { - connection = this.rawRMCSecureConnection; - } - - connection.handleRawRMC(data); - const packet = connection.packets[connection.packets.length-1]; - - this.emit('packet', packet); - } - - /** - * - * @param {Buffer} frame Raw packet bytes - * @returns {object} Carved out packet data or null if not valid UDP packet - */ - parsePacketFrame(frame) { - const stream = new Stream(frame); - - const versionAndHeaderLength = stream.readUInt8(); - const version = (versionAndHeaderLength >> 4) & 0x0F; - - // * All packets we care about are - // * assumed to be IPv4 - if (version !== 4) { - return; - } - - const headerLength = (versionAndHeaderLength & 0x0F) * 4; - - stream.skip(1); // * Service type - const totalLength = stream.readUInt16BE(); - stream.skip(2); // * Identification - stream.skip(2); // * Flags and fragment offset. Fragment offset is the last 13 bits (& 0x1FFF) - stream.skip(1); // * Time to live - const protocol = stream.readUInt8(); - stream.skip(2); // * Checksum - - const source = this.int2ip(stream.readUInt32BE()); - const destination = this.int2ip(stream.readUInt32BE()); - - // TODO - Add this back with the new offsets - //if (frame.subarray(17, 20).equals(XID_MAGIC)) { - // return; - //} - - if (protocol !== 0x11) { - return; - } - - const udpLength = totalLength - headerLength; - const udpStream = new Stream(stream.readBytes(udpLength)); - - // * Parse UDP header - const sourcePort = udpStream.readUInt16BE(); - const destinationPort = udpStream.readUInt16BE(); - const udpPacketLength = udpStream.readUInt16BE(); - - if (udpPacketLength !== udpLength) { - throw new Error(`Got bad UDP packet length. Expected ${udpLength}, got ${udpPacketLength}`); - } - - udpStream.skip(0x2); // * Checksum - - const payload = udpStream.readBytes(udpLength - 0x8); - - return { - source, - destination, - sourcePort, - destinationPort, - payload - }; - } - - /** - * - * @param {number} int IP int - * @returns {string} IP string - */ - int2ip(int) { - return `${int >>> 24}.${int >> 16 & 255}.${int >> 8 & 255}.${int & 255}`; - } -} - - -module.exports = NEXParser; diff --git a/src/pcap-parser.js b/src/pcap-parser.js deleted file mode 100644 index e31353d..0000000 --- a/src/pcap-parser.js +++ /dev/null @@ -1,110 +0,0 @@ -const Stream = require('./stream'); - -const LINKTYPE_ETHERNET = 0x0001; -const LINKTYPE_RAW = 0x0065; - -class PCAPParser { - #buffer; - #stream; - #be = false; - #packetStartOffset; - #linkLayerSize; - - versionMajor; - versionMinor; - thisZone; - sigfigs; - maxPacketLength; - linkLayerType; - - constructor(buffer) { - this.#buffer = buffer; - this.#stream = new Stream(this.#buffer); - - this.#parseHeader(); - } - - #readUInt16() { - if (!this.#be) { - return this.#stream.readUInt16LE(); - } else { - return this.#stream.readUInt16BE(); - } - } - - #readUInt32() { - if (!this.#be) { - return this.#stream.readUInt32LE(); - } else { - return this.#stream.readUInt32BE(); - } - } - - #readInt32() { - if (!this.#be) { - return this.#stream.readInt32LE(); - } else { - return this.#stream.readInt32BE(); - } - } - - #parseHeader() { - const magic = this.#readUInt32(); - - if (magic !== 0xA1B2C3D4 && magic !== 0xD4C3B2A1) { - const magicHex = magic.toString(16).toLocaleUpperCase(); - throw new Error(`Invalid PCAP magic. Expected either 0xA1B2C3D4 or 0xD4C3B2A1, got 0x${magicHex}`); - } - - if (magic !== 0xA1B2C3D4) { - this.#be = true; - } - - this.versionMajor = this.#readUInt16(); - this.versionMinor = this.#readUInt16(); - this.thisZone = this.#readInt32(); - this.sigfigs = this.#readUInt32(); - this.maxPacketLength = this.#readUInt32(); - this.linkLayerType = this.#readUInt32(); - - this.#packetStartOffset = this.#stream.pos(); - this.#linkLayerSize = this.#checkLinkLayerSize(); - } - - #checkLinkLayerSize() { - switch (this.linkLayerType) { - case LINKTYPE_ETHERNET: - return 14; - - case LINKTYPE_RAW: - return 0; - - default: - console.log(`Unsupported link layer type ${this.linkLayerType}`); - return 0; - } - } - - *packets() { - this.#stream.seek(this.#packetStartOffset); - - while (this.#stream.hasDataLeft()) { - const packet = { - timestamp: { - seconds: this.#readUInt32(), - microseconds: this.#readUInt32() - }, - storedLength: this.#readUInt32(), - realLength: this.#readUInt32() - }; - - this.#stream.skip(this.#linkLayerSize); - - packet.data = this.#stream.readBytes(packet.storedLength - this.#linkLayerSize); - - yield packet; - } - } -} - -module.exports = PCAPParser; \ No newline at end of file diff --git a/src/pcap-parser.ts b/src/pcap-parser.ts new file mode 100644 index 0000000..bc78e6a --- /dev/null +++ b/src/pcap-parser.ts @@ -0,0 +1,116 @@ +import ByteStream from '@/byte-stream'; +import type { Packet } from '@/types/pcap-parser'; + +const LINKTYPE_ETHERNET = 0x0001; +const LINKTYPE_RAW = 0x0065; + +const LINKTYPE_HOKAKUCTR = 0x0093; + +export default class PCAPParser { + private buffer: Buffer; + private stream: ByteStream; + private be = false; + private packetStartOffset: number; + private linkLayerSize: number; + + public versionMajor: number; + public versionMinor: number; + public thisZone: number; + public sigfigs: number; + public maxPacketLength: number; + public linkLayerType: number; + + constructor(buffer: Buffer) { + this.buffer = buffer; + this.stream = new ByteStream(this.buffer); + + this.parseHeader(); + } + + private readUInt16(): number { + if (!this.be) { + return this.stream.readUInt16LE(); + } else { + return this.stream.readUInt16BE(); + } + } + + private readUInt32(): number { + if (!this.be) { + return this.stream.readUInt32LE(); + } else { + return this.stream.readUInt32BE(); + } + } + + public readInt32(): number { + if (!this.be) { + return this.stream.readInt32LE(); + } else { + return this.stream.readInt32BE(); + } + } + + private parseHeader(): void { + const magic = this.readUInt32(); + + if (magic !== 0xA1B2C3D4 && magic !== 0xD4C3B2A1) { + const magicHex = magic.toString(16).toLocaleUpperCase(); + throw new Error(`Invalid PCAP magic. Expected either 0xA1B2C3D4 or 0xD4C3B2A1, got 0x${magicHex}`); + } + + if (magic !== 0xA1B2C3D4) { + this.be = true; + } + + this.versionMajor = this.readUInt16(); + this.versionMinor = this.readUInt16(); + this.thisZone = this.readInt32(); + this.sigfigs = this.readUInt32(); + this.maxPacketLength = this.readUInt32(); + this.linkLayerType = this.readUInt32(); + + this.packetStartOffset = this.stream.pos(); + this.linkLayerSize = this.checkLinkLayerSize(); + } + + private checkLinkLayerSize(): number { + switch (this.linkLayerType) { + case LINKTYPE_ETHERNET: + return 14; + + case LINKTYPE_RAW: + case LINKTYPE_HOKAKUCTR: + return 0; + + default: + console.log(`Unsupported link layer type ${this.linkLayerType}`); + return 0; + } + } + + public *packets(): Generator { + this.stream.seek(this.packetStartOffset); + + while (this.stream.hasDataLeft()) { + const timestampSeconds = this.readUInt32(); + const timestampMicroseconds = this.readUInt32(); + const storedLength = this.readUInt32(); + const realLength = this.readUInt32(); + + this.stream.skip(this.linkLayerSize); + + const data = this.stream.readBytes(storedLength - this.linkLayerSize); + + yield { + timestamp: { + seconds: timestampSeconds, + microseconds: timestampMicroseconds + }, + storedLength, + realLength, + data + }; + } + } +} \ No newline at end of file diff --git a/src/pcapng-parser.js b/src/pcapng-parser.js deleted file mode 100644 index 74fdb96..0000000 --- a/src/pcapng-parser.js +++ /dev/null @@ -1,384 +0,0 @@ -const Stream = require('./stream'); - -const BLOCK_TYPE_SECTION_HEADER = 0x0A0D0D0A; -const BLOCK_TYPE_INTERFACE_DESCRIPTION = 0x00000001; -const BLOCK_TYPE_ENHANCED_PACKET = 0x00000006; -const BLOCK_TYPE_SIMPLE_PACKET = 0x00000003; -const BLOCK_TYPE_NAME_RESOLUTION = 0x00000004; -const BLOCK_TYPE_INTERFACE_STATISTICS = 0x00000005; -const BLOCK_TYPE_CUSTOM_1 = 0x00000BAD; -const BLOCK_TYPE_CUSTOM_2 = 0x40000BAD; - -const LINKTYPE_ETHERNET = 0x0001; - -class PCAPNGParser { - #buffer; - #stream; - #currentSection; - - constructor(buffer) { - this.#buffer = buffer; - this.#stream = new Stream(this.#buffer); - } - - #readUInt16() { - if (!this.#currentSection || !this.#currentSection.be) { - return this.#stream.readUInt16LE(); - } else { - return this.#stream.readUInt16BE(); - } - } - - #readUInt32() { - if (!this.#currentSection || !this.#currentSection.be) { - return this.#stream.readUInt32LE(); - } else { - return this.#stream.readUInt32BE(); - } - } - - #parseOptionalData(optionsLength) { - const options = new Map(); - const optionsEnd = this.#stream.pos() + optionsLength; - - while (this.#stream.pos() != optionsEnd) { - const optionCode = this.#readUInt16(); - const optionLength = this.#readUInt16(); - const padding = (4 - (optionLength % 4)) % 4; - const optionData = this.#stream.readBytes(optionLength); - - this.#stream.skip(padding); - - options.set(optionCode, optionData); - } - - return options; - } - - // * BLOCK PARSERS - - #parseSectionHeaderBlock() { - const blockStart = this.#stream.pos(); - const magic = this.#readUInt32(); - - if (magic !== BLOCK_TYPE_SECTION_HEADER) { - const expected = BLOCK_TYPE_SECTION_HEADER.toString(16).toLocaleUpperCase(); - const magicHex = magic.toString(16).toLocaleUpperCase(); - throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); - } - - const blockLength = this.#readUInt32(); - const bom = this.#readUInt32(); - - if (bom !== 0x1A2B3C4D && bom !== 0x4D3C2B1A) { - const bomHex = magic.toString(16).toLocaleUpperCase(); - throw new Error(`Invalid SHB BOM. Expected either 0x1A2B3C4D or 0x4D3C2B1A, got 0x${bomHex}`); - } - - const section = { - be: bom === 0x4D3C2B1A, - opt: [], // * Optional data. Unused at the moment - interfaces: [], - versionMajor: this.#readUInt16(), - versionMinor: this.#readUInt16() - }; - - this.#stream.skip(8); // * Length of all the data (blocks) in this section, for skipping. We never skip whole sections - - const optionsLength = (blockStart + blockLength - 4) - this.#stream.pos(); - - section.options = this.#parseOptionalData(optionsLength); - - const blockLength2 = this.#readUInt32(); - - if (blockLength !== blockLength2) { - throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); - } - - return section; - } - - #parseInterfaceDescriptionBlock() { - const blockStart = this.#stream.pos(); - const magic = this.#readUInt32(); - - if (magic !== BLOCK_TYPE_INTERFACE_DESCRIPTION) { - const expected = BLOCK_TYPE_INTERFACE_DESCRIPTION.toString(16).toLocaleUpperCase(); - const magicHex = magic.toString(16).toLocaleUpperCase(); - throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); - } - - const blockLength = this.#readUInt32(); - - const interfaceDescription = { - linkLayerType: this.#readUInt16(), - reserved: this.#readUInt16(), // * Unused - maxPacketLength: this.#readUInt32() - }; - - const optionsLength = (blockStart + blockLength - 4) - this.#stream.pos(); - - interfaceDescription.options = this.#parseOptionalData(optionsLength); - - const blockLength2 = this.#readUInt32(); - - if (blockLength !== blockLength2) { - throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); - } - - return interfaceDescription; - } - - #parseEnhancedPacketBlock() { - const blockStart = this.#stream.pos(); - const magic = this.#readUInt32(); - - if (magic !== BLOCK_TYPE_ENHANCED_PACKET) { - const expected = BLOCK_TYPE_ENHANCED_PACKET.toString(16).toLocaleUpperCase(); - const magicHex = magic.toString(16).toLocaleUpperCase(); - throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); - } - - const blockLength = this.#readUInt32(); - - const enhancedPacket = { - interfaceID: this.#readUInt32(), - timestamp: { - high: this.#readUInt32(), - low: this.#readUInt32() - }, - storedLength: this.#readUInt32(), - realLength: this.#readUInt32() - }; - - const interfaceDescription = this.#currentSection.interfaces[enhancedPacket.interfaceID]; - let interfaceDataLength = 0; - - switch (interfaceDescription.linkLayerType) { - case LINKTYPE_ETHERNET: - enhancedPacket.interface = this.#parseInterfaceEthernet(); - interfaceDataLength = 14; - break; - - default: - throw new Error(`Unsupported interface type 0x${interfaceDescription.linkLayerType.toString(16).toLocaleUpperCase()}`); - } - - enhancedPacket.data = this.#stream.readBytes(enhancedPacket.storedLength - interfaceDataLength); - - const timestampResolutionData = interfaceDescription.options.get(0x9); - let timestampResolution = 6; // * Default if no if_tsresol option set in the interface - - if (timestampResolutionData) { - timestampResolution = timestampResolutionData.readUInt8(); - } - - const timestamp = (BigInt(enhancedPacket.timestamp.high) << 32n) | BigInt(enhancedPacket.timestamp.low); - const isMSBSet = (timestampResolution & 0x80) !== 0; - const resolutionBits = timestampResolution & 0x7F; - - enhancedPacket.timestamp.seconds = isMSBSet - ? Number(timestamp) * Math.pow(2, -resolutionBits) - : Number(timestamp) * Math.pow(10, -resolutionBits); - - const padding = (4 - (enhancedPacket.storedLength % 4)) % 4; - - this.#stream.skip(padding); - - const optionsLength = (blockStart + blockLength - 4) - this.#stream.pos(); - enhancedPacket.options = this.#parseOptionalData(optionsLength); - - const blockLength2 = this.#readUInt32(); - - if (blockLength !== blockLength2) { - throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); - } - - return enhancedPacket; - } - - #parseSimplePacketBlock() { - const magic = this.#readUInt32(); - - if (magic !== BLOCK_TYPE_SIMPLE_PACKET) { - const expected = BLOCK_TYPE_SIMPLE_PACKET.toString(16).toLocaleUpperCase(); - const magicHex = magic.toString(16).toLocaleUpperCase(); - throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); - } - - const blockLength = this.#readUInt32(); - - const simplePacket = { - timestampHigh: 0, // * Not present in SPBs - timestampLow: 0, // * Not present in SPBs - storedLength: blockLength - 16, // * Derive from the block length minus the 4 u32 sections - realLength: this.#readUInt32() - }; - - // * From the docs: - // * - // * The Simple Packet Block does not contain the Interface ID field. - // * Therefore, it MUST be assumed that all the Simple Packet Blocks - // * have been captured on the interface previously specified in the - // * first Interface Description Block. - const interfaceDescription = this.#currentSection.interfaces[0]; - let interfaceDataLength = 0; - - switch (interfaceDescription.linkLayerType) { - case LINKTYPE_ETHERNET: - simplePacket.interface = this.#parseInterfaceEthernet(); - interfaceDataLength = 14; - break; - - default: - throw new Error(`Unsupported interface type 0x${interfaceDescription.linkLayerType.toString(16).toLocaleUpperCase()}`); - } - - simplePacket.data = this.#stream.readBytes(simplePacket.storedLength - interfaceDataLength); - - // * Block has no optional data - - const blockLength2 = this.#readUInt32(); - - if (blockLength !== blockLength2) { - throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); - } - - return simplePacket; - } - - #parseNameResolutionBlock() { - const blockStart = this.#stream.pos(); - const magic = this.#readUInt32(); - - if (magic !== BLOCK_TYPE_NAME_RESOLUTION) { - const expected = BLOCK_TYPE_NAME_RESOLUTION.toString(16).toLocaleUpperCase(); - const magicHex = magic.toString(16).toLocaleUpperCase(); - throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); - } - - const blockLength = this.#readUInt32(); - - // * Skip this whole block. We don't need this data - // * Only implemented to prevent a crash - - this.#stream.seek((blockStart + blockLength) - 4); - - const blockLength2 = this.#readUInt32(); - - if (blockLength !== blockLength2) { - throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); - } - } - - #parseInterfaceStatisticsBlock() { - const blockStart = this.#stream.pos(); - const magic = this.#readUInt32(); - - if (magic !== BLOCK_TYPE_INTERFACE_STATISTICS) { - const expected = BLOCK_TYPE_INTERFACE_STATISTICS.toString(16).toLocaleUpperCase(); - const magicHex = magic.toString(16).toLocaleUpperCase(); - throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); - } - - const blockLength = this.#readUInt32(); - - // * Skip this whole block. We don't need this data - // * Only implemented to prevent a crash - - this.#stream.seek((blockStart + blockLength) - 4); - - const blockLength2 = this.#readUInt32(); - - if (blockLength !== blockLength2) { - throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); - } - } - - #parseCustomBlock() { - const blockStart = this.#stream.pos(); - const magic = this.#readUInt32(); - - if (magic !== BLOCK_TYPE_CUSTOM_1 && magic !== BLOCK_TYPE_CUSTOM_2) { - const expected1 = BLOCK_TYPE_CUSTOM_1.toString(16).toLocaleUpperCase(); - const expected2 = BLOCK_TYPE_CUSTOM_2.toString(16).toLocaleUpperCase(); - const magicHex = magic.toString(16).toLocaleUpperCase(); - throw new Error(`Invalid PCAP magic. Expected either 0x${expected1} or 0x${expected2}, got 0x${magicHex}`); - } - - const blockLength = this.#readUInt32(); - - // * Skip this whole block. We don't need this data - // * Only implemented to prevent a crash - - this.#stream.seek((blockStart + blockLength) - 4); - - const blockLength2 = this.#readUInt32(); - - if (blockLength !== blockLength2) { - throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); - } - } - - // * INTERFACE PARSERS - - #parseInterfaceEthernet() { - return { - type: LINKTYPE_ETHERNET, - data: { - destinationMAC: this.#stream.readBytes(6).toString('hex'), - sourceMAC: this.#stream.readBytes(6).toString('hex'), - type: this.#stream.readUInt8() * 256 + this.#stream.readUInt8() - } - }; - } - - *packets() { - this.#stream.seek(0); // * Make sure we're always at the start - - while (this.#stream.hasDataLeft()) { - const magic = this.#readUInt32(); - - // * Skip back so the block parsers can have the right start position. - // * Makes the block parsers follow the docs layout better rather than - // * skipping the magic read - this.#stream.skip(-4); - - switch (magic) { - case BLOCK_TYPE_SECTION_HEADER: - this.#currentSection = this.#parseSectionHeaderBlock(); - break; - - case BLOCK_TYPE_INTERFACE_DESCRIPTION: - this.#currentSection.interfaces.push(this.#parseInterfaceDescriptionBlock()); - break; - - case BLOCK_TYPE_ENHANCED_PACKET: - yield this.#parseEnhancedPacketBlock(); - break; - - case BLOCK_TYPE_SIMPLE_PACKET: - yield this.#parseSimplePacketBlock(); - break; - - case BLOCK_TYPE_NAME_RESOLUTION: - this.#parseNameResolutionBlock(); - break; - - case BLOCK_TYPE_INTERFACE_STATISTICS: - this.#parseInterfaceStatisticsBlock(); - break; - - case BLOCK_TYPE_CUSTOM_1: - case BLOCK_TYPE_CUSTOM_2: - this.#parseCustomBlock(); - break; - - default: - throw new Error(`Unsupported block type 0x${magic.toString(16).toLocaleUpperCase()}`); - } - } - } -} - -module.exports = PCAPNGParser; \ No newline at end of file diff --git a/src/pcapng-parser.ts b/src/pcapng-parser.ts new file mode 100644 index 0000000..771b234 --- /dev/null +++ b/src/pcapng-parser.ts @@ -0,0 +1,400 @@ +import ByteStream from '@/byte-stream'; +import type { + SectionHeaderBlock, + InterfaceDescriptionBlock, + EnhancedPacketBlock, + SimplePacketBlock, + EthernetInterface +} from '@/types/pcapng-parser'; + +const BLOCK_TYPE_SECTION_HEADER = 0x0A0D0D0A; +const BLOCK_TYPE_INTERFACE_DESCRIPTION = 0x00000001; +const BLOCK_TYPE_ENHANCED_PACKET = 0x00000006; +const BLOCK_TYPE_SIMPLE_PACKET = 0x00000003; +const BLOCK_TYPE_NAME_RESOLUTION = 0x00000004; +const BLOCK_TYPE_INTERFACE_STATISTICS = 0x00000005; +const BLOCK_TYPE_CUSTOM_1 = 0x00000BAD; +const BLOCK_TYPE_CUSTOM_2 = 0x40000BAD; + +const LINKTYPE_ETHERNET = 0x0001; + +export default class PCAPNGParser { + private buffer: Buffer; + private stream: ByteStream; + private currentSection: SectionHeaderBlock; + + constructor(buffer: Buffer) { + this.buffer = buffer; + this.stream = new ByteStream(this.buffer); + } + + private readUInt16(): number { + if (!this.currentSection || !this.currentSection.be) { + return this.stream.readUInt16LE(); + } else { + return this.stream.readUInt16BE(); + } + } + + private readUInt32(): number { + if (!this.currentSection || !this.currentSection.be) { + return this.stream.readUInt32LE(); + } else { + return this.stream.readUInt32BE(); + } + } + + private parseOptionalData(optionsLength: number): Map { + const options = new Map(); + const optionsEnd = this.stream.pos() + optionsLength; + + while (this.stream.pos() != optionsEnd) { + const optionCode = this.readUInt16(); + const optionLength = this.readUInt16(); + const padding = (4 - (optionLength % 4)) % 4; + const optionData = this.stream.readBytes(optionLength); + + this.stream.skip(padding); + + options.set(optionCode, optionData); + } + + return options; + } + + // * BLOCK PARSERS + + private parseSectionHeaderBlock(): SectionHeaderBlock { + const blockStart = this.stream.pos(); + const magic = this.readUInt32(); + + if (magic !== BLOCK_TYPE_SECTION_HEADER) { + const expected = BLOCK_TYPE_SECTION_HEADER.toString(16).toLocaleUpperCase(); + const magicHex = magic.toString(16).toLocaleUpperCase(); + throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); + } + + const blockLength = this.readUInt32(); + const bom = this.readUInt32(); + + if (bom !== 0x1A2B3C4D && bom !== 0x4D3C2B1A) { + const bomHex = magic.toString(16).toLocaleUpperCase(); + throw new Error(`Invalid SHB BOM. Expected either 0x1A2B3C4D or 0x4D3C2B1A, got 0x${bomHex}`); + } + + const versionMajor = this.readUInt16(); + const versionMinor = this.readUInt16(); + + this.stream.skip(8); // * Length of all the data (blocks) in this section, for skipping. We never skip whole sections + + const optionsLength = (blockStart + blockLength - 4) - this.stream.pos(); + + const options = this.parseOptionalData(optionsLength); + + const blockLength2 = this.readUInt32(); + + if (blockLength !== blockLength2) { + throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); + } + + return { + be: bom === 0x4D3C2B1A, + interfaces: [], + versionMajor, + versionMinor, + options + }; + } + + private parseInterfaceDescriptionBlock(): InterfaceDescriptionBlock { + const blockStart = this.stream.pos(); + const magic = this.readUInt32(); + + if (magic !== BLOCK_TYPE_INTERFACE_DESCRIPTION) { + const expected = BLOCK_TYPE_INTERFACE_DESCRIPTION.toString(16).toLocaleUpperCase(); + const magicHex = magic.toString(16).toLocaleUpperCase(); + throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); + } + + const blockLength = this.readUInt32(); + const linkLayerType = this.readUInt16(); + const reserved = this.readUInt16(); // * Unused + const maxPacketLength = this.readUInt32(); + + const optionsLength = (blockStart + blockLength - 4) - this.stream.pos(); + + const options = this.parseOptionalData(optionsLength); + + const blockLength2 = this.readUInt32(); + + if (blockLength !== blockLength2) { + throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); + } + + return { + linkLayerType, + reserved, + maxPacketLength, + options + }; + } + + private parseEnhancedPacketBlock(): EnhancedPacketBlock { + const blockStart = this.stream.pos(); + const magic = this.readUInt32(); + + if (magic !== BLOCK_TYPE_ENHANCED_PACKET) { + const expected = BLOCK_TYPE_ENHANCED_PACKET.toString(16).toLocaleUpperCase(); + const magicHex = magic.toString(16).toLocaleUpperCase(); + throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); + } + + const blockLength = this.readUInt32(); + const interfaceID = this.readUInt32(); + const timestampHigh = this.readUInt32(); + const timestampLow = this.readUInt32(); + const storedLength = this.readUInt32(); + const realLength = this.readUInt32(); + + const interfaceDescription = this.currentSection.interfaces[interfaceID]; + let interfaceDataLength = 0; + let networkInterface; + + switch (interfaceDescription.linkLayerType) { + case LINKTYPE_ETHERNET: + networkInterface = this.parseInterfaceEthernet(); + interfaceDataLength = 14; + break; + + default: + throw new Error(`Unsupported interface type 0x${interfaceDescription.linkLayerType.toString(16).toLocaleUpperCase()}`); + } + + const data = this.stream.readBytes(storedLength - interfaceDataLength); + + const timestampResolutionData = interfaceDescription.options.get(0x9); + let timestampResolution = 6; // * Default if no if_tsresol option set in the interface + + if (timestampResolutionData) { + timestampResolution = timestampResolutionData.readUInt8(); + } + + const timestamp = (BigInt(timestampHigh) << 32n) | BigInt(timestampLow); + const isMSBSet = (timestampResolution & 0x80) !== 0; + const resolutionBits = timestampResolution & 0x7F; + + const timestampSeconds = isMSBSet + ? Number(timestamp) * Math.pow(2, -resolutionBits) + : Number(timestamp) * Math.pow(10, -resolutionBits); + + const padding = (4 - (storedLength % 4)) % 4; + + this.stream.skip(padding); + + const optionsLength = (blockStart + blockLength - 4) - this.stream.pos(); + const options = this.parseOptionalData(optionsLength); + + const blockLength2 = this.readUInt32(); + + if (blockLength !== blockLength2) { + throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); + } + + return { + interfaceID, + timestamp: { + high: timestampHigh, + low: timestampLow, + sectonds: timestampSeconds + }, + storedLength, + realLength, + interface: networkInterface, + options, + data + }; + } + + private parseSimplePacketBlock(): SimplePacketBlock { + const magic = this.readUInt32(); + + if (magic !== BLOCK_TYPE_SIMPLE_PACKET) { + const expected = BLOCK_TYPE_SIMPLE_PACKET.toString(16).toLocaleUpperCase(); + const magicHex = magic.toString(16).toLocaleUpperCase(); + throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); + } + + const blockLength = this.readUInt32(); + const realLength = this.readUInt32(); + const storedLength = blockLength - 16; + + // * From the docs: + // * + // * The Simple Packet Block does not contain the Interface ID field. + // * Therefore, it MUST be assumed that all the Simple Packet Blocks + // * have been captured on the interface previously specified in the + // * first Interface Description Block. + const interfaceDescription = this.currentSection.interfaces[0]; + let interfaceDataLength = 0; + let networkInterface; + + switch (interfaceDescription.linkLayerType) { + case LINKTYPE_ETHERNET: + networkInterface = this.parseInterfaceEthernet(); + interfaceDataLength = 14; + break; + + default: + throw new Error(`Unsupported interface type 0x${interfaceDescription.linkLayerType.toString(16).toLocaleUpperCase()}`); + } + + const data = this.stream.readBytes(storedLength - interfaceDataLength); + + // * Block has no optional data + + const blockLength2 = this.readUInt32(); + + if (blockLength !== blockLength2) { + throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); + } + + return { + realLength, + interface: networkInterface, + data: data, + }; + } + + private parseNameResolutionBlock(): void { + const blockStart = this.stream.pos(); + const magic = this.readUInt32(); + + if (magic !== BLOCK_TYPE_NAME_RESOLUTION) { + const expected = BLOCK_TYPE_NAME_RESOLUTION.toString(16).toLocaleUpperCase(); + const magicHex = magic.toString(16).toLocaleUpperCase(); + throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); + } + + const blockLength = this.readUInt32(); + + // * Skip this whole block. We don't need this data + // * Only implemented to prevent a crash + + this.stream.seek((blockStart + blockLength) - 4); + + const blockLength2 = this.readUInt32(); + + if (blockLength !== blockLength2) { + throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); + } + } + + private parseInterfaceStatisticsBlock(): void { + const blockStart = this.stream.pos(); + const magic = this.readUInt32(); + + if (magic !== BLOCK_TYPE_INTERFACE_STATISTICS) { + const expected = BLOCK_TYPE_INTERFACE_STATISTICS.toString(16).toLocaleUpperCase(); + const magicHex = magic.toString(16).toLocaleUpperCase(); + throw new Error(`Invalid PCAP magic. Expected 0x${expected}, got 0x${magicHex}`); + } + + const blockLength = this.readUInt32(); + + // * Skip this whole block. We don't need this data + // * Only implemented to prevent a crash + + this.stream.seek((blockStart + blockLength) - 4); + + const blockLength2 = this.readUInt32(); + + if (blockLength !== blockLength2) { + throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); + } + } + + private parseCustomBlock(): void { + const blockStart = this.stream.pos(); + const magic = this.readUInt32(); + + if (magic !== BLOCK_TYPE_CUSTOM_1 && magic !== BLOCK_TYPE_CUSTOM_2) { + const expected1 = BLOCK_TYPE_CUSTOM_1.toString(16).toLocaleUpperCase(); + const expected2 = BLOCK_TYPE_CUSTOM_2.toString(16).toLocaleUpperCase(); + const magicHex = magic.toString(16).toLocaleUpperCase(); + throw new Error(`Invalid PCAP magic. Expected either 0x${expected1} or 0x${expected2}, got 0x${magicHex}`); + } + + const blockLength = this.readUInt32(); + + // * Skip this whole block. We don't need this data + // * Only implemented to prevent a crash + + this.stream.seek((blockStart + blockLength) - 4); + + const blockLength2 = this.readUInt32(); + + if (blockLength !== blockLength2) { + throw new Error(`Invalid trailing block length. Expected ${blockLength}, got ${blockLength2}`); + } + } + + // * INTERFACE PARSERS + + private parseInterfaceEthernet(): EthernetInterface { + return { + type: LINKTYPE_ETHERNET, + data: { + destinationMAC: this.stream.readBytes(6).toString('hex'), + sourceMAC: this.stream.readBytes(6).toString('hex'), + type: this.stream.readUInt8() * 256 + this.stream.readUInt8() + } + }; + } + + public *packets(): Generator { + this.stream.seek(0); // * Make sure we're always at the start + + while (this.stream.hasDataLeft()) { + const magic = this.readUInt32(); + + // * Skip back so the block parsers can have the right start position. + // * Makes the block parsers follow the docs layout better rather than + // * skipping the magic read + this.stream.skip(-4); + + switch (magic) { + case BLOCK_TYPE_SECTION_HEADER: + this.currentSection = this.parseSectionHeaderBlock(); + break; + + case BLOCK_TYPE_INTERFACE_DESCRIPTION: + this.currentSection.interfaces.push(this.parseInterfaceDescriptionBlock()); + break; + + case BLOCK_TYPE_ENHANCED_PACKET: + yield this.parseEnhancedPacketBlock(); + break; + + case BLOCK_TYPE_SIMPLE_PACKET: + yield this.parseSimplePacketBlock(); + break; + + case BLOCK_TYPE_NAME_RESOLUTION: + this.parseNameResolutionBlock(); + break; + + case BLOCK_TYPE_INTERFACE_STATISTICS: + this.parseInterfaceStatisticsBlock(); + break; + + case BLOCK_TYPE_CUSTOM_1: + case BLOCK_TYPE_CUSTOM_2: + this.parseCustomBlock(); + break; + + default: + throw new Error(`Unsupported block type 0x${magic.toString(16).toLocaleUpperCase()}`); + } + } + } +} \ No newline at end of file diff --git a/src/protocols/authentication.js b/src/protocols/authentication.js deleted file mode 100644 index 7038fd3..0000000 --- a/src/protocols/authentication.js +++ /dev/null @@ -1,162 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const semver = require('semver'); -const Stream = require('../stream'); - -require('./types/authentication'); - -const Requests = require('./requests/authentication'); -const Responses = require('./responses/authentication'); - -class Authentication { - static ProtocolID = 0xA; - - static ProtocolName = 'Authentication'; - - static Methods = { - Login: 0x1, - LoginEx: 0x2, - RequestTicket: 0x3, - GetPID: 0x4, - GetName: 0x5, - LoginWithContext: 0x6 - }; - - static MethodNames = Object.entries(Authentication.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x1: Authentication.Login, - 0x2: Authentication.LoginEx, - 0x3: Authentication.RequestTicket, - 0x4: Authentication.GetPID, - 0x5: Authentication.GetName, - 0x6: Authentication.LoginWithContext - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = Authentication.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Authentication method ID ${methodId} (0x${methodId?.toString(16)}) (${Authentication.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static Login(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.LoginRequest(stream); - } else { - return new Responses.LoginResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static LoginEx(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.LoginExRequest(stream); - } else { - return new Responses.LoginExResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RequestTicket(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RequestTicketRequest(stream); - } else { - return new Responses.RequestTicketResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPID(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPIDRequest(stream); - } else { - return new Responses.GetPIDResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetName(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetNameRequest(stream); - } else { - return new Responses.GetNameResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static LoginWithContext(rmcMessage, stream) { - // TODO - Move this check somewhere else and use proper method name - if (semver.gte(stream.connection.title.nex_version, '4.4.0')) { - if (rmcMessage.isRequest()) { - return new Requests.ValidateAndRequestTicketWithParamRequest(stream); - } else { - return new Responses.ValidateAndRequestTicketWithParamResponse(stream); - } - } else { - if (rmcMessage.isRequest()) { - return new Requests.LoginWithContextRequest(stream); - } else { - return new Responses.LoginWithContextResponse(stream); - } - } - } -} - - -module.exports = Authentication; diff --git a/src/protocols/datastore.js b/src/protocols/datastore.js deleted file mode 100644 index 91a2fcd..0000000 --- a/src/protocols/datastore.js +++ /dev/null @@ -1,811 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const DataStoreSMM = require('./patches/datastore_smm'); -const DataStoreBadgeArcade = require('./patches/datastore_badge_arcade'); -const DataStorePokemonBank = require('./patches/datastore_pokemon_bank'); - -const Requests = require('./requests/datastore'); -const Responses = require('./responses/datastore'); - -class DataStore { - static ProtocolID = 0x73; - - static ProtocolName = 'DataStore'; - - static Methods = { - PrepareGetObjectV1: 0x01, - PreparePostObjectV1: 0x02, - CompletePostObjectV1: 0x03, - DeleteObject: 0x04, - DeleteObjects: 0x05, - ChangeMetaV1: 0x06, - ChangeMetasV1: 0x07, - GetMeta: 0x08, - GetMetas: 0x09, - PrepareUpdateObject: 0x0a, - CompleteUpdateObject: 0x0b, - SearchObject: 0x0c, - GetNotificationUrl: 0x0d, - GetNewArrivedNotificationsV1: 0x0e, - RateObject: 0x0f, - GetRating: 0x10, - GetRatings: 0x11, - ResetRating: 0x12, - ResetRatings: 0x13, - GetSpecificMetaV1: 0x14, - PostMetaBinary: 0x15, - TouchObject: 0x16, - GetRatingWithLog: 0x17, - PreparePostObject: 0x18, - PrepareGetObject: 0x19, - CompletePostObject: 0x1a, - GetNewArrivedNotifications: 0x1b, - GetSpecificMeta: 0x1c, - GetPersistenceInfo: 0x1d, - GetPersistenceInfos: 0x1e, - PerpetuateObject: 0x1f, - UnperpetuateObject: 0x20, - PrepareGetObjectOrMetaBinary: 0x21, - GetPasswordInfo: 0x22, - GetPasswordInfos: 0x23, - GetMetasMultipleParam: 0x24, - CompletePostObjects: 0x25, - ChangeMeta: 0x26, - ChangeMetas: 0x27, - RateObjects: 0x28, - PostMetaBinaryWithDataId: 0x29, - PostMetaBinariesWithDataId: 0x2a, - RateObjectWithPosting: 0x2b, - RateObjectsWithPosting: 0x2c, - GetObjectInfos: 0x2d, - SearchObjectLight: 0x2e - }; - - static MethodNames = Object.entries(DataStore.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x01: DataStore.PrepareGetObjectV1, - 0x02: DataStore.PreparePostObjectV1, - 0x03: DataStore.CompletePostObjectV1, - 0x04: DataStore.DeleteObject, - 0x05: DataStore.DeleteObjects, - 0x06: DataStore.ChangeMetaV1, - 0x07: DataStore.ChangeMetasV1, - 0x08: DataStore.GetMeta, - 0x09: DataStore.GetMetas, - 0x0a: DataStore.PrepareUpdateObject, - 0x0b: DataStore.CompleteUpdateObject, - 0x0c: DataStore.SearchObject, - 0x0d: DataStore.GetNotificationUrl, - 0x0e: DataStore.GetNewArrivedNotificationsV1, - 0x0f: DataStore.RateObject, - 0x10: DataStore.GetRating, - 0x11: DataStore.GetRatings, - 0x12: DataStore.ResetRating, - 0x13: DataStore.ResetRatings, - 0x14: DataStore.GetSpecificMetaV1, - 0x15: DataStore.PostMetaBinary, - 0x16: DataStore.TouchObject, - 0x17: DataStore.GetRatingWithLog, - 0x18: DataStore.PreparePostObject, - 0x19: DataStore.PrepareGetObject, - 0x1a: DataStore.CompletePostObject, - 0x1b: DataStore.GetNewArrivedNotifications, - 0x1c: DataStore.GetSpecificMeta, - 0x1d: DataStore.GetPersistenceInfo, - 0x1e: DataStore.GetPersistenceInfos, - 0x1f: DataStore.PerpetuateObject, - 0x20: DataStore.UnperpetuateObject, - 0x21: DataStore.PrepareGetObjectOrMetaBinary, - 0x22: DataStore.GetPasswordInfo, - 0x23: DataStore.GetPasswordInfos, - 0x24: DataStore.GetMetasMultipleParam, - 0x25: DataStore.CompletePostObjects, - 0x26: DataStore.ChangeMeta, - 0x27: DataStore.ChangeMetas, - 0x28: DataStore.RateObjects, - 0x29: DataStore.PostMetaBinaryWithDataId, - 0x2a: DataStore.PostMetaBinariesWithDataId, - 0x2b: DataStore.RateObjectWithPosting, - 0x2c: DataStore.RateObjectsWithPosting, - 0x2d: DataStore.GetObjectInfos, - 0x2e: DataStore.SearchObjectLight - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - // Check if method is a SMM patched method - if (packet.connection.accessKey === '9f2b4678' && methodId >= 0x2D) { - DataStoreSMM.handlePacket(packet); - return; - } - - // Check if method is a Badge Arcade patched method - if (packet.connection.accessKey === '82d5962d' && methodId >= 0x2D) { - DataStoreBadgeArcade.handlePacket(packet); - return; - } - - // Check if method is a Pokémon Bank patched method - if (packet.connection.accessKey === '9a2961d8' && methodId >= 0x28) { - DataStorePokemonBank.handlePacket(packet); - return; - } - - const handler = DataStore.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown DataStore method ID ${methodId} (0x${methodId?.toString(16)}) (${DataStore.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PrepareGetObjectV1(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PrepareGetObjectV1Request(stream); - } else { - return new Responses.PrepareGetObjectV1Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PreparePostObjectV1(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PreparePostObjectV1Request(stream); - } else { - return new Responses.PreparePostObjectV1Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CompletePostObjectV1(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CompletePostObjectV1Request(stream); - } else { - return new Responses.CompletePostObjectV1Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteObjectRequest(stream); - } else { - return new Responses.DeleteObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteObjects(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteObjectsRequest(stream); - } else { - return new Responses.DeleteObjectsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ChangeMetaV1(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ChangeMetaV1Request(stream); - } else { - return new Responses.ChangeMetaV1Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ChangeMetasV1(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ChangeMetasV1Request(stream); - } else { - return new Responses.ChangeMetasV1Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetMeta(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetMetaRequest(stream); - } else { - return new Responses.GetMetaResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetMetas(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetMetasRequest(stream); - } else { - return new Responses.GetMetasResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PrepareUpdateObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PrepareUpdateObjectRequest(stream); - } else { - return new Responses.PrepareUpdateObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CompleteUpdateObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CompleteUpdateObjectRequest(stream); - } else { - return new Responses.CompleteUpdateObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SearchObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SearchObjectRequest(stream); - } else { - return new Responses.SearchObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetNotificationUrl(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetNotificationUrlRequest(stream); - } else { - return new Responses.GetNotificationUrlResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetNewArrivedNotificationsV1(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetNewArrivedNotificationsV1Request(stream); - } else { - return new Responses.GetNewArrivedNotificationsV1Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RateObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RateObjectRequest(stream); - } else { - return new Responses.RateObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetRating(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetRatingRequest(stream); - } else { - return new Responses.GetRatingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetRatings(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetRatingsRequest(stream); - } else { - return new Responses.GetRatingsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ResetRating(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ResetRatingRequest(stream); - } else { - return new Responses.ResetRatingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ResetRatings(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ResetRatingsRequest(stream); - } else { - return new Responses.ResetRatingsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetSpecificMetaV1(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetSpecificMetaV1Request(stream); - } else { - return new Responses.GetSpecificMetaV1Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PostMetaBinary(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PostMetaBinaryRequest(stream); - } else { - return new Responses.PostMetaBinaryResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static TouchObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.TouchObjectRequest(stream); - } else { - return new Responses.TouchObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetRatingWithLog(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetRatingWithLogRequest(stream); - } else { - return new Responses.GetRatingWithLogResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PreparePostObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PreparePostObjectRequest(stream); - } else { - return new Responses.PreparePostObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PrepareGetObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PrepareGetObjectRequest(stream); - } else { - return new Responses.PrepareGetObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CompletePostObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CompletePostObjectRequest(stream); - } else { - return new Responses.CompletePostObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetNewArrivedNotifications(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetNewArrivedNotificationsRequest(stream); - } else { - return new Responses.GetNewArrivedNotificationsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetSpecificMeta(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetSpecificMetaRequest(stream); - } else { - return new Responses.GetSpecificMetaResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPersistenceInfo(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPersistenceInfoRequest(stream); - } else { - return new Responses.GetPersistenceInfoResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPersistenceInfos(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPersistenceInfosRequest(stream); - } else { - return new Responses.GetPersistenceInfosResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PerpetuateObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PerpetuateObjectRequest(stream); - } else { - return new Responses.PerpetuateObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UnperpetuateObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UnperpetuateObjectRequest(stream); - } else { - return new Responses.UnperpetuateObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PrepareGetObjectOrMetaBinary(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PrepareGetObjectOrMetaBinaryRequest(stream); - } else { - return new Responses.PrepareGetObjectOrMetaBinaryResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPasswordInfo(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPasswordInfoRequest(stream); - } else { - return new Responses.GetPasswordInfoResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPasswordInfos(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPasswordInfosRequest(stream); - } else { - return new Responses.GetPasswordInfosResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetMetasMultipleParam(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetMetasMultipleParamRequest(stream); - } else { - return new Responses.GetMetasMultipleParamResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CompletePostObjects(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CompletePostObjectsRequest(stream); - } else { - return new Responses.CompletePostObjectsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ChangeMeta(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ChangeMetaRequest(stream); - } else { - return new Responses.ChangeMetaResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ChangeMetas(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ChangeMetasRequest(stream); - } else { - return new Responses.ChangeMetasResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RateObjects(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RateObjectsRequest(stream); - } else { - return new Responses.RateObjectsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PostMetaBinaryWithDataId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PostMetaBinaryWithDataIdRequest(stream); - } else { - return new Responses.PostMetaBinaryWithDataIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PostMetaBinariesWithDataId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PostMetaBinariesWithDataIdRequest(stream); - } else { - return new Responses.PostMetaBinariesWithDataIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RateObjectWithPosting(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RateObjectWithPostingRequest(stream); - } else { - return new Responses.RateObjectWithPostingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RateObjectsWithPosting(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RateObjectsWithPostingRequest(stream); - } else { - return new Responses.RateObjectsWithPostingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetObjectInfos(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetObjectInfosRequest(stream); - } else { - return new Responses.GetObjectInfosResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SearchObjectLight(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SearchObjectLightRequest(stream); - } else { - return new Responses.SearchObjectLightResponse(stream); - } - } -} - -module.exports = DataStore; diff --git a/src/protocols/friends_3ds.js b/src/protocols/friends_3ds.js deleted file mode 100644 index 3d82aa2..0000000 --- a/src/protocols/friends_3ds.js +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const Requests = require('./requests/friends_3ds'); -const Responses = require('./responses/friends_3ds'); - -class Friends3DS { - static ProtocolID = 0x65; - - static ProtocolName = 'Friends (3DS)'; - - static Methods = { - UpdateProfile: 0x01, - UpdateMii: 0x02, - UpdateMiiList: 0x03, - UpdatePlayedGames: 0x04, - UpdatePreference: 0x05, - GetFriendMii: 0x06, - GetFriendMiiList: 0x07, - IsActiveGame: 0x08, - GetPrincipalIDByLocalFriendCode: 0x09, - GetFriendRelationships: 0x0a, - AddFriendByPrincipalID: 0x0b, - AddFriendBylstPrincipalID: 0x0c, - RemoveFriendByLocalFriendCode: 0x0d, - RemoveFriendByPrincipalID: 0x0e, - GetAllFriends: 0x0f, - UpdateBlackList: 0x10, - SyncFriend: 0x11, - UpdatePresence: 0x12, - UpdateFavoriteGameKey: 0x13, - UpdateComment: 0x14, - UpdatePicture: 0x15, - GetFriendPresence: 0x16, - GetFriendComment: 0x17, - GetFriendPicture: 0x18, - GetFriendPersistentInfo: 0x19, - SendInvitation: 0x1a - }; - - static MethodNames = Object.entries(Friends3DS.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x11: Friends3DS.SyncFriend, - 0x12: Friends3DS.UpdatePresence, - 0x16: Friends3DS.GetFriendPresence, - 0x19: Friends3DS.GetFriendPersistentInfo - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = Friends3DS.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Friends3DS method ID ${methodId} (0x${methodId?.toString(16)}) (${Friends3DS.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SyncFriend(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SyncFriendRequest(stream); - } else { - return new Responses.SyncFriendResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdatePresence(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdatePresenceRequest(stream); - } else { - return new Responses.UpdatePresenceResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetFriendPresence(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetFriendPresenceRequest(stream); - } else { - return new Responses.GetFriendPresenceResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetFriendPersistentInfo(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetFriendPersistentInfoRequest(stream); - } else { - return new Responses.GetFriendPersistentInfoResponse(stream); - } - } -} - - -module.exports = Friends3DS; diff --git a/src/protocols/friends_wiiu.js b/src/protocols/friends_wiiu.js deleted file mode 100644 index bc54f7e..0000000 --- a/src/protocols/friends_wiiu.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const Requests = require('./requests/friends_wiiu'); -const Responses = require('./responses/friends_wiiu'); - -class FriendsWiiU { - static ProtocolID = 0x66; - - static ProtocolName = 'Friends (Wii U)'; - - static Methods = { - UpdateAndGetAllInformation: 0x01, - AddFriend: 0x02, - AddFriendByName: 0x03, - RemoveFriend: 0x04, - AddFriendRequest: 0x05, - CancelFriendRequest: 0x06, - AcceptFriendRequest: 0x07, - DeleteFriendRequest: 0x08, - DenyFriendRequest: 0x09, - MarkFriendRequestsAsReceived: 0x0a, - AddBlackList: 0x0b, - RemoveBlackList: 0x0c, - UpdatePresence: 0x0d, - UpdateMii: 0x0e, - UpdateComment: 0x0f, - UpdatePreference: 0x10, - GetBasicInfo: 0x11, - DeletePersistentNotification: 0x12, - CheckSettingStatus: 0x13, - GetRequestBlockSettings: 0x14 - }; - - static MethodNames = Object.entries(FriendsWiiU.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x01: FriendsWiiU.UpdateAndGetAllInformation, - 0x0d: FriendsWiiU.UpdatePresence - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = FriendsWiiU.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown FriendsWiiU method ID ${methodId} (0x${methodId?.toString(16)}) (${FriendsWiiU.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateAndGetAllInformation(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateAndGetAllInformationRequest(stream); - } else { - return new Responses.UpdateAndGetAllInformationResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdatePresence(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdatePresenceRequest(stream); - } else { - return new Responses.UpdatePresenceResponse(stream); - } - } -} - - -module.exports = FriendsWiiU; \ No newline at end of file diff --git a/src/protocols/index.js b/src/protocols/index.js deleted file mode 100644 index c957773..0000000 --- a/src/protocols/index.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = { - 0x3: require('./nat_traversal'), - 0xA: require('./authentication'), - 0xB: require('./secure_connection'), - 0xE: require('./notifications'), - 0x15: require('./match_making'), - 0x1B: require('./message_delivery'), - 0x32: require('./match_making_ext'), - 0x64: require('./nintendo_notifications'), - 0x65: require('./friends_3ds'), - 0x66: require('./friends_wiiu'), - 0x6d: require('./matchmake_extension'), - 0x6e: require('./utility'), - 0x70: require('./ranking'), - 0x73: require('./datastore'), - 0x75: require('./subscription'), - 0x77: require('./service_item'), - 0xC8: require('./shop') -}; diff --git a/src/protocols/match_making.js b/src/protocols/match_making.js deleted file mode 100644 index bbad9cf..0000000 --- a/src/protocols/match_making.js +++ /dev/null @@ -1,758 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const Requests = require('./requests/match_making'); -const Responses = require('./responses/match_making'); - -class MatchMaking { - static ProtocolID = 0x15; - - static ProtocolName = 'Match making'; - - static Methods = { - RegisterGathering: 0x01, - UnregisterGathering: 0x02, - UnregisterGatherings: 0x03, - UpdateGathering: 0x04, - Invite: 0x05, - AcceptInvitation: 0x06, - DeclineInvitation: 0x07, - CancelInvitation: 0x08, - GetInvitationsSent: 0x09, - GetInvitationsReceived: 0x0a, - Participate: 0x0b, - CancelParticipation: 0x0c, - GetParticipants: 0x0d, - AddParticipants: 0x0e, - GetDetailedParticipants: 0x0f, - GetParticipantsURLs: 0x10, - FindByType: 0x11, - FindByDescription: 0x12, - FindByDescriptionRegex: 0x13, - FindByID: 0x14, - FindBySingleID: 0x15, - FindByOwner: 0x16, - FindByParticipants: 0x17, - FindInvitations: 0x18, - FindBySQLQuery: 0x19, - LaunchSession: 0x1a, - UpdateSessionURL: 0x1b, - GetSessionURL: 0x1c, - GetState: 0x1d, - SetState: 0x1e, - ReportStats: 0x1f, - GetStats: 0x20, - DeleteGathering: 0x21, - GetPendingDeletions: 0x22, - DeleteFromDeletions: 0x23, - MigrateGatheringOwnershipV1: 0x24, - FindByDescriptionLike: 0x25, - RegisterLocalURL: 0x26, - RegisterLocalURLs: 0x27, - UpdateSessionHostV1: 0x28, - GetSessionURLs: 0x29, - UpdateSessionHost: 0x2a, - UpdateGatheringOwnership: 0x2b, - MigrateGatheringOwnership: 0x2c - }; - - static MethodNames = Object.entries(MatchMaking.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x01: MatchMaking.RegisterGathering, - 0x02: MatchMaking.UnregisterGathering, - 0x03: MatchMaking.UnregisterGatherings, - 0x04: MatchMaking.UpdateGathering, - 0x05: MatchMaking.Invite, - 0x06: MatchMaking.AcceptInvitation, - 0x07: MatchMaking.DeclineInvitation, - 0x08: MatchMaking.CancelInvitation, - 0x09: MatchMaking.GetInvitationsSent, - 0x0a: MatchMaking.GetInvitationsReceived, - 0x0b: MatchMaking.Participate, - 0x0c: MatchMaking.CancelParticipation, - 0x0d: MatchMaking.GetParticipants, - 0x0e: MatchMaking.AddParticipants, - 0x0f: MatchMaking.GetDetailedParticipants, - 0x10: MatchMaking.GetParticipantsURLs, - 0x11: MatchMaking.FindByType, - 0x12: MatchMaking.FindByDescription, - 0x13: MatchMaking.FindByDescriptionRegex, - 0x14: MatchMaking.FindByID, - 0x15: MatchMaking.FindBySingleID, - 0x16: MatchMaking.FindByOwner, - 0x17: MatchMaking.FindByParticipants, - 0x18: MatchMaking.FindInvitations, - 0x19: MatchMaking.FindBySQLQuery, - 0x1a: MatchMaking.LaunchSession, - 0x1b: MatchMaking.UpdateSessionURL, - 0x1c: MatchMaking.GetSessionURL, - 0x1d: MatchMaking.GetState, - 0x1e: MatchMaking.SetState, - 0x1f: MatchMaking.ReportStats, - 0x20: MatchMaking.GetStats, - 0x21: MatchMaking.DeleteGathering, - 0x22: MatchMaking.GetPendingDeletions, - 0x23: MatchMaking.DeleteFromDeletions, - 0x24: MatchMaking.MigrateGatheringOwnershipV1, - 0x25: MatchMaking.FindByDescriptionLike, - 0x26: MatchMaking.RegisterLocalURL, - 0x27: MatchMaking.RegisterLocalURLs, - 0x28: MatchMaking.UpdateSessionHostV1, - 0x29: MatchMaking.GetSessionURLs, - 0x2a: MatchMaking.UpdateSessionHost, - 0x2b: MatchMaking.UpdateGatheringOwnership, - 0x2c: MatchMaking.MigrateGatheringOwnership - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = MatchMaking.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown MatchMaking method ID ${methodId} (0x${methodId?.toString(16)}) (${MatchMaking.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RegisterGathering(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RegisterGatheringRequest(stream); - } else { - return new Responses.RegisterGatheringResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UnregisterGathering(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UnregisterGatheringRequest(stream); - } else { - return new Responses.UnregisterGatheringResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UnregisterGatherings(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UnregisterGatheringsRequest(stream); - } else { - return new Responses.UnregisterGatheringsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateGathering(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateGatheringRequest(stream); - } else { - return new Responses.UpdateGatheringResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static Invite(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.InviteRequest(stream); - } else { - return new Responses.InviteResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AcceptInvitation(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AcceptInvitationRequest(stream); - } else { - return new Responses.AcceptInvitationResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeclineInvitation(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeclineInvitationRequest(stream); - } else { - return new Responses.DeclineInvitationResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CancelInvitation(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CancelInvitationRequest(stream); - } else { - return new Responses.CancelInvitationResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetInvitationsSent(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetInvitationsSentRequest(stream); - } else { - return new Responses.GetInvitationsSentResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetInvitationsReceived(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetInvitationsReceivedRequest(stream); - } else { - return new Responses.GetInvitationsReceivedResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static Participate(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ParticipateRequest(stream); - } else { - return new Responses.ParticipateResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CancelParticipation(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CancelParticipationRequest(stream); - } else { - return new Responses.CancelParticipationResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetParticipants(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetParticipantsRequest(stream); - } else { - return new Responses.GetParticipantsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AddParticipants(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AddParticipantsRequest(stream); - } else { - return new Responses.AddParticipantsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetDetailedParticipants(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetDetailedParticipantsRequest(stream); - } else { - return new Responses.GetDetailedParticipantsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetParticipantsURLs(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetParticipantsURLsRequest(stream); - } else { - return new Responses.GetParticipantsURLsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindByType(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindByTypeRequest(stream); - } else { - return new Responses.FindByTypeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindByDescription(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindByDescriptionRequest(stream); - } else { - return new Responses.FindByDescriptionResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindByDescriptionRegex(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindByDescriptionRegexRequest(stream); - } else { - return new Responses.FindByDescriptionRegexResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindByID(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindByIDRequest(stream); - } else { - return new Responses.FindByIDResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindBySingleID(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindBySingleIDRequest(stream); - } else { - return new Responses.FindBySingleIDResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindByOwner(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindByOwnerRequest(stream); - } else { - return new Responses.FindByOwnerResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindByParticipants(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindByParticipantsRequest(stream); - } else { - return new Responses.FindByParticipantsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindInvitations(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindInvitationsRequest(stream); - } else { - return new Responses.FindInvitationsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindBySQLQuery(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindBySQLQueryRequest(stream); - } else { - return new Responses.FindBySQLQueryResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static LaunchSession(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.LaunchSessionRequest(stream); - } else { - return new Responses.LaunchSessionResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateSessionURL(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateSessionURLRequest(stream); - } else { - return new Responses.UpdateSessionURLResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetSessionURL(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetSessionURLRequest(stream); - } else { - return new Responses.GetSessionURLResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetState(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetStateRequest(stream); - } else { - return new Responses.GetStateResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SetState(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SetStateRequest(stream); - } else { - return new Responses.SetStateResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ReportStats(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ReportStatsRequest(stream); - } else { - return new Responses.ReportStatsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetStats(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetStatsRequest(stream); - } else { - return new Responses.GetStatsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteGathering(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteGatheringRequest(stream); - } else { - return new Responses.DeleteGatheringResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPendingDeletions(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPendingDeletionsRequest(stream); - } else { - return new Responses.GetPendingDeletionsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteFromDeletions(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteFromDeletionsRequest(stream); - } else { - return new Responses.DeleteFromDeletionsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static MigrateGatheringOwnershipV1(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.MigrateGatheringOwnershipV1Request(stream); - } else { - return new Responses.MigrateGatheringOwnershipV1Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindByDescriptionLike(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindByDescriptionLikeRequest(stream); - } else { - return new Responses.FindByDescriptionLikeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RegisterLocalURL(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RegisterLocalURLRequest(stream); - } else { - return new Responses.RegisterLocalURLResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RegisterLocalURLs(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RegisterLocalURLsRequest(stream); - } else { - return new Responses.RegisterLocalURLsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateSessionHostV1(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateSessionHostV1Request(stream); - } else { - return new Responses.UpdateSessionHostV1Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetSessionURLs(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetSessionURLsRequest(stream); - } else { - return new Responses.GetSessionURLsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateSessionHost(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateSessionHostRequest(stream); - } else { - return new Responses.UpdateSessionHostResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateGatheringOwnership(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateGatheringOwnershipRequest(stream); - } else { - return new Responses.UpdateGatheringOwnershipResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static MigrateGatheringOwnership(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.MigrateGatheringOwnershipRequest(stream); - } else { - return new Responses.MigrateGatheringOwnershipResponse(stream); - } - } -} - - -module.exports = MatchMaking; \ No newline at end of file diff --git a/src/protocols/match_making_ext.js b/src/protocols/match_making_ext.js deleted file mode 100644 index c1f0a1c..0000000 --- a/src/protocols/match_making_ext.js +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const Requests = require('./requests/match_making_ext'); -const Responses = require('./responses/match_making_ext'); - -class MatchMakingExt { - static ProtocolID = 0x32; - - static ProtocolName = 'Match making (extension)'; - - static Methods = { - EndParticipation: 0x1, - GetParticipants: 0x2, - GetDetailedParticipants: 0x3, - GetParticipantsURLs: 0x4, - GetGatheringRelations: 0x5, - DeleteFromDeletions: 0x6 - }; - - static MethodNames = Object.entries(MatchMakingExt.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x1: MatchMakingExt.EndParticipation, - 0x2: MatchMakingExt.GetParticipants, - 0x3: MatchMakingExt.GetDetailedParticipants, - 0x4: MatchMakingExt.GetParticipantsURLs, - 0x5: MatchMakingExt.GetGatheringRelations, - 0x6: MatchMakingExt.DeleteFromDeletions - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = MatchMakingExt.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown MatchMakingExt method ID ${methodId} (0x${methodId?.toString(16)}) (${MatchMakingExt.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static EndParticipation(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.EndParticipationRequest(stream); - } else { - return new Responses.EndParticipationResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetParticipants(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetParticipantsRequest(stream); - } else { - return new Responses.GetParticipantsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetDetailedParticipants(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetDetailedParticipantsRequest(stream); - } else { - return new Responses.GetDetailedParticipantsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetParticipantsURLs(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetParticipantsURLsRequest(stream); - } else { - return new Responses.GetParticipantsURLsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetGatheringRelations(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetGatheringRelationsRequest(stream); - } else { - return new Responses.GetGatheringRelationsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteFromDeletions(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteFromDeletionsRequest(stream); - } else { - return new Responses.DeleteFromDeletionsResponse(stream); - } - } -} - - -module.exports = MatchMakingExt; \ No newline at end of file diff --git a/src/protocols/matchmake_extension.js b/src/protocols/matchmake_extension.js deleted file mode 100644 index 7e313d8..0000000 --- a/src/protocols/matchmake_extension.js +++ /dev/null @@ -1,908 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const MatchmakeExtensionMK8 = require('./patches/matchmake_extension_mk8'); - -const Requests = require('./requests/matchmake_extension'); -const Responses = require('./responses/matchmake_extension'); - -class MatchmakeExtension { - static ProtocolID = 0x6d; - - static ProtocolName = 'Matchmake extension'; - - static Methods = { - CloseParticipation: 0x01, - OpenParticipation: 0x02, - AutoMatchmake_Postpone: 0x03, - BrowseMatchmakeSession: 0x04, - BrowseMatchmakeSessionWithHostUrls: 0x05, - CreateMatchmakeSession: 0x06, - JoinMatchmakeSession: 0x07, - ModifyCurrentGameAttribute: 0x08, - UpdateNotificationData: 0x09, - GetFriendNotificationData: 0x0a, - UpdateApplicationBuffer: 0x0b, - UpdateMatchmakeSessionAttribute: 0x0c, - GetlstFriendNotificationData: 0x0d, - UpdateMatchmakeSession: 0x0e, - AutoMatchmakeWithSearchCriteria_Postpone: 0x0f, - GetPlayingSession: 0x10, - CreateCommunity: 0x11, - UpdateCommunity: 0x12, - JoinCommunity: 0x13, - FindCommunityByGatheringId: 0x14, - FindOfficialCommunity: 0x15, - FindCommunityByParticipant: 0x16, - UpdatePrivacySetting: 0x17, - GetMyBlockList: 0x18, - AddToBlockList: 0x19, - RemoveFromBlockList: 0x1a, - ClearMyBlockList: 0x1b, - ReportViolation: 0x1c, - IsViolationUser: 0x1d, - JoinMatchmakeSessionEx: 0x1e, - GetSimplePlayingSession: 0x1f, - GetSimpleCommunity: 0x20, - AutoMatchmakeWithGatheringId_Postpone: 0x21, - UpdateProgressScore: 0x22, - DebugNotifyEvent: 0x23, - GenerateMatchmakeSessionSystemPassword: 0x24, - ClearMatchmakeSessionSystemPassword: 0x25, - CreateMatchmakeSessionWithParam: 0x26, - JoinMatchmakeSessionWithParam: 0x27, - AutoMatchmakeWithParam_Postpone: 0x28, - FindMatchmakeSessionByGatheringIdDetail: 0x29, - BrowseMatchmakeSessionNoHolder: 0x2a, - BrowseMatchmakeSessionWithHostUrlsNoHolder: 0x2b, - UpdateMatchmakeSessionPart: 0x2c, - RequestMatchmaking: 0x2d, - WithdrawMatchmaking: 0x2e, - WithdrawMatchmakingAll: 0x2f, - FindMatchmakeSessionByGatheringId: 0x30, - FindMatchmakeSessionBySingleGatheringId: 0x31, - FindMatchmakeSessionByOwner: 0x32, - FindMatchmakeSessionByParticipant: 0x33, - BrowseMatchmakeSessionNoHolderNoResultRange: 0x34, - BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange: 0x35, - FindCommunityByOwner: 0x36 - }; - - static MethodNames = Object.entries(MatchmakeExtension.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x01: MatchmakeExtension.CloseParticipation, - 0x02: MatchmakeExtension.OpenParticipation, - 0x03: MatchmakeExtension.AutoMatchmake_Postpone, - 0x04: MatchmakeExtension.BrowseMatchmakeSession, - 0x05: MatchmakeExtension.BrowseMatchmakeSessionWithHostUrls, - 0x06: MatchmakeExtension.CreateMatchmakeSession, - 0x07: MatchmakeExtension.JoinMatchmakeSession, - 0x08: MatchmakeExtension.ModifyCurrentGameAttribute, - 0x09: MatchmakeExtension.UpdateNotificationData, - 0x0a: MatchmakeExtension.GetFriendNotificationData, - 0x0b: MatchmakeExtension.UpdateApplicationBuffer, - 0x0c: MatchmakeExtension.UpdateMatchmakeSessionAttribute, - 0x0d: MatchmakeExtension.GetlstFriendNotificationData, - 0x0e: MatchmakeExtension.UpdateMatchmakeSession, - 0x0f: MatchmakeExtension.AutoMatchmakeWithSearchCriteria_Postpone, - 0x10: MatchmakeExtension.GetPlayingSession, - 0x11: MatchmakeExtension.CreateCommunity, - 0x12: MatchmakeExtension.UpdateCommunity, - 0x13: MatchmakeExtension.JoinCommunity, - 0x14: MatchmakeExtension.FindCommunityByGatheringId, - 0x15: MatchmakeExtension.FindOfficialCommunity, - 0x16: MatchmakeExtension.FindCommunityByParticipant, - 0x17: MatchmakeExtension.UpdatePrivacySetting, - 0x18: MatchmakeExtension.GetMyBlockList, - 0x19: MatchmakeExtension.AddToBlockList, - 0x1a: MatchmakeExtension.RemoveFromBlockList, - 0x1b: MatchmakeExtension.ClearMyBlockList, - 0x1c: MatchmakeExtension.ReportViolation, - 0x1d: MatchmakeExtension.IsViolationUser, - 0x1e: MatchmakeExtension.JoinMatchmakeSessionEx, - 0x1f: MatchmakeExtension.GetSimplePlayingSession, - 0x20: MatchmakeExtension.GetSimpleCommunity, - 0x21: MatchmakeExtension.AutoMatchmakeWithGatheringId_Postpone, - 0x22: MatchmakeExtension.UpdateProgressScore, - 0x23: MatchmakeExtension.DebugNotifyEvent, - 0x24: MatchmakeExtension.GenerateMatchmakeSessionSystemPassword, - 0x25: MatchmakeExtension.ClearMatchmakeSessionSystemPassword, - 0x26: MatchmakeExtension.CreateMatchmakeSessionWithParam, - 0x27: MatchmakeExtension.JoinMatchmakeSessionWithParam, - 0x28: MatchmakeExtension.AutoMatchmakeWithParam_Postpone, - 0x29: MatchmakeExtension.FindMatchmakeSessionByGatheringIdDetail, - 0x2a: MatchmakeExtension.BrowseMatchmakeSessionNoHolder, - 0x2b: MatchmakeExtension.BrowseMatchmakeSessionWithHostUrlsNoHolder, - 0x2c: MatchmakeExtension.UpdateMatchmakeSessionPart, - 0x2d: MatchmakeExtension.RequestMatchmaking, - 0x2e: MatchmakeExtension.WithdrawMatchmaking, - 0x2f: MatchmakeExtension.WithdrawMatchmakingAll, - 0x30: MatchmakeExtension.FindMatchmakeSessionByGatheringId, - 0x31: MatchmakeExtension.FindMatchmakeSessionBySingleGatheringId, - 0x32: MatchmakeExtension.FindMatchmakeSessionByOwner, - 0x33: MatchmakeExtension.FindMatchmakeSessionByParticipant, - 0x34: MatchmakeExtension.BrowseMatchmakeSessionNoHolderNoResultRange, - 0x35: MatchmakeExtension.BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - // Check if method is a Mario Kart 8 patched method - if (packet.connection.accessKey === '25dbf96a' && methodId >= 36 && methodId <= 41) { - MatchmakeExtensionMK8.handlePacket(packet); - return; - } - - const handler = MatchmakeExtension.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown MatchmakeExtension method ID ${methodId} (0x${methodId?.toString(16)}) (${MatchmakeExtension.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CloseParticipation(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CloseParticipationRequest(stream); - } else { - return new Responses.CloseParticipationResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static OpenParticipation(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.OpenParticipationRequest(stream); - } else { - return new Responses.OpenParticipationResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AutoMatchmake_Postpone(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AutoMatchmake_PostponeRequest(stream); - } else { - return new Responses.AutoMatchmake_PostponeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static BrowseMatchmakeSession(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.BrowseMatchmakeSessionRequest(stream); - } else { - return new Responses.BrowseMatchmakeSessionResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static BrowseMatchmakeSessionWithHostUrls(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.BrowseMatchmakeSessionWithHostUrlsRequest(stream); - } else { - return new Responses.BrowseMatchmakeSessionWithHostUrlsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CreateMatchmakeSession(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CreateMatchmakeSessionRequest(stream); - } else { - return new Responses.CreateMatchmakeSessionResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static JoinMatchmakeSession(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.JoinMatchmakeSessionRequest(stream); - } else { - return new Responses.JoinMatchmakeSessionResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ModifyCurrentGameAttribute(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ModifyCurrentGameAttributeRequest(stream); - } else { - return new Responses.ModifyCurrentGameAttributeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateNotificationData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateNotificationDataRequest(stream); - } else { - return new Responses.UpdateNotificationDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetFriendNotificationData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetFriendNotificationDataRequest(stream); - } else { - return new Responses.GetFriendNotificationDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateApplicationBuffer(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateApplicationBufferRequest(stream); - } else { - return new Responses.UpdateApplicationBufferResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateMatchmakeSessionAttribute(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateMatchmakeSessionAttributeRequest(stream); - } else { - return new Responses.UpdateMatchmakeSessionAttributeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetlstFriendNotificationData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetlstFriendNotificationDataRequest(stream); - } else { - return new Responses.GetlstFriendNotificationDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateMatchmakeSession(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateMatchmakeSessionRequest(stream); - } else { - return new Responses.UpdateMatchmakeSessionResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AutoMatchmakeWithSearchCriteria_Postpone(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AutoMatchmakeWithSearchCriteria_PostponeRequest(stream); - } else { - return new Responses.AutoMatchmakeWithSearchCriteria_PostponeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPlayingSession(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPlayingSessionRequest(stream); - } else { - return new Responses.GetPlayingSessionResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CreateCommunity(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CreateCommunityRequest(stream); - } else { - return new Responses.CreateCommunityResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateCommunity(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateCommunityRequest(stream); - } else { - return new Responses.UpdateCommunityResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static JoinCommunity(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.JoinCommunityRequest(stream); - } else { - return new Responses.JoinCommunityResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindCommunityByGatheringId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindCommunityByGatheringIdRequest(stream); - } else { - return new Responses.FindCommunityByGatheringIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindOfficialCommunity(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindOfficialCommunityRequest(stream); - } else { - return new Responses.FindOfficialCommunityResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindCommunityByParticipant(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindCommunityByParticipantRequest(stream); - } else { - return new Responses.FindCommunityByParticipantResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdatePrivacySetting(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdatePrivacySettingRequest(stream); - } else { - return new Responses.UpdatePrivacySettingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetMyBlockList(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetMyBlockListRequest(stream); - } else { - return new Responses.GetMyBlockListResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AddToBlockList(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AddToBlockListRequest(stream); - } else { - return new Responses.AddToBlockListResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RemoveFromBlockList(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RemoveFromBlockListRequest(stream); - } else { - return new Responses.RemoveFromBlockListResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @returns {object} Parsed RMC body - */ - static ClearMyBlockList(rmcMessage) { - if (rmcMessage.isRequest()) { - return new Requests.ClearMyBlockListRequest(); - } else { - return new Responses.ClearMyBlockListResponse(); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ReportViolation(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ReportViolationRequest(stream); - } else { - return new Responses.ReportViolationResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static IsViolationUser(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.IsViolationUserRequest(stream); - } else { - return new Responses.IsViolationUserResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static JoinMatchmakeSessionEx(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.JoinMatchmakeSessionExRequest(stream); - } else { - return new Responses.JoinMatchmakeSessionExResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetSimplePlayingSession(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetSimplePlayingSessionRequest(stream); - } else { - return new Responses.GetSimplePlayingSessionResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetSimpleCommunity(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetSimpleCommunityRequest(stream); - } else { - return new Responses.GetSimpleCommunityResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AutoMatchmakeWithGatheringId_Postpone(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AutoMatchmakeWithGatheringId_PostponeRequest(stream); - } else { - return new Responses.AutoMatchmakeWithGatheringId_PostponeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateProgressScore(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateProgressScoreRequest(stream); - } else { - return new Responses.UpdateProgressScoreResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DebugNotifyEvent(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DebugNotifyEventRequest(stream); - } else { - return new Responses.DebugNotifyEventResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GenerateMatchmakeSessionSystemPassword(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GenerateMatchmakeSessionSystemPasswordRequest(stream); - } else { - return new Responses.GenerateMatchmakeSessionSystemPasswordResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ClearMatchmakeSessionSystemPassword(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ClearMatchmakeSessionSystemPasswordRequest(stream); - } else { - return new Responses.ClearMatchmakeSessionSystemPasswordResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CreateMatchmakeSessionWithParam(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CreateMatchmakeSessionWithParamRequest(stream); - } else { - return new Responses.CreateMatchmakeSessionWithParamResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static JoinMatchmakeSessionWithParam(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.JoinMatchmakeSessionWithParamRequest(stream); - } else { - return new Responses.JoinMatchmakeSessionWithParamResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AutoMatchmakeWithParam_Postpone(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AutoMatchmakeWithParam_PostponeRequest(stream); - } else { - return new Responses.AutoMatchmakeWithParam_PostponeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindMatchmakeSessionByGatheringIdDetail(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindMatchmakeSessionByGatheringIdDetailRequest(stream); - } else { - return new Responses.FindMatchmakeSessionByGatheringIdDetailResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static BrowseMatchmakeSessionNoHolder(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.BrowseMatchmakeSessionNoHolderRequest(stream); - } else { - return new Responses.BrowseMatchmakeSessionNoHolderResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static BrowseMatchmakeSessionWithHostUrlsNoHolder(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.BrowseMatchmakeSessionWithHostUrlsNoHolderRequest(stream); - } else { - return new Responses.BrowseMatchmakeSessionWithHostUrlsNoHolderResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateMatchmakeSessionPart(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateMatchmakeSessionPartRequest(stream); - } else { - return new Responses.UpdateMatchmakeSessionPartResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RequestMatchmaking(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RequestMatchmakingRequest(stream); - } else { - return new Responses.RequestMatchmakingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static WithdrawMatchmaking(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.WithdrawMatchmakingRequest(stream); - } else { - return new Responses.WithdrawMatchmakingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @returns {object} Parsed RMC body - */ - static WithdrawMatchmakingAll(rmcMessage) { - if (rmcMessage.isRequest()) { - return new Requests.WithdrawMatchmakingAllRequest(); - } else { - return new Responses.WithdrawMatchmakingAllResponse(); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindMatchmakeSessionByGatheringId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindMatchmakeSessionByGatheringIdRequest(stream); - } else { - return new Responses.FindMatchmakeSessionByGatheringIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindMatchmakeSessionBySingleGatheringId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindMatchmakeSessionBySingleGatheringIdRequest(stream); - } else { - return new Responses.FindMatchmakeSessionBySingleGatheringIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindMatchmakeSessionByOwner(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindMatchmakeSessionByOwnerRequest(stream); - } else { - return new Responses.FindMatchmakeSessionByOwnerResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FindMatchmakeSessionByParticipant(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FindMatchmakeSessionByParticipantRequest(stream); - } else { - return new Responses.FindMatchmakeSessionByParticipantResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static BrowseMatchmakeSessionNoHolderNoResultRange(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.BrowseMatchmakeSessionNoHolderNoResultRangeRequest(stream); - } else { - return new Responses.BrowseMatchmakeSessionNoHolderNoResultRangeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRangeRequest(stream); - } else { - return new Responses.BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRangeResponse(stream); - } - } -} - -module.exports = MatchmakeExtension; \ No newline at end of file diff --git a/src/protocols/message_delivery.js b/src/protocols/message_delivery.js deleted file mode 100644 index 61f7143..0000000 --- a/src/protocols/message_delivery.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -require('./types/message_delivery'); - -const Requests = require('./requests/message_delivery'); -const Responses = require('./responses/message_delivery'); - -class MessageDelivery { - static ProtocolID = 0x1B; - - static ProtocolName = 'Message Delivery'; - - static Methods = { - DeliverMessage: 0x1 - }; - - static MethodNames = Object.entries(MessageDelivery.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x1: MessageDelivery.DeliverMessage - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = MessageDelivery.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown MessageDelivery method ID ${methodId} (0x${methodId?.toString(16)}) (${MessageDelivery.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeliverMessage(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeliverMessageRequest(stream); - } else { - return new Responses.DeliverMessageResponse(stream); - } - } -} - -module.exports = MessageDelivery; \ No newline at end of file diff --git a/src/protocols/nat_traversal.js b/src/protocols/nat_traversal.js deleted file mode 100644 index 6aa232d..0000000 --- a/src/protocols/nat_traversal.js +++ /dev/null @@ -1,166 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const Requests = require('./requests/nat_traversal'); -const Responses = require('./responses/nat_traversal'); - -class NATTraversal { - static ProtocolID = 0x3; - - static ProtocolName = 'NAT Traversal'; - - static Methods = { - RequestProbeInitiation: 0x1, - InitiateProbe: 0x2, - RequestProbeInitiationExt: 0x3, - ReportNATTraversalResult: 0x4, - ReportNATProperties: 0x5, - GetRelaySignatureKey: 0x6, - ReportNATTraversalResultDetail: 0x7 - }; - - static MethodNames = Object.entries(NATTraversal.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x1: NATTraversal.RequestProbeInitiation, - 0x2: NATTraversal.InitiateProbe, - 0x3: NATTraversal.RequestProbeInitiationExt, - 0x4: NATTraversal.ReportNATTraversalResult, - 0x5: NATTraversal.ReportNATProperties, - 0x6: NATTraversal.GetRelaySignatureKey, - 0x7: NATTraversal.ReportNATTraversalResultDetail - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = NATTraversal.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown NATTraversal method ID ${methodId} (0x${methodId?.toString(16)}) (${NATTraversal.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RequestProbeInitiation(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RequestProbeInitiationRequest(stream); - } else { - return new Responses.RequestProbeInitiationResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static InitiateProbe(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.InitiateProbeRequest(stream); - } else { - return new Responses.InitiateProbeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RequestProbeInitiationExt(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RequestProbeInitiationExtRequest(stream); - } else { - return new Responses.RequestProbeInitiationExtResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ReportNATTraversalResult(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ReportNATTraversalResultRequest(stream); - } else { - return new Responses.ReportNATTraversalResultResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ReportNATProperties(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ReportNATPropertiesRequest(stream); - } else { - return new Responses.ReportNATPropertiesResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetRelaySignatureKey(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetRelaySignatureKeyRequest(stream); - } else { - return new Responses.GetRelaySignatureKeyResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ReportNATTraversalResultDetail(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ReportNATTraversalResultDetailRequest(stream); - } else { - return new Responses.ReportNATTraversalResultDetailResponse(stream); - } - } -} - - -module.exports = NATTraversal; \ No newline at end of file diff --git a/src/protocols/nintendo_notifications.js b/src/protocols/nintendo_notifications.js deleted file mode 100644 index 7b1a361..0000000 --- a/src/protocols/nintendo_notifications.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const Requests = require('./requests/nintendo_notifications'); -const Responses = require('./responses/nintendo_notifications'); - -class NintendoNotifications { - static ProtocolID = 0x64; - - static ProtocolName = 'Nintendo notification events'; - - static Methods = { - ProcessNintendoNotificationEvent1: 0x1, - ProcessNintendoNotificationEvent2: 0x2 - }; - - static MethodNames = Object.entries(NintendoNotifications.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x1: NintendoNotifications.ProcessNintendoNotificationEvent1, - 0x2: NintendoNotifications.ProcessNintendoNotificationEvent2 - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = NintendoNotifications.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown NintendoNotifications method ID ${methodId} (0x${methodId?.toString(16)}) (${NintendoNotifications.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ProcessNintendoNotificationEvent1(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ProcessNintendoNotificationEvent1Request(stream); - } else { - return new Responses.ProcessNintendoNotificationEvent1Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ProcessNintendoNotificationEvent2(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ProcessNintendoNotificationEvent2Request(stream); - } else { - return new Responses.ProcessNintendoNotificationEvent2Response(stream); - } - } -} - - -module.exports = NintendoNotifications; \ No newline at end of file diff --git a/src/protocols/notifications.js b/src/protocols/notifications.js deleted file mode 100644 index 8365a6b..0000000 --- a/src/protocols/notifications.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const Requests = require('./requests/notifications'); -const Responses = require('./responses/notifications'); - -class Notifications { - static ProtocolID = 0xE; - - static ProtocolName = 'Notification events'; - - static Methods = { - ProcessNotificationEvent: 0x1 - }; - - static MethodNames = Object.entries(Notifications.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x1: Notifications.ProcessNotificationEvent - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = Notifications.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Notifications method ID ${methodId} (0x${methodId?.toString(16)}) (${Notifications.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ProcessNotificationEvent(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ProcessNotificationEventRequest(stream); - } else { - return new Responses.ProcessNotificationEventResponse(stream); - } - } -} - - -module.exports = Notifications; \ No newline at end of file diff --git a/src/protocols/patches/datastore_badge_arcade.js b/src/protocols/patches/datastore_badge_arcade.js deleted file mode 100644 index 97df8f3..0000000 --- a/src/protocols/patches/datastore_badge_arcade.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @typedef {import('../../packet')} Packet - * @typedef {import('../../packetv0')} PacketV0 - * @typedef {import('../../packetv1')} PacketV1 - * @typedef {import('../../rmc')} RMCMessage - */ - -const Stream = require('../../stream'); - -const Requests = require('../requests/datastore_badge_arcade'); -const Responses = require('../responses/datastore_badge_arcade'); - -class DataStoreBadgeArcade { - static ProtocolID = 0x73; - - static ProtocolName = 'DataStore (Badge Arcade)'; - - static Methods = { - GetMetaByOwnerId: 0x2d - }; - - static MethodNames = Object.entries(DataStoreBadgeArcade.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x2d: DataStoreBadgeArcade.GetMetaByOwnerId - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = DataStoreBadgeArcade.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown DataStore (Badge Arcade) method ID ${methodId} (0x${methodId.toString(16)}) (${DataStoreBadgeArcade.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetMetaByOwnerId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetMetaByOwnerIdRequest(stream); - } else { - return new Responses.GetMetaByOwnerIdResponse(stream); - } - } -} - -module.exports = DataStoreBadgeArcade; diff --git a/src/protocols/patches/datastore_pokemon_bank.js b/src/protocols/patches/datastore_pokemon_bank.js deleted file mode 100644 index 3939c23..0000000 --- a/src/protocols/patches/datastore_pokemon_bank.js +++ /dev/null @@ -1,343 +0,0 @@ -/** - * @typedef {import('../../packet')} Packet - * @typedef {import('../../packetv0')} PacketV0 - * @typedef {import('../../packetv1')} PacketV1 - * @typedef {import('../../rmc')} RMCMessage - */ - -const Stream = require('../../stream'); - -const Requests = require('../requests/datastore_pokemon_bank'); -const Responses = require('../responses/datastore_pokemon_bank'); - -class DataStorePokemonBank { - static ProtocolID = 0x73; - - static ProtocolName = 'DataStore (Pokémon Bank)'; - - static Methods = { - PrepareUploadPokemon: 0x28, - UploadPokemon: 0x29, - SearchPokemon: 0x2a, - PrepareTradePokemon: 0x2b, - TradePokemon: 0x2c, - DownloadOtherPokemon: 0x2d, - DownloadMyPokemon: 0x2e, - DeletePokemon: 0x2f, - GetTransactionParam: 0x30, - PreparePostBankObject: 0x31, - CompletePostBankObject: 0x32, - PrepareGetBankObject: 0x33, - PrepareUpdateBankObject: 0x34, - CompleteUpdateBankObject: 0x35, - RollbackBankObject: 0x36, - GetUnlockKey: 0x37, - RequestMigration: 0x38, - GetMigrationStatus: 0x39, - }; - - static MethodNames = Object.entries(DataStorePokemonBank.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x28: DataStorePokemonBank.PrepareUploadPokemon, - 0x29: DataStorePokemonBank.UploadPokemon, - 0x2a: DataStorePokemonBank.SearchPokemon, - 0x2b: DataStorePokemonBank.PrepareTradePokemon, - 0x2c: DataStorePokemonBank.TradePokemon, - 0x2d: DataStorePokemonBank.DownloadOtherPokemon, - 0x2e: DataStorePokemonBank.DownloadMyPokemon, - 0x2f: DataStorePokemonBank.DeletePokemon, - 0x30: DataStorePokemonBank.GetTransactionParam, - 0x31: DataStorePokemonBank.PreparePostBankObject, - 0x32: DataStorePokemonBank.CompletePostBankObject, - 0x33: DataStorePokemonBank.PrepareGetBankObject, - 0x34: DataStorePokemonBank.PrepareUpdateBankObject, - 0x35: DataStorePokemonBank.CompleteUpdateBankObject, - 0x36: DataStorePokemonBank.RollbackBankObject, - 0x37: DataStorePokemonBank.GetUnlockKey, - 0x38: DataStorePokemonBank.RequestMigration, - 0x39: DataStorePokemonBank.GetMigrationStatus, - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = DataStorePokemonBank.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown DataStore (Pokémon Bank) method ID ${methodId} (0x${methodId.toString(16)}) (${DataStorePokemonBank.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PrepareUploadPokemon(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PrepareUploadPokemonRequest(stream); - } else { - return new Responses.PrepareUploadPokemonResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UploadPokemon(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UploadPokemonRequest(stream); - } else { - return new Responses.UploadPokemonResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SearchPokemon(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SearchPokemonRequest(stream); - } else { - return new Responses.SearchPokemonResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PrepareTradePokemon(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PrepareTradePokemonRequest(stream); - } else { - return new Responses.PrepareTradePokemonResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static TradePokemon(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.TradePokemonRequest(stream); - } else { - return new Responses.TradePokemonResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DownloadOtherPokemon(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DownloadOtherPokemonRequest(stream); - } else { - return new Responses.DownloadOtherPokemonResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DownloadMyPokemon(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DownloadMyPokemonRequest(stream); - } else { - return new Responses.DownloadMyPokemonResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeletePokemon(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeletePokemonRequest(stream); - } else { - return new Responses.DeletePokemonResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetTransactionParam(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetTransactionParamRequest(stream); - } else { - return new Responses.GetTransactionParamResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PreparePostBankObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PreparePostBankObjectRequest(stream); - } else { - return new Responses.PreparePostBankObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CompletePostBankObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CompletePostBankObjectRequest(stream); - } else { - return new Responses.CompletePostBankObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PrepareGetBankObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PrepareGetBankObjectRequest(stream); - } else { - return new Responses.PrepareGetBankObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PrepareUpdateBankObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PrepareUpdateBankObjectRequest(stream); - } else { - return new Responses.PrepareUpdateBankObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CompleteUpdateBankObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CompleteUpdateBankObjectRequest(stream); - } else { - return new Responses.CompleteUpdateBankObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RollbackBankObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RollbackBankObjectRequest(stream); - } else { - return new Responses.RollbackBankObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetUnlockKey(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetUnlockKeyRequest(stream); - } else { - return new Responses.GetUnlockKeyResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RequestMigration(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RequestMigrationRequest(stream); - } else { - return new Responses.RequestMigrationResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetMigrationStatus(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetMigrationStatusRequest(stream); - } else { - return new Responses.GetMigrationStatusResponse(stream); - } - } -} - -module.exports = DataStorePokemonBank; diff --git a/src/protocols/patches/datastore_smm.js b/src/protocols/patches/datastore_smm.js deleted file mode 100644 index d8bf8ae..0000000 --- a/src/protocols/patches/datastore_smm.js +++ /dev/null @@ -1,744 +0,0 @@ -/** - * @typedef {import('../../packet')} Packet - * @typedef {import('../../packetv0')} PacketV0 - * @typedef {import('../../packetv1')} PacketV1 - * @typedef {import('../../rmc')} RMCMessage - */ - -const Stream = require('../../stream'); - -const Requests = require('../requests/datastore_smm'); -const Responses = require('../responses/datastore_smm'); - -class DataStoreSMM { - static ProtocolID = 0x73; - - static ProtocolName = 'DataStore (SMM)'; - - static Methods = { - GetObjectInfos: 0x2d, - GetMetaByOwnerId: 0x2e, - CustomSearchObject: 0x2f, - RateCustomRanking: 0x30, - GetCustomRanking: 0x31, - GetCustomRankingByDataId: 0x32, - DeleteCustomRanking: 0x33, - AddToBufferQueue: 0x34, - AddToBufferQueues: 0x35, - GetBufferQueue: 0x36, - GetBufferQueues: 0x37, - ClearBufferQueues: 0x38, - CompleteAttachFile: 0x39, - CompleteAttachFileV1: 0x3a, - PrepareAttachFile: 0x3b, - ConditionalSearchObject: 0x3c, - GetApplicationConfig: 0x3d, - SetApplicationConfig: 0x3e, - DeleteApplicationConfig: 0x3f, - LatestCourseSearchObject: 0x40, - FollowingsLatestCourseSearchObject: 0x41, - RecommendedCourseSearchObject: 0x42, - ScoreRangeCascadedSearchObject: 0x43, - SuggestedCourseSearchObject: 0x44, - PreparePostObjectWithOwnerIdAndDataId: 0x45, - CompletePostObjectWithOwnerId: 0x46, - UploadCourseRecord: 0x47, - GetCourseRecord: 0x48, - DeleteCourseRecord: 0x49, - GetApplicationConfigString: 0x4a, - SetApplicationConfigString: 0x4b, - GetDeletionReason: 0x4c, - SetDeletionReason: 0x4d, - GetMetasWithCourseRecord: 0x4e, - CheckRateCustomRankingCounter: 0x4f, - ResetRateCustomRankingCounter: 0x50, - BestScoreRateCourseSearchObject: 0x51, - CTRPickUpCourseSearchObject: 0x52, - SetCachedRanking: 0x53, - DeleteCachedRanking: 0x54, - ChangePlayablePlatform: 0x55, - SearchUnknownPlatformObjects: 0x56, - ReportCourse: 0x57 - }; - - static MethodNames = Object.entries(DataStoreSMM.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x2d: DataStoreSMM.GetObjectInfos, - 0x2e: DataStoreSMM.GetMetaByOwnerId, - 0x2f: DataStoreSMM.CustomSearchObject, - 0x30: DataStoreSMM.RateCustomRanking, - 0x31: DataStoreSMM.GetCustomRanking, - 0x32: DataStoreSMM.GetCustomRankingByDataId, - 0x33: DataStoreSMM.DeleteCustomRanking, - 0x34: DataStoreSMM.AddToBufferQueue, - 0x35: DataStoreSMM.AddToBufferQueues, - 0x36: DataStoreSMM.GetBufferQueue, - 0x37: DataStoreSMM.GetBufferQueues, - 0x38: DataStoreSMM.ClearBufferQueues, - 0x39: DataStoreSMM.CompleteAttachFile, - 0x3a: DataStoreSMM.CompleteAttachFileV1, - 0x3b: DataStoreSMM.PrepareAttachFile, - 0x3c: DataStoreSMM.ConditionalSearchObject, - 0x3d: DataStoreSMM.GetApplicationConfig, - 0x3e: DataStoreSMM.SetApplicationConfig, - 0x3f: DataStoreSMM.DeleteApplicationConfig, - 0x40: DataStoreSMM.LatestCourseSearchObject, - 0x41: DataStoreSMM.FollowingsLatestCourseSearchObject, - 0x42: DataStoreSMM.RecommendedCourseSearchObject, - 0x43: DataStoreSMM.ScoreRangeCascadedSearchObject, - 0x44: DataStoreSMM.SuggestedCourseSearchObject, - 0x45: DataStoreSMM.PreparePostObjectWithOwnerIdAndDataId, - 0x46: DataStoreSMM.CompletePostObjectWithOwnerId, - 0x47: DataStoreSMM.UploadCourseRecord, - 0x48: DataStoreSMM.GetCourseRecord, - 0x49: DataStoreSMM.DeleteCourseRecord, - 0x4a: DataStoreSMM.GetApplicationConfigString, - 0x4b: DataStoreSMM.SetApplicationConfigString, - 0x4c: DataStoreSMM.GetDeletionReason, - 0x4d: DataStoreSMM.SetDeletionReason, - 0x4e: DataStoreSMM.GetMetasWithCourseRecord, - 0x4f: DataStoreSMM.CheckRateCustomRankingCounter, - 0x50: DataStoreSMM.ResetRateCustomRankingCounter, - 0x51: DataStoreSMM.BestScoreRateCourseSearchObject, - 0x52: DataStoreSMM.CTRPickUpCourseSearchObject, - 0x53: DataStoreSMM.SetCachedRanking, - 0x54: DataStoreSMM.DeleteCachedRanking, - 0x55: DataStoreSMM.ChangePlayablePlatform, - 0x56: DataStoreSMM.SearchUnknownPlatformObjects, - 0x57: DataStoreSMM.ReportCourse - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = DataStoreSMM.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown DataStore (SMM) method ID ${methodId} (0x${methodId.toString(16)}) (${DataStoreSMM.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetObjectInfos(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetObjectInfosRequest(stream); - } else { - return new Responses.GetObjectInfosResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetMetaByOwnerId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetMetaByOwnerIdRequest(stream); - } else { - return new Responses.GetMetaByOwnerIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CustomSearchObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CustomSearchObjectRequest(stream); - } else { - return new Responses.CustomSearchObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RateCustomRanking(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RateCustomRankingRequest(stream); - } else { - return new Responses.RateCustomRankingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetCustomRanking(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetCustomRankingRequest(stream); - } else { - return new Responses.GetCustomRankingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetCustomRankingByDataId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetCustomRankingByDataIdRequest(stream); - } else { - return new Responses.GetCustomRankingByDataIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteCustomRanking(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteCustomRankingRequest(stream); - } else { - return new Responses.DeleteCustomRankingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AddToBufferQueue(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AddToBufferQueueRequest(stream); - } else { - return new Responses.AddToBufferQueueResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AddToBufferQueues(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AddToBufferQueuesRequest(stream); - } else { - return new Responses.AddToBufferQueuesResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetBufferQueue(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetBufferQueueRequest(stream); - } else { - return new Responses.GetBufferQueueResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetBufferQueues(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetBufferQueuesRequest(stream); - } else { - return new Responses.GetBufferQueuesResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ClearBufferQueues(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ClearBufferQueuesRequest(stream); - } else { - return new Responses.ClearBufferQueuesResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CompleteAttachFile(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CompleteAttachFileRequest(stream); - } else { - return new Responses.CompleteAttachFileResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CompleteAttachFileV1(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CompleteAttachFileV1Request(stream); - } else { - return new Responses.CompleteAttachFileV1Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PrepareAttachFile(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PrepareAttachFileRequest(stream); - } else { - return new Responses.PrepareAttachFileResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ConditionalSearchObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ConditionalSearchObjectRequest(stream); - } else { - return new Responses.ConditionalSearchObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetApplicationConfig(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetApplicationConfigRequest(stream); - } else { - return new Responses.GetApplicationConfigResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SetApplicationConfig(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SetApplicationConfigRequest(stream); - } else { - return new Responses.SetApplicationConfigResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteApplicationConfig(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteApplicationConfigRequest(stream); - } else { - return new Responses.DeleteApplicationConfigResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static LatestCourseSearchObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.LatestCourseSearchObjectRequest(stream); - } else { - return new Responses.LatestCourseSearchObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static FollowingsLatestCourseSearchObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.FollowingsLatestCourseSearchObjectRequest(stream); - } else { - return new Responses.FollowingsLatestCourseSearchObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RecommendedCourseSearchObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RecommendedCourseSearchObjectRequest(stream); - } else { - return new Responses.RecommendedCourseSearchObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ScoreRangeCascadedSearchObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ScoreRangeCascadedSearchObjectRequest(stream); - } else { - return new Responses.ScoreRangeCascadedSearchObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SuggestedCourseSearchObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SuggestedCourseSearchObjectRequest(stream); - } else { - return new Responses.SuggestedCourseSearchObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PreparePostObjectWithOwnerIdAndDataId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PreparePostObjectWithOwnerIdAndDataIdRequest(stream); - } else { - return new Responses.PreparePostObjectWithOwnerIdAndDataIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CompletePostObjectWithOwnerId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CompletePostObjectWithOwnerIdRequest(stream); - } else { - return new Responses.CompletePostObjectWithOwnerIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UploadCourseRecord(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UploadCourseRecordRequest(stream); - } else { - return new Responses.UploadCourseRecordResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetCourseRecord(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetCourseRecordRequest(stream); - } else { - return new Responses.GetCourseRecordResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteCourseRecord(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteCourseRecordRequest(stream); - } else { - return new Responses.DeleteCourseRecordResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetApplicationConfigString(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetApplicationConfigStringRequest(stream); - } else { - return new Responses.GetApplicationConfigStringResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SetApplicationConfigString(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SetApplicationConfigStringRequest(stream); - } else { - return new Responses.SetApplicationConfigStringResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetDeletionReason(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetDeletionReasonRequest(stream); - } else { - return new Responses.GetDeletionReasonResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SetDeletionReason(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SetDeletionReasonRequest(stream); - } else { - return new Responses.SetDeletionReasonResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetMetasWithCourseRecord(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetMetasWithCourseRecordRequest(stream); - } else { - return new Responses.GetMetasWithCourseRecordResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CheckRateCustomRankingCounter(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CheckRateCustomRankingCounterRequest(stream); - } else { - return new Responses.CheckRateCustomRankingCounterResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ResetRateCustomRankingCounter(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ResetRateCustomRankingCounterRequest(stream); - } else { - return new Responses.ResetRateCustomRankingCounterResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static BestScoreRateCourseSearchObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.BestScoreRateCourseSearchObjectRequest(stream); - } else { - return new Responses.BestScoreRateCourseSearchObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CTRPickUpCourseSearchObject(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CTRPickUpCourseSearchObjectRequest(stream); - } else { - return new Responses.CTRPickUpCourseSearchObjectResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SetCachedRanking(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SetCachedRankingRequest(stream); - } else { - return new Responses.SetCachedRankingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteCachedRanking(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteCachedRankingRequest(stream); - } else { - return new Responses.DeleteCachedRankingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ChangePlayablePlatform(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ChangePlayablePlatformRequest(stream); - } else { - return new Responses.ChangePlayablePlatformResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SearchUnknownPlatformObjects(rmcMessage, stream) { - // ! This function has an unknown request/response format - if (rmcMessage.isRequest()) { - return new Requests.SearchUnknownPlatformObjectsRequest(stream); - } else { - return new Responses.SearchUnknownPlatformObjectsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ReportCourse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ReportCourseRequest(stream); - } else { - return new Responses.ReportCourseResponse(stream); - } - } -} - -module.exports = DataStoreSMM; \ No newline at end of file diff --git a/src/protocols/patches/matchmake_extension_mk8.js b/src/protocols/patches/matchmake_extension_mk8.js deleted file mode 100644 index d119b30..0000000 --- a/src/protocols/patches/matchmake_extension_mk8.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @typedef {import('../../packet')} Packet - * @typedef {import('../../packetv0')} PacketV0 - * @typedef {import('../../packetv1')} PacketV1 - * @typedef {import('../../rmc')} RMCMessage - */ - -const Stream = require('../../stream'); - -const Requests = require('../requests/matchmake_extension_mk8'); -const Responses = require('../responses/matchmake_extension_mk8'); - -class MatchmakeExtensionMK8 { - static ProtocolID = 0x6d; - - static ProtocolName = 'MatchmakeExtension (MK8)'; - - static Methods = { - JoinMatchmakeSessionWithExtraParticipants: 0x28 - }; - - static MethodNames = Object.entries(MatchmakeExtensionMK8.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x28: MatchmakeExtensionMK8.JoinMatchmakeSessionWithExtraParticipants - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = MatchmakeExtensionMK8.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown MatchmakeExtension (MK8) method ID ${methodId} (0x${methodId.toString(16)}) (${MatchmakeExtensionMK8.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static JoinMatchmakeSessionWithExtraParticipants(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.JoinMatchmakeSessionWithExtraParticipantsRequest(stream); - } else { - return new Responses.JoinMatchmakeSessionWithExtraParticipantsResponse(stream); - } - } -} - -module.exports = MatchmakeExtensionMK8; \ No newline at end of file diff --git a/src/protocols/patches/ranking_legacy.js b/src/protocols/patches/ranking_legacy.js deleted file mode 100644 index 9e11c18..0000000 --- a/src/protocols/patches/ranking_legacy.js +++ /dev/null @@ -1,185 +0,0 @@ -/** - * @typedef {import('../../packet')} Packet - * @typedef {import('../../packetv0')} PacketV0 - * @typedef {import('../../packetv1')} PacketV1 - * @typedef {import('../../rmc')} RMCMessage - */ - -const Stream = require('../../stream'); - -const Requests = require('../requests/ranking_legacy'); -const Responses = require('../responses/ranking_legacy'); - -// * This is the old version of the Ranking protocol. -// * It has been rewritten on NEX 3.0.0 to the current Ranking protocol -class RankingLegacy { - static ProtocolID = 0x6e; - - static ProtocolName = 'Ranking (Legacy)'; - - static Methods = { - UploadCommonData: 0x05, - UnknownMethod0xE: 0x0e, - UnknownMethod0xF: 0x0f, - GetTotal: 0x10, - UploadScoreWithLimit: 0x11, - UploadSpecificPeriodScore: 0x14, - GetSpecificPeriodDataList: 0x16, - GetSpecificPeriodTotal: 0x19 - }; - - static MethodNames = Object.entries(RankingLegacy.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x05: RankingLegacy.UploadCommonData, - 0x0e: RankingLegacy.UnknownMethod0xE, - 0x0f: RankingLegacy.UnknownMethod0xF, - 0x10: RankingLegacy.GetTotal, - 0x11: RankingLegacy.UploadScoreWithLimit, - 0x14: RankingLegacy.UploadSpecificPeriodScore, - 0x16: RankingLegacy.GetSpecificPeriodDataList, - 0x19: RankingLegacy.GetSpecificPeriodTotal - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = RankingLegacy.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Ranking (Legacy) method ID ${methodId} (0x${methodId?.toString(16)}) (${RankingLegacy.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UploadCommonData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UploadCommonDataRequest(stream); - } else { - return new Responses.UploadCommonDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UnknownMethod0xE(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UnknownMethod0xERequest(stream); - } else { - return new Responses.UnknownMethod0xEResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UnknownMethod0xF(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UnknownMethod0xFRequest(stream); - } else { - return new Responses.UnknownMethod0xFResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetTotal(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetTotalRequest(stream); - } else { - return new Responses.GetTotalResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UploadScoreWithLimit(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UploadScoreWithLimitRequest(stream); - } else { - return new Responses.UploadScoreWithLimitResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UploadSpecificPeriodScore(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UploadSpecificPeriodScoreRequest(stream); - } else { - return new Responses.UploadSpecificPeriodScoreResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetSpecificPeriodDataList(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetSpecificPeriodDataListRequest(stream); - } else { - return new Responses.GetSpecificPeriodDataListResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetSpecificPeriodTotal(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetSpecificPeriodTotalRequest(stream); - } else { - return new Responses.GetSpecificPeriodTotalResponse(stream); - } - } -} - -module.exports = RankingLegacy; diff --git a/src/protocols/patches/ranking_splatoon.js b/src/protocols/patches/ranking_splatoon.js deleted file mode 100644 index 45aff32..0000000 --- a/src/protocols/patches/ranking_splatoon.js +++ /dev/null @@ -1,119 +0,0 @@ -/** - * @typedef {import('../../packet')} Packet - * @typedef {import('../../packetv0')} PacketV0 - * @typedef {import('../../packetv1')} PacketV1 - * @typedef {import('../../rmc')} RMCMessage - */ - -const Stream = require('../../stream'); - -const Requests = require('../requests/ranking_splatoon'); -const Responses = require('../responses/ranking_splatoon'); - -class RankingSplatoon { - static ProtocolID = 0x70; - - static ProtocolName = 'Ranking (Splatoon)'; - - static Methods = { - GetCompetitionRankingScore: 0x10, - GetcompetitionRankingScoreByPeriodList: 0x11, - UploadCompetitionRankingScore: 0x12, - DeleteCompetitionRankingScore: 0x13 - }; - - static MethodNames = Object.entries(RankingSplatoon.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x10: RankingSplatoon.GetCompetitionRankingScore, - 0x11: RankingSplatoon.GetcompetitionRankingScoreByPeriodList, - 0x12: RankingSplatoon.UploadCompetitionRankingScore, - 0x13: RankingSplatoon.DeleteCompetitionRankingScore - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = RankingSplatoon.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown RankingSplatoon method ID ${methodId} (0x${methodId?.toString(16)}) (${RankingSplatoon.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetCompetitionRankingScore(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetCompetitionRankingScoreRequest(stream); - } else { - return new Responses.GetCompetitionRankingScoreResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetcompetitionRankingScoreByPeriodList(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetcompetitionRankingScoreByPeriodListRequest(stream); - } else { - return new Responses.GetcompetitionRankingScoreByPeriodListResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UploadCompetitionRankingScore(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UploadCompetitionRankingScoreRequest(stream); - } else { - return new Responses.UploadCompetitionRankingScoreResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteCompetitionRankingScore(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteCompetitionRankingScoreRequest(stream); - } else { - return new Responses.DeleteCompetitionRankingScoreResponse(stream); - } - } -} - -module.exports = RankingSplatoon; \ No newline at end of file diff --git a/src/protocols/patches/secure_connection_badge_arcade.js b/src/protocols/patches/secure_connection_badge_arcade.js deleted file mode 100644 index 3ad674d..0000000 --- a/src/protocols/patches/secure_connection_badge_arcade.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @typedef {import('../../packet')} Packet - * @typedef {import('../../packetv0')} PacketV0 - * @typedef {import('../../packetv1')} PacketV1 - * @typedef {import('../../rmc')} RMCMessage - */ - -const Stream = require('../../stream'); - -const Requests = require('../requests/secure_connection_badge_arcade'); -const Responses = require('../responses/secure_connection_badge_arcade'); - -class SecureConnectionBadgeArcade { - static ProtocolID = 0xB; - - static ProtocolName = 'Secure Connection (Badge Arcade)'; - - static Methods = { - GetMaintenanceStatus: 0x9 - }; - - static MethodNames = Object.entries(SecureConnectionBadgeArcade.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x9: SecureConnectionBadgeArcade.GetMaintenanceStatus - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = SecureConnectionBadgeArcade.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Secure Connection (Badge Arcade) method ID ${methodId} (0x${methodId.toString(16)}) (${SecureConnectionBadgeArcade.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetMaintenanceStatus(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetMaintenanceStatusRequest(stream); - } else { - return new Responses.GetMaintenanceStatusResponse(stream); - } - } -} - -module.exports = SecureConnectionBadgeArcade; diff --git a/src/protocols/patches/service_item_tkcd.js b/src/protocols/patches/service_item_tkcd.js deleted file mode 100644 index ef17579..0000000 --- a/src/protocols/patches/service_item_tkcd.js +++ /dev/null @@ -1,408 +0,0 @@ -/** - * @typedef {import('../../packet')} Packet - * @typedef {import('../../packetv0')} PacketV0 - * @typedef {import('../../packetv1')} PacketV1 - * @typedef {import('../../rmc')} RMCMessage - */ - -const Stream = require('../../stream'); - -const Requests = require('../requests/service_item_tkcd'); -const Responses = require('../responses/service_item_tkcd'); - -class ServiceItemTKCD { - static ProtocolID = 0x77; - - static ProtocolName = 'Service Item (TKCD)'; - - static Methods = { - GetEnvironment: 0x01, - HttpGetRequest: 0x02, - HttpGetResponse: 0x03, - PurchaseServiceItemRequest: 0x04, - PurchaseServiceItemResponse: 0x05, - ListServiceItemRequest: 0x06, - ListServiceItemResponse: 0x07, - GetBalanceRequest: 0x08, - GetBalanceResponse: 0x09, - GetPrepurchaseInfoRequest: 0x0a, - GetPrepurchaseInfoResponse: 0x0b, - GetServiceItemRightRequest: 0x0c, - GetServiceItemRightResponse: 0x0d, - GetPurchaseHistoryRequest: 0x0e, - GetPurchaseHistoryResponse: 0x0f, - PostRightBinaryByAccount: 0x10, - UseServiceItemByAccountRequest: 0x11, - UseServiceItemByAccountResponse: 0x12, - AcquireServiceItemByAccount: 0x13, - GetSupportId: 0x14, - GetLawMessageRequest: 0x15, - GetLawMessageResponse: 0x16, - }; - - static MethodNames = Object.entries(ServiceItemTKCD.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x01: ServiceItemTKCD.GetEnvironment, - 0x02: ServiceItemTKCD.HttpGetRequest, - 0x03: ServiceItemTKCD.HttpGetResponse, - 0x04: ServiceItemTKCD.PurchaseServiceItemRequest, - 0x05: ServiceItemTKCD.PurchaseServiceItemResponse, - 0x06: ServiceItemTKCD.ListServiceItemRequest, - 0x07: ServiceItemTKCD.ListServiceItemResponse, - 0x08: ServiceItemTKCD.GetBalanceRequest, - 0x09: ServiceItemTKCD.GetBalanceResponse, - 0x0a: ServiceItemTKCD.GetPrepurchaseInfoRequest, - 0x0b: ServiceItemTKCD.GetPrepurchaseInfoResponse, - 0x0c: ServiceItemTKCD.GetServiceItemRightRequest, - 0x0d: ServiceItemTKCD.GetServiceItemRightResponse, - 0x0e: ServiceItemTKCD.GetPurchaseHistoryRequest, - 0x0f: ServiceItemTKCD.GetPurchaseHistoryResponse, - 0x10: ServiceItemTKCD.PostRightBinaryByAccount, - 0x11: ServiceItemTKCD.UseServiceItemByAccountRequest, - 0x12: ServiceItemTKCD.UseServiceItemByAccountResponse, - 0x13: ServiceItemTKCD.AcquireServiceItemByAccount, - 0x14: ServiceItemTKCD.GetSupportId, - 0x15: ServiceItemTKCD.GetLawMessageRequest, - 0x16: ServiceItemTKCD.GetLawMessageResponse - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = ServiceItemTKCD.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Service Item (TKCD) method ID ${methodId} (0x${methodId?.toString(16)}) (${ServiceItemTKCD.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetEnvironment(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetEnvironmentRequest(stream); - } else { - return new Responses.GetEnvironmentResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static HttpGetRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.HttpGetRequestRequest(stream); - } else { - return new Responses.HttpGetRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static HttpGetResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.HttpGetResponseRequest(stream); - } else { - return new Responses.HttpGetResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PurchaseServiceItemRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PurchaseServiceItemRequestRequest(stream); - } else { - return new Responses.PurchaseServiceItemRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PurchaseServiceItemResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PurchaseServiceItemResponseRequest(stream); - } else { - return new Responses.PurchaseServiceItemResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ListServiceItemRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ListServiceItemRequestRequest(stream); - } else { - return new Responses.ListServiceItemRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ListServiceItemResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ListServiceItemResponseRequest(stream); - } else { - return new Responses.ListServiceItemResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetBalanceRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetBalanceRequestRequest(stream); - } else { - return new Responses.GetBalanceRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetBalanceResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetBalanceResponseRequest(stream); - } else { - return new Responses.GetBalanceResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPrepurchaseInfoRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPrepurchaseInfoRequestRequest(stream); - } else { - return new Responses.GetPrepurchaseInfoRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPrepurchaseInfoResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPrepurchaseInfoResponseRequest(stream); - } else { - return new Responses.GetPrepurchaseInfoResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetServiceItemRightRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetServiceItemRightRequestRequest(stream); - } else { - return new Responses.GetServiceItemRightRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetServiceItemRightResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetServiceItemRightResponseRequest(stream); - } else { - return new Responses.GetServiceItemRightResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPurchaseHistoryRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPurchaseHistoryRequestRequest(stream); - } else { - return new Responses.GetPurchaseHistoryRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPurchaseHistoryResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPurchaseHistoryResponseRequest(stream); - } else { - return new Responses.GetPurchaseHistoryResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PostRightBinaryByAccount(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PostRightBinaryByAccountRequest(stream); - } else { - return new Responses.PostRightBinaryByAccountResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UseServiceItemByAccountRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UseServiceItemByAccountRequestRequest(stream); - } else { - return new Responses.UseServiceItemByAccountRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UseServiceItemByAccountResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UseServiceItemByAccountResponseRequest(stream); - } else { - return new Responses.UseServiceItemByAccountResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AcquireServiceItemByAccount(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AcquireServiceItemByAccountRequest(stream); - } else { - return new Responses.AcquireServiceItemByAccountResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetSupportId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetSupportIdRequest(stream); - } else { - return new Responses.GetSupportIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetLawMessageRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetLawMessageRequestRequest(stream); - } else { - return new Responses.GetLawMessageRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetLawMessageResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetLawMessageResponseRequest(stream); - } else { - return new Responses.GetLawMessageResponseResponse(stream); - } - } -} - - -module.exports = ServiceItemTKCD; diff --git a/src/protocols/patches/service_item_wii_sports_club.js b/src/protocols/patches/service_item_wii_sports_club.js deleted file mode 100644 index bd2ca26..0000000 --- a/src/protocols/patches/service_item_wii_sports_club.js +++ /dev/null @@ -1,408 +0,0 @@ -/** - * @typedef {import('../../packet')} Packet - * @typedef {import('../../packetv0')} PacketV0 - * @typedef {import('../../packetv1')} PacketV1 - * @typedef {import('../../rmc')} RMCMessage - */ - -const Stream = require('../../stream'); - -const Requests = require('../requests/service_item_wii_sports_club'); -const Responses = require('../responses/service_item_wii_sports_club'); - -class ServiceItemWiiSportsClub { - static ProtocolID = 0x77; - - static ProtocolName = 'Service Item (Wii Sports Club)'; - - static Methods = { - Hello: 0x01, - HttpGetRequest: 0x02, - HttpGetResponse: 0x03, - PurchaseServiceItemRequest: 0x04, - PurchaseServiceItemResponse: 0x05, - ListServiceItemRequest: 0x06, - ListServiceItemResponse: 0x07, - GetBalanceRequest: 0x08, - GetBalanceResponse: 0x09, - GetPrepurchaseInfoRequest: 0x0a, - GetPrepurchaseInfoResponse: 0x0b, - GetServiceItemRightRequest: 0x0c, - GetServiceItemRightResponse: 0x0d, - GetPurchaseHistoryRequest: 0x0e, - GetPurchaseHistoryResponse: 0x0f, - GetNotice: 0x10, - UpdateAndGetTicketInfo: 0x11, - LoadUserInfo: 0x12, - SaveUserInfo: 0x13, - StartChallenge: 0x14, - EndChallenge: 0x15, - RequestTicketRestoration: 0x16, - }; - - static MethodNames = Object.entries(ServiceItemWiiSportsClub.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x01: ServiceItemWiiSportsClub.Hello, - 0x02: ServiceItemWiiSportsClub.HttpGetRequest, - 0x03: ServiceItemWiiSportsClub.HttpGetResponse, - 0x04: ServiceItemWiiSportsClub.PurchaseServiceItemRequest, - 0x05: ServiceItemWiiSportsClub.PurchaseServiceItemResponse, - 0x06: ServiceItemWiiSportsClub.ListServiceItemRequest, - 0x07: ServiceItemWiiSportsClub.ListServiceItemResponse, - 0x08: ServiceItemWiiSportsClub.GetBalanceRequest, - 0x09: ServiceItemWiiSportsClub.GetBalanceResponse, - 0x0a: ServiceItemWiiSportsClub.GetPrepurchaseInfoRequest, - 0x0b: ServiceItemWiiSportsClub.GetPrepurchaseInfoResponse, - 0x0c: ServiceItemWiiSportsClub.GetServiceItemRightRequest, - 0x0d: ServiceItemWiiSportsClub.GetServiceItemRightResponse, - 0x0e: ServiceItemWiiSportsClub.GetPurchaseHistoryRequest, - 0x0f: ServiceItemWiiSportsClub.GetPurchaseHistoryResponse, - 0x10: ServiceItemWiiSportsClub.GetNotice, - 0x11: ServiceItemWiiSportsClub.UpdateAndGetTicketInfo, - 0x12: ServiceItemWiiSportsClub.LoadUserInfo, - 0x13: ServiceItemWiiSportsClub.SaveUserInfo, - 0x14: ServiceItemWiiSportsClub.StartChallenge, - 0x15: ServiceItemWiiSportsClub.EndChallenge, - 0x16: ServiceItemWiiSportsClub.RequestTicketRestoration - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = ServiceItemWiiSportsClub.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Service Item (Wii Sports Club) method ID ${methodId} (0x${methodId?.toString(16)}) (${ServiceItemWiiSportsClub.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static Hello(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.HelloRequest(stream); - } else { - return new Responses.HelloResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static HttpGetRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.HttpGetRequestRequest(stream); - } else { - return new Responses.HttpGetRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static HttpGetResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.HttpGetResponseRequest(stream); - } else { - return new Responses.HttpGetResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PurchaseServiceItemRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PurchaseServiceItemRequestRequest(stream); - } else { - return new Responses.PurchaseServiceItemRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PurchaseServiceItemResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PurchaseServiceItemResponseRequest(stream); - } else { - return new Responses.PurchaseServiceItemResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ListServiceItemRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ListServiceItemRequestRequest(stream); - } else { - return new Responses.ListServiceItemRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ListServiceItemResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ListServiceItemResponseRequest(stream); - } else { - return new Responses.ListServiceItemResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetBalanceRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetBalanceRequestRequest(stream); - } else { - return new Responses.GetBalanceRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetBalanceResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetBalanceResponseRequest(stream); - } else { - return new Responses.GetBalanceResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPrepurchaseInfoRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPrepurchaseInfoRequestRequest(stream); - } else { - return new Responses.GetPrepurchaseInfoRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPrepurchaseInfoResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPrepurchaseInfoResponseRequest(stream); - } else { - return new Responses.GetPrepurchaseInfoResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetServiceItemRightRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetServiceItemRightRequestRequest(stream); - } else { - return new Responses.GetServiceItemRightRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetServiceItemRightResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetServiceItemRightResponseRequest(stream); - } else { - return new Responses.GetServiceItemRightResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPurchaseHistoryRequest(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPurchaseHistoryRequestRequest(stream); - } else { - return new Responses.GetPurchaseHistoryRequestResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPurchaseHistoryResponse(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPurchaseHistoryResponseRequest(stream); - } else { - return new Responses.GetPurchaseHistoryResponseResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetNotice(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetNoticeRequest(stream); - } else { - return new Responses.GetNoticeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateAndGetTicketInfo(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateAndGetTicketInfoRequest(stream); - } else { - return new Responses.UpdateAndGetTicketInfoResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static LoadUserInfo(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.LoadUserInfoRequest(stream); - } else { - return new Responses.LoadUserInfoResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SaveUserInfo(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SaveUserInfoRequest(stream); - } else { - return new Responses.SaveUserInfoResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static StartChallenge(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.StartChallengeRequest(stream); - } else { - return new Responses.StartChallengeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static EndChallenge(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.EndChallengeRequest(stream); - } else { - return new Responses.EndChallengeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RequestTicketRestoration(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RequestTicketRestorationRequest(stream); - } else { - return new Responses.RequestTicketRestorationResponse(stream); - } - } -} - - -module.exports = ServiceItemWiiSportsClub; diff --git a/src/protocols/patches/shop_badge_arcade.js b/src/protocols/patches/shop_badge_arcade.js deleted file mode 100644 index 88fe948..0000000 --- a/src/protocols/patches/shop_badge_arcade.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @typedef {import('../../packet')} Packet - * @typedef {import('../../packetv0')} PacketV0 - * @typedef {import('../../packetv1')} PacketV1 - * @typedef {import('../../rmc')} RMCMessage - */ - -const Stream = require('../../stream'); - -const Requests = require('../requests/shop_badge_arcade'); -const Responses = require('../responses/shop_badge_arcade'); - -class ShopBadgeArcade { - static ProtocolID = 0xC8; - - static ProtocolName = 'Shop (Badge Arcade)'; - - static Methods = { - GetRivToken: 0x1, - PostPlayLog: 0x2 - }; - - static MethodNames = Object.entries(ShopBadgeArcade.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x1: ShopBadgeArcade.GetRivToken, - 0x2: ShopBadgeArcade.PostPlayLog - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = ShopBadgeArcade.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Shop (Badge Arcade) method ID ${methodId} (0x${methodId?.toString(16)}) (${ShopBadgeArcade.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetRivToken(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetRivTokenRequest(stream); - } else { - return new Responses.GetRivTokenResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PostPlayLog(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PostPlayLogRequest(stream); - } else { - return new Responses.PostPlayLogResponse(stream); - } - } -} - -module.exports = ShopBadgeArcade; diff --git a/src/protocols/patches/shop_pokemon_bank.js b/src/protocols/patches/shop_pokemon_bank.js deleted file mode 100644 index 61340f2..0000000 --- a/src/protocols/patches/shop_pokemon_bank.js +++ /dev/null @@ -1,215 +0,0 @@ -/** - * @typedef {import('../../packet')} Packet - * @typedef {import('../../packetv0')} PacketV0 - * @typedef {import('../../packetv1')} PacketV1 - * @typedef {import('../../rmc')} RMCMessage - */ - -const Stream = require('../../stream'); - -const Requests = require('../requests/shop_pokemon_bank'); -const Responses = require('../responses/shop_pokemon_bank'); - -class ShopPokemonBank { - static ProtocolID = 0xC8; - - static ProtocolName = 'Shop (Pokémon Bank)'; - - static Methods = { - GetItems: 0x1, - GetChallengeBlob: 0x2, - GetRivToken: 0x3, - GetRivTokenByItemId: 0x4, - GetItemRights: 0x5, - VerifyAndRegisterTicket: 0x6, - DebugSetExpireTime: 0x7, - PrincipalIDToSupportNumber: 0x8, - SupportNumberToPrincipalID: 0x9, - GetGameServerTime: 0xa, - }; - - static MethodNames = Object.entries(ShopPokemonBank.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x1: ShopPokemonBank.GetItems, - 0x2: ShopPokemonBank.GetChallengeBlob, - 0x3: ShopPokemonBank.GetRivToken, - 0x4: ShopPokemonBank.GetRivTokenByItemId, - 0x5: ShopPokemonBank.GetItemRights, - 0x6: ShopPokemonBank.VerifyAndRegisterTicket, - 0x7: ShopPokemonBank.DebugSetExpireTime, - 0x8: ShopPokemonBank.PrincipalIDToSupportNumber, - 0x9: ShopPokemonBank.SupportNumberToPrincipalID, - 0xa: ShopPokemonBank.GetGameServerTime, - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = ShopPokemonBank.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Shop (Pokémon Bank) method ID ${methodId} (0x${methodId?.toString(16)}) (${ShopPokemonBank.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetItems(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetItemsRequest(stream); - } else { - return new Responses.GetItemsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetChallengeBlob(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetChallengeBlobRequest(stream); - } else { - return new Responses.GetChallengeBlobResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetRivToken(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetRivTokenRequest(stream); - } else { - return new Responses.GetRivTokenResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetRivTokenByItemId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetRivTokenByItemIdRequest(stream); - } else { - return new Responses.GetRivTokenByItemIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetItemRights(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetItemRightsRequest(stream); - } else { - return new Responses.GetItemRightsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static VerifyAndRegisterTicket(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.VerifyAndRegisterTicketRequest(stream); - } else { - return new Responses.VerifyAndRegisterTicketResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DebugSetExpireTime(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DebugSetExpireTimeRequest(stream); - } else { - return new Responses.DebugSetExpireTimeResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static PrincipalIDToSupportNumber(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.PrincipalIDToSupportNumberRequest(stream); - } else { - return new Responses.PrincipalIDToSupportNumberResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SupportNumberToPrincipalID(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SupportNumberToPrincipalIDRequest(stream); - } else { - return new Responses.SupportNumberToPrincipalIDResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetGameServerTime(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetGameServerTimeRequest(stream); - } else { - return new Responses.GetGameServerTimeResponse(stream); - } - } -} - -module.exports = ShopPokemonBank; diff --git a/src/protocols/ranking.js b/src/protocols/ranking.js deleted file mode 100644 index d1a9ce1..0000000 --- a/src/protocols/ranking.js +++ /dev/null @@ -1,313 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const semver = require('semver'); -const Stream = require('../stream'); - -const RankingSplatoon = require('./patches/ranking_splatoon'); -const RankingLegacy = require('./patches/ranking_legacy'); - -const Requests = require('./requests/ranking'); -const Responses = require('./responses/ranking'); - -class Ranking { - static ProtocolID = 0x70; - - static ProtocolName = 'Ranking'; - - static Methods = { - UploadScore: 0x01, - DeleteScore: 0x02, - DeleteAllScores: 0x03, - UploadCommonData: 0x04, - DeleteCommonData: 0x05, - GetCommonData: 0x06, - ChangeAttributes: 0x07, - ChangeAllAttributes: 0x08, - GetRanking: 0x09, - GetApproxOrder: 0x0a, - GetStats: 0x0b, - GetRankingByPIDList: 0x0c, - GetRankingByUniqueIdList: 0x0d, - GetCachedTopXRanking: 0x0e, - GetCachedTopXRankings: 0x0f - }; - - static MethodNames = Object.entries(Ranking.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x01: Ranking.UploadScore, - 0x02: Ranking.DeleteScore, - 0x03: Ranking.DeleteAllScores, - 0x04: Ranking.UploadCommonData, - 0x05: Ranking.DeleteCommonData, - 0x06: Ranking.GetCommonData, - 0x07: Ranking.ChangeAttributes, - 0x08: Ranking.ChangeAllAttributes, - 0x09: Ranking.GetRanking, - 0x0a: Ranking.GetApproxOrder, - 0x0b: Ranking.GetStats, - 0x0c: Ranking.GetRankingByPIDList, - 0x0d: Ranking.GetRankingByUniqueIdList, - 0x0e: Ranking.GetCachedTopXRanking, - 0x0f: Ranking.GetCachedTopXRankings - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - // Check if method is a Splatoon patched method - if (packet.connection.accessKey === '6f599f81' && methodId >= 0x10) { - RankingSplatoon.handlePacket(packet); - return; - } - - const nexVersion = packet.connection.title.nex_ranking_version || packet.connection.title.nex_version; - - // Check if game uses legacy Ranking. Since there aren't many games that use it, - // assume games not listed on title list to use modern Ranking - if (semver.lt(nexVersion, '3.0.0') && semver.gt(nexVersion, '0.0.0')) { - RankingLegacy.handlePacket(packet); - return; - } - - const handler = Ranking.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Ranking method ID ${methodId} (0x${methodId?.toString(16)}) (${Ranking.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UploadScore(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UploadScoreRequest(stream); - } else { - return new Responses.UploadScoreResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteScore(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteScoreRequest(stream); - } else { - return new Responses.DeleteScoreResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteAllScores(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteAllScoresRequest(stream); - } else { - return new Responses.DeleteAllScoresResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UploadCommonData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UploadCommonDataRequest(stream); - } else { - return new Responses.UploadCommonDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteCommonData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteCommonDataRequest(stream); - } else { - return new Responses.DeleteCommonDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetCommonData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetCommonDataRequest(stream); - } else { - return new Responses.GetCommonDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ChangeAttributes(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ChangeAttributesRequest(stream); - } else { - return new Responses.ChangeAttributesResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ChangeAllAttributes(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ChangeAllAttributesRequest(stream); - } else { - return new Responses.ChangeAllAttributesResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetRanking(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetRankingRequest(stream); - } else { - return new Responses.GetRankingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetApproxOrder(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetApproxOrderRequest(stream); - } else { - return new Responses.GetApproxOrderResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetStats(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetStatsRequest(stream); - } else { - return new Responses.GetStatsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetRankingByPIDList(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetRankingByPIDListRequest(stream); - } else { - return new Responses.GetRankingByPIDListResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetRankingByUniqueIdList(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetRankingByUniqueIdListRequest(stream); - } else { - return new Responses.GetRankingByUniqueIdListResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetCachedTopXRanking(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetCachedTopXRankingRequest(stream); - } else { - return new Responses.GetCachedTopXRankingResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetCachedTopXRankings(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetCachedTopXRankingsRequest(stream); - } else { - return new Responses.GetCachedTopXRankingsResponse(stream); - } - } -} - - -module.exports = Ranking; diff --git a/src/protocols/requests/authentication.js b/src/protocols/requests/authentication.js deleted file mode 100644 index db38551..0000000 --- a/src/protocols/requests/authentication.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const AuthenticationTypes = require('../types/authentication'); - -class LoginRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.strUserName = stream.readNEXString(); - } - - toJSON() { - return { - strUserName: { - __typeName: 'String', - __typeValue: this.strUserName - } - }; - } -} - -class LoginExRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.strUserName = stream.readNEXString(); - this.oExtraData = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - strUserName: { - __typeName: 'String', - __typeValue: this.strUserName - }, - oExtraData: { - __typeName: 'AnyDataHolder', - __typeValue: this.oExtraData - } - }; - } -} - -class RequestTicketRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idSource = stream.readPID(); - this.idTarget = stream.readPID(); - } - - toJSON() { - return { - idSource: { - __typeName: 'PID', - __typeValue: this.idSource - }, - idTarget: { - __typeName: 'PID', - __typeValue: this.idTarget - } - }; - } -} - -class GetPIDRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.strUserName = stream.readNEXString(); - } - - toJSON() { - return { - strUserName: { - __typeName: 'String', - __typeValue: this.strUserName - } - }; - } -} - -class GetNameRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.id = stream.readPID(); - } - - toJSON() { - return { - id: { - __typeName: 'PID', - __typeValue: this.id - } - }; - } -} - -class LoginWithContextRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.loginData = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - loginData: { - __typeName: 'AnyDataHolder', - __typeValue: this.loginData - } - }; - } -} - -class ValidateAndRequestTicketWithParamRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(AuthenticationTypes.ValidateAndRequestTicketParam); - } - - toJSON() { - return { - param: { - __typeName: 'ValidateAndRequestTicketParam', - __typeValue: this.param - } - }; - } -} - -module.exports = { - LoginRequest, - LoginExRequest, - RequestTicketRequest, - GetPIDRequest, - GetNameRequest, - LoginWithContextRequest, - ValidateAndRequestTicketWithParamRequest -}; diff --git a/src/protocols/requests/datastore.js b/src/protocols/requests/datastore.js deleted file mode 100644 index e045c6b..0000000 --- a/src/protocols/requests/datastore.js +++ /dev/null @@ -1,1048 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const semver = require('semver'); -const DataStoreTypes = require('../types/datastore'); - -class PrepareGetObjectV1Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStorePrepareGetParamV1); - } - - toJSON() { - return { - param: { - __typeName: 'DataStorePrepareGetParamV1', - __typeValue: this.param - } - }; - } -} - -class PreparePostObjectV1Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStorePreparePostParamV1); - } - - toJSON() { - return { - param: { - __typeName: 'DataStorePreparePostParamV1', - __typeValue: this.param - } - }; - } -} - -class CompletePostObjectV1Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreCompletePostParamV1); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreCompletePostParamV1', - __typeValue: this.param - } - }; - } -} - -class DeleteObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreDeleteParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreDeleteParam', - __typeValue: this.param - } - }; - } -} - -class DeleteObjectsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.params = stream.readNEXList(DataStoreTypes.DataStoreDeleteParam); - this.transactional = stream.readBoolean(); - } - - toJSON() { - return { - params: { - __typeName: 'List', - __typeValue: this.params - }, - transactional: { - __typeName: 'boolean', - __typeValue: this.transactional - } - }; - } -} - -class ChangeMetaV1Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreChangeMetaParamV1); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreChangeMetaParamV1', - __typeValue: this.param - } - }; - } -} - -class ChangeMetasV1Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIds = stream.readNEXList(stream.readUInt64LE); - this.params = stream.readNEXList(DataStoreTypes.DataStoreChangeMetaParamV1); - this.transactional = stream.readBoolean(); - } - - toJSON() { - return { - dataIds: { - __typeName: 'List', - __typeValue: this.dataIds - }, - param: { - __typeName: 'List', - __typeValue: this.param - }, - transactional: { - __typeName: 'boolean', - __typeValue: this.transactional - } - }; - } -} - -class GetMetaRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreGetMetaParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreGetMetaParam', - __typeValue: this.param - } - }; - } -} - -class GetMetasRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIds = stream.readNEXList(stream.readUInt64LE); - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreGetMetaParam); - } - - toJSON() { - return { - dataIds: { - __typeName: 'List', - __typeValue: this.dataIds - }, - param: { - __typeName: 'DataStoreGetMetaParam', - __typeValue: this.param - } - }; - } -} - -class PrepareUpdateObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStorePrepareUpdateParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStorePrepareUpdateParam', - __typeValue: this.param - } - }; - } -} - -class CompleteUpdateObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreCompleteUpdateParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreCompleteUpdateParam', - __typeValue: this.param - } - }; - } -} - -class SearchObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreSearchParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreSearchParam', - __typeValue: this.param - } - }; - } -} - -class GetNotificationUrlRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreGetNotificationUrlParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreGetNotificationUrlParam', - __typeValue: this.param - } - }; - } -} - -class GetNewArrivedNotificationsV1Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreGetNewArrivedNotificationsParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreGetNewArrivedNotificationsParam', - __typeValue: this.param - } - }; - } -} - -class RateObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - const nexVersion = stream.connection.title.nex_datastore_version || stream.connection.title.nex_version; - - this.target = stream.readNEXStructure(DataStoreTypes.DataStoreRatingTarget); - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreRateObjectParam); - - if (semver.gte(nexVersion, '3.5.0')) { - this.fetchRatings = stream.readBoolean(); - } - } - - toJSON() { - const data = { - target: { - __typeName: 'DataStoreRatingTarget', - __typeValue: this.target - }, - param: { - __typeName: 'DataStoreRateObjectParam', - __typeValue: this.param - }, - }; - - if (this.fetchRatings !== undefined) { - data.fetchRatings = { - __typeName: 'boolean', - __typeValue: this.fetchRatings - }; - } - - return data; - } -} - -class GetRatingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.target = stream.readNEXStructure(DataStoreTypes.DataStoreRatingTarget); - this.accessPassword = stream.readUInt64LE(); - } - - toJSON() { - return { - target: { - __typeName: 'DataStoreRatingTarget', - __typeValue: this.target - }, - accessPassword: { - __typeName: 'uint64', - __typeValue: this.accessPassword - } - }; - } -} - -class GetRatingsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIds = stream.readNEXList(stream.readUInt64LE); - this.accessPassword = stream.readUInt64LE(); - } - - toJSON() { - return { - dataIds: { - __typeName: 'List', - __typeValue: this.dataIds - }, - accessPassword: { - __typeName: 'uint64', - __typeValue: this.accessPassword - } - }; - } -} - -class ResetRatingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.target = stream.readNEXStructure(DataStoreTypes.DataStoreRatingTarget); - this.accessPassword = stream.readUInt64LE(); - } - - toJSON() { - return { - target: { - __typeName: 'DataStoreRatingTarget', - __typeValue: this.target - }, - accessPassword: { - __typeName: 'uint64', - __typeValue: this.accessPassword - } - }; - } -} - -class ResetRatingsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIds = stream.readNEXList(stream.readUInt64LE); - this.transactional = stream.readBoolean(); - } - - toJSON() { - return { - dataIds: { - __typeName: 'List', - __typeValue: this.dataIds - }, - transactional: { - __typeName: 'boolean', - __typeValue: this.transactional - } - }; - } -} - -class GetSpecificMetaV1Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreGetSpecificMetaParamV1); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreGetSpecificMetaParamV1', - __typeValue: this.param - } - }; - } -} - -class PostMetaBinaryRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStorePreparePostParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStorePreparePostParam', - __typeValue: this.param - } - }; - } -} - -class TouchObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreTouchObjectParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreTouchObjectParam', - __typeValue: this.param - } - }; - } -} - -class GetRatingWithLogRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.target = stream.readNEXStructure(DataStoreTypes.DataStoreRatingTarget); - this.accessPassword = stream.readUInt64LE(); - } - - toJSON() { - return { - target: { - __typeName: 'DataStoreRatingTarget', - __typeValue: this.target - }, - accessPassword: { - __typeName: 'uint64', - __typeValue: this.accessPassword - } - }; - } -} - -class PreparePostObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStorePreparePostParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStorePreparePostParam', - __typeValue: this.param - } - }; - } -} - -class PrepareGetObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStorePrepareGetParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStorePrepareGetParam', - __typeValue: this.param - } - }; - } -} - -class CompletePostObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreCompletePostParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreCompletePostParam', - __typeValue: this.param - } - }; - } -} - -class GetNewArrivedNotificationsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreGetNewArrivedNotificationsParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreGetNewArrivedNotificationsParam', - __typeValue: this.param - } - }; - } -} - -class GetSpecificMetaRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreGetSpecificMetaParam); - } - - toJSON() { - return { - param: { - __typeName: 'GetSpecificMetaRequest', - __typeValue: this.param - } - }; - } -} - -class GetPersistenceInfoRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.ownerId = stream.readPID(); - this.persistenceSlotId = stream.readUInt16LE(); - } - - toJSON() { - return { - ownerId: { - __typeName: 'PID', - __typeValue: this.ownerId - }, - persistenceSlotId: { - __typeName: 'uint16', - __typeValue: this.persistenceSlotId - } - }; - } -} - -class GetPersistenceInfosRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.ownerId = stream.readPID(); - this.persistenceSlotIds = stream.readNEXList(stream.readUInt16LE); - } - - toJSON() { - return { - ownerId: { - __typeName: 'PID', - __typeValue: this.ownerId - }, - persistenceSlotIds: { - __typeName: 'List', - __typeValue: this.persistenceSlotIds - } - }; - } -} - -class PerpetuateObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.persistenceSlotId = stream.readUInt16LE(); - this.dataId = stream.readUInt64LE(); - this.deleteLastObject = stream.readBoolean(); - } - - toJSON() { - return { - persistenceSlotId: { - __typeName: 'uint16', - __typeValue: this.persistenceSlotId - }, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - deleteLastObject: { - __typeName: 'boolean', - __typeValue: this.deleteLastObject - } - }; - } -} - -class UnperpetuateObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.persistenceSlotId = stream.readUInt16LE(); - this.deleteLastObject = stream.readBoolean(); - } - - toJSON() { - return { - persistenceSlotId: { - __typeName: 'uint16', - __typeValue: this.persistenceSlotId - }, - deleteLastObject: { - __typeName: 'boolean', - __typeValue: this.deleteLastObject - } - }; - } -} - -class PrepareGetObjectOrMetaBinaryRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStorePrepareGetParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStorePrepareGetParam', - __typeValue: this.param - } - }; - } -} - -class GetPasswordInfoRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataId = stream.readUInt64LE(); - } - - toJSON() { - return { - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - } - }; - } -} - -class GetPasswordInfosRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIds = stream.readNEXList(stream.readUInt64LE); - } - - toJSON() { - return { - dataId: { - __typeName: 'List', - __typeValue: this.dataId - } - }; - } -} - -class GetMetasMultipleParamRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.params = stream.readNEXList(DataStoreTypes.DataStoreGetMetaParam); - } - - toJSON() { - return { - params: { - __typeName: 'List', - __typeValue: this.params - } - }; - } -} - -class CompletePostObjectsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIds = stream.readNEXList(stream.readUInt64LE); - } - - toJSON() { - return { - dataIds: { - __typeName: 'List', - __typeValue: this.dataIds - } - }; - } -} - -class ChangeMetaRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreChangeMetaParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreChangeMetaParam', - __typeValue: this.param - } - }; - } -} - -class ChangeMetasRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIds = stream.readNEXList(stream.readUInt64LE); - this.params = stream.readNEXList(DataStoreTypes.DataStoreChangeMetaParam); - this.transactional = stream.readBoolean(); - } - - toJSON() { - return { - dataIds: { - __typeName: 'List', - __typeValue: this.dataIds - }, - params: { - __typeName: 'List', - __typeValue: this.params - }, - transactional: { - __typeName: 'boolean', - __typeValue: this.transactional - } - }; - } -} - -class RateObjectsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.targets = stream.readNEXList(DataStoreTypes.DataStoreRatingTarget); - this.params = stream.readNEXList(DataStoreTypes.DataStoreRateObjectParam); - this.transactional = stream.readBoolean(); - this.fetchRatings = stream.readBoolean(); - } - - toJSON() { - return { - targets: { - __typeName: 'List', - __typeValue: this.targets - }, - params: { - __typeName: 'List', - __typeValue: this.params - }, - transactional: { - __typeName: 'boolean', - __typeValue: this.transactional - }, - fetchRatings: { - __typeName: 'boolean', - __typeValue: this.fetchRatings - } - }; - } -} - -class PostMetaBinaryWithDataIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataId = stream.readUInt64LE(); - this.param = stream.readNEXStructure(DataStoreTypes.DataStorePreparePostParam); - } - - toJSON() { - return { - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - param: { - __typeName: 'DataStorePreparePostParam', - __typeValue: this.param - } - }; - } -} - -class PostMetaBinariesWithDataIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIds = stream.readNEXList(stream.readUInt64LE); - this.params = stream.readNEXList(DataStoreTypes.DataStorePreparePostParam); - this.transactional = stream.readBoolean(); - } - - toJSON() { - return { - dataIds: { - __typeName: 'List', - __typeValue: this.dataIds - }, - params: { - __typeName: 'List', - __typeValue: this.params - }, - transactional: { - __typeName: 'boolean', - __typeValue: this.transactional - } - }; - } -} - -class RateObjectWithPostingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.target = stream.readNEXStructure(DataStoreTypes.DataStoreRatingTarget); - this.rateParam = stream.readNEXStructure(DataStoreTypes.DataStoreRateObjectParam); - this.postParam = stream.readNEXStructure(DataStoreTypes.DataStorePreparePostParam); - this.fetchRatings = stream.readBoolean(); - } - - toJSON() { - return { - target: { - __typeName: 'DataStoreRatingTarget', - __typeValue: this.target - }, - rateParam: { - __typeName: 'DataStoreRateObjectParam', - __typeValue: this.rateParam - }, - postParam: { - __typeName: 'DataStorePreparePostParam', - __typeValue: this.postParam - }, - fetchRatings: { - __typeName: 'boolean', - __typeValue: this.fetchRatings - } - }; - } -} - -class RateObjectsWithPostingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.targets = stream.readNEXList(DataStoreTypes.DataStoreRatingTarget); - this.rateParams = stream.readNEXList(DataStoreTypes.DataStoreRateObjectParam); - this.postParams = stream.readNEXList(DataStoreTypes.DataStorePreparePostParam); - this.transactional = stream.readBoolean(); - this.fetchRatings = stream.readBoolean(); - } - - toJSON() { - return { - targets: { - __typeName: 'List', - __typeValue: this.targets - }, - rateParams: { - __typeName: 'List', - __typeValue: this.rateParams - }, - postParams: { - __typeName: 'List', - __typeValue: this.postParams - }, - transactional: { - __typeName: 'boolean', - __typeValue: this.transactional - }, - fetchRatings: { - __typeName: 'boolean', - __typeValue: this.fetchRatings - } - }; - } -} - -class GetObjectInfosRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIds = stream.readNEXList(stream.readUInt64LE); - } - - toJSON() { - return { - dataIds: { - __typeName: 'List', - __typeValue: this.dataIds - } - }; - } -} - -class SearchObjectLightRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreSearchParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreSearchParam', - __typeValue: this.param - } - }; - } -} - -module.exports = { - PrepareGetObjectV1Request, - PreparePostObjectV1Request, - CompletePostObjectV1Request, - DeleteObjectRequest, - DeleteObjectsRequest, - ChangeMetaV1Request, - ChangeMetasV1Request, - GetMetaRequest, - GetMetasRequest, - PrepareUpdateObjectRequest, - CompleteUpdateObjectRequest, - SearchObjectRequest, - GetNotificationUrlRequest, - GetNewArrivedNotificationsV1Request, - RateObjectRequest, - GetRatingRequest, - GetRatingsRequest, - ResetRatingRequest, - ResetRatingsRequest, - GetSpecificMetaV1Request, - PostMetaBinaryRequest, - TouchObjectRequest, - GetRatingWithLogRequest, - PreparePostObjectRequest, - PrepareGetObjectRequest, - CompletePostObjectRequest, - GetNewArrivedNotificationsRequest, - GetSpecificMetaRequest, - GetPersistenceInfoRequest, - GetPersistenceInfosRequest, - PerpetuateObjectRequest, - UnperpetuateObjectRequest, - PrepareGetObjectOrMetaBinaryRequest, - GetPasswordInfoRequest, - GetPasswordInfosRequest, - GetMetasMultipleParamRequest, - CompletePostObjectsRequest, - ChangeMetaRequest, - ChangeMetasRequest, - RateObjectsRequest, - PostMetaBinaryWithDataIdRequest, - PostMetaBinariesWithDataIdRequest, - RateObjectWithPostingRequest, - RateObjectsWithPostingRequest, - GetObjectInfosRequest, - SearchObjectLightRequest -}; diff --git a/src/protocols/requests/datastore_badge_arcade.js b/src/protocols/requests/datastore_badge_arcade.js deleted file mode 100644 index 74dbad7..0000000 --- a/src/protocols/requests/datastore_badge_arcade.js +++ /dev/null @@ -1,25 +0,0 @@ -const Stream = require('../../stream'); - -const DataStoreBadgeArcadeTypes = require('../types/datastore_badge_arcade'); - -class GetMetaByOwnerIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreBadgeArcadeTypes.DataStoreGetMetaByOwnerIdParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreGetMetaByOwnerIdParam', - __typeValue: this.param - } - }; - } -} - -module.exports = { - GetMetaByOwnerIdRequest -}; diff --git a/src/protocols/requests/datastore_pokemon_bank.js b/src/protocols/requests/datastore_pokemon_bank.js deleted file mode 100644 index 200c1d8..0000000 --- a/src/protocols/requests/datastore_pokemon_bank.js +++ /dev/null @@ -1,362 +0,0 @@ -const Stream = require('../../stream'); - -const DataStoreTypes = require('../types/datastore'); -const DataStorePokemonBankTypes = require('../types/datastore_pokemon_bank'); - -class PrepareUploadPokemonRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class UploadPokemonRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationUploadPokemonParam); - } - - toJSON() { - return { - param: { - __typeName: 'GlobalTradeStationUploadPokemonParam', - __typeValue: this.param - } - }; - } -} - -class SearchPokemonRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationSearchPokemonParam); - } - - toJSON() { - return { - param: { - __typeName: 'GlobalTradeStationSearchPokemonParam', - __typeValue: this.param - } - }; - } -} - -class PrepareTradePokemonRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationPrepareTradePokemonParam); - } - - toJSON() { - return { - param: { - __typeName: 'GlobalTradeStationPrepareTradePokemonParam', - __typeValue: this.param - } - }; - } -} - -class TradePokemonRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationTradePokemonParam); - } - - toJSON() { - return { - param: { - __typeName: 'GlobalTradeStationTradePokemonParam', - __typeValue: this.param - } - }; - } -} - -class DownloadOtherPokemonRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationDownloadOtherPokemonParam); - } - - toJSON() { - return { - param: { - __typeName: 'GlobalTradeStationDownloadOtherPokemonParam', - __typeValue: this.param - } - }; - } -} - -class DownloadMyPokemonRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationDownloadMyPokemonParam); - } - - toJSON() { - return { - param: { - __typeName: 'GlobalTradeStationDownloadMyPokemonParam', - __typeValue: this.param - } - }; - } -} - -class DeletePokemonRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationDeletePokemonParam); - } - - toJSON() { - return { - param: { - __typeName: 'GlobalTradeStationDeletePokemonParam', - __typeValue: this.param - } - }; - } -} - -class GetTransactionParamRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.slotId = stream.readUInt16LE(); - } - - toJSON() { - return { - slotId: { - __typeName: 'uint16', - __typeValue: this.slotId - } - }; - } -} - -class PreparePostBankObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.slotId = stream.readUInt16LE(); - this.size = stream.readUInt32LE(); - } - - toJSON() { - return { - slotId: { - __typeName: 'uint16', - __typeValue: this.slotId - }, - size: { - __typeName: 'uint32', - __typeValue: this.size - } - }; - } -} - -class CompletePostBankObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreCompletePostParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreCompletePostParam', - __typeValue: this.param - } - }; - } -} - -class PrepareGetBankObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.slotId = stream.readUInt16LE(); - this.applicationId = stream.readUInt16LE(); - } - - toJSON() { - return { - slotId: { - __typeName: 'uint16', - __typeValue: this.slotId - }, - applicationId: { - __typeName: 'uint16', - __typeValue: this.applicationId - } - }; - } -} - -class PrepareUpdateBankObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.transactionParam = stream.readNEXStructure(DataStorePokemonBankTypes.BankTransactionParam); - } - - toJSON() { - return { - transactionParam: { - __typeName: 'BankTransactionParam', - __typeValue: this.transactionParam - } - }; - } -} - -class CompleteUpdateBankObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.slotId = stream.readUInt16LE(); - this.transactionParam = stream.readNEXStructure(DataStorePokemonBankTypes.BankTransactionParam); - this.isForce = stream.readBoolean(); - } - - toJSON() { - return { - slotId: { - __typeName: 'uint16', - __typeValue: this.slotId - }, - transactionParam: { - __typeName: 'BankTransactionParam', - __typeValue: this.transactionParam - }, - isForce: { - __typeName: 'boolean', - __typeValue: this.isForce - } - }; - } -} - -class RollbackBankObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.slotId = stream.readUInt16LE(); - this.transactionParam = stream.readNEXStructure(DataStorePokemonBankTypes.BankTransactionParam); - this.isForce = stream.readBoolean(); - } - - toJSON() { - return { - slotId: { - __typeName: 'uint16', - __typeValue: this.slotId - }, - transactionParam: { - __typeName: 'BankTransactionParam', - __typeValue: this.transactionParam - }, - isForce: { - __typeName: 'boolean', - __typeValue: this.isForce - } - }; - } -} - -class GetUnlockKeyRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.challengeValue = stream.readUInt32LE(); - } - - toJSON() { - return { - challengeValue: { - __typeName: 'uint32', - __typeValue: this.challengeValue - } - }; - } -} - -class RequestMigrationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.oneTimePassword = stream.readNEXString(); - this.boxes = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - oneTimePassword: { - __typeName: 'String', - __typeValue: this.oneTimePassword - }, - boxes: { - __typeName: 'List', - __typeValue: this.boxes - } - }; - } -} - -class GetMigrationStatusRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -module.exports = { - PrepareUploadPokemonRequest, - UploadPokemonRequest, - SearchPokemonRequest, - PrepareTradePokemonRequest, - TradePokemonRequest, - DownloadOtherPokemonRequest, - DownloadMyPokemonRequest, - DeletePokemonRequest, - GetTransactionParamRequest, - PreparePostBankObjectRequest, - CompletePostBankObjectRequest, - PrepareGetBankObjectRequest, - PrepareUpdateBankObjectRequest, - CompleteUpdateBankObjectRequest, - RollbackBankObjectRequest, - GetUnlockKeyRequest, - RequestMigrationRequest, - GetMigrationStatusRequest -}; diff --git a/src/protocols/requests/datastore_smm.js b/src/protocols/requests/datastore_smm.js deleted file mode 100644 index 0231444..0000000 --- a/src/protocols/requests/datastore_smm.js +++ /dev/null @@ -1,950 +0,0 @@ -const Stream = require('../../stream'); - -const DataStoreTypes = require('../types/datastore'); -const DataStoreSMMTypes = require('../types/datastore_smm'); - -class GetObjectInfosRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIds = stream.readNEXList(stream.readUInt64LE); - } - - toJSON() { - return { - dataIds: { - __typeName: 'List', - __typeValue: this.dataIds - } - }; - } -} - -class GetMetaByOwnerIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreSMMTypes.DataStoreGetMetaByOwnerIdParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreGetMetaByOwnerIdParam', - __typeValue: this.param - } - }; - } -} - -class CustomSearchObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.condition = stream.readUInt32LE(); - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreSearchParam); - } - - toJSON() { - return { - condition: { - __typeName: 'uint32', - __typeValue: this.condition - }, - param: { - __typeName: 'DataStoreSearchParam', - __typeValue: this.param - } - }; - } -} - -class RateCustomRankingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.params = stream.readNEXList(DataStoreSMMTypes.DataStoreRateCustomRankingParam); - } - - toJSON() { - return { - params: { - __typeName: 'List', - __typeValue: this.params - } - }; - } -} - -class GetCustomRankingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreSMMTypes.DataStoreGetCustomRankingParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreGetCustomRankingParam', - __typeValue: this.param - } - }; - } -} - -class GetCustomRankingByDataIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreSMMTypes.DataStoreGetCustomRankingByDataIdParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreGetCustomRankingByDataIdParam', - __typeValue: this.param - } - }; - } -} - -class DeleteCustomRankingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIdList = stream.readNEXList(stream.readUInt64LE); - } - - toJSON() { - return { - dataIdList: { - __typeName: 'List', - __typeValue: this.dataIdList - } - }; - } -} - -class AddToBufferQueueRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreSMMTypes.BufferQueueParam); - this.buffer = stream.readNEXQBuffer(); - } - - toJSON() { - return { - param: { - __typeName: 'BufferQueueParam', - __typeValue: this.param - }, - buffer: { - __typeName: 'qBuffer', - __typeValue: this.buffer - } - }; - } -} - -class AddToBufferQueuesRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.params = stream.readNEXList(DataStoreSMMTypes.BufferQueueParam); - this.buffers = stream.readNEXList(stream.readNEXQBuffer); - } - - toJSON() { - return { - params: { - __typeName: 'List', - __typeValue: this.params - }, - buffers: { - __typeName: 'List', - __typeValue: this.buffers - } - }; - } -} - -class GetBufferQueueRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreSMMTypes.BufferQueueParam); - } - - toJSON() { - return { - param: { - __typeName: 'BufferQueueParam', - __typeValue: this.param - } - }; - } -} - -class GetBufferQueuesRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.params = stream.readNEXList(DataStoreSMMTypes.BufferQueueParam); - } - - toJSON() { - return { - params: { - __typeName: 'List', - __typeValue: this.params - } - }; - } -} - -class ClearBufferQueuesRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.params = stream.readNEXList(DataStoreSMMTypes.BufferQueueParam); - } - - toJSON() { - return { - params: { - __typeName: 'List', - __typeValue: this.params - } - }; - } -} - -class CompleteAttachFileRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreCompletePostParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreCompletePostParam', - __typeValue: this.param - } - }; - } -} - -class CompleteAttachFileV1Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreCompletePostParamV1); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreCompletePostParamV1', - __typeValue: this.param - } - }; - } -} - -class PrepareAttachFileRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreSMMTypes.DataStoreAttachFileParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreAttachFileParam', - __typeValue: this.param - } - }; - } -} - -class ConditionalSearchObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.condition = stream.readUInt32LE(); - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreSearchParam); - this.extraData = stream.readNEXList(stream.readNEXString); - } - - toJSON() { - return { - condition: { - __typeName: 'uint32', - __typeValue: this.condition - }, - param: { - __typeName: 'DataStoreSearchParam', - __typeValue: this.param - }, - extraData: { - __typeName: 'List', - __typeValue: this.extraData - } - }; - } -} - -class GetApplicationConfigRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.applicationId = stream.readUInt32LE(); - } - - toJSON() { - return { - applicationId: { - __typeName: 'uint32', - __typeValue: this.applicationId - } - }; - } -} - -class SetApplicationConfigRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.applicationId = stream.readUInt32LE(); - this.key = stream.readUInt32LE(); - this.value = stream.readInt32LE(); - } - - toJSON() { - return { - applicationId: { - __typeName: 'uint32', - __typeValue: this.applicationId - }, - key: { - __typeName: 'uint32', - __typeValue: this.key - }, - value: { - __typeName: 'sint32', - __typeValue: this.value - } - }; - } -} - -class DeleteApplicationConfigRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.applicationId = stream.readUInt32LE(); - this.key = stream.readUInt32LE(); - } - - toJSON() { - return { - applicationId: { - __typeName: 'uint32', - __typeValue: this.applicationId - }, - key: { - __typeName: 'uint32', - __typeValue: this.key - } - }; - } -} - -class LatestCourseSearchObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreSearchParam); - this.extraData = stream.readNEXList(stream.readNEXString); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreSearchParam', - __typeValue: this.param - }, - extraData: { - __typeName: 'List', - __typeValue: this.extraData - } - }; - } -} - -class FollowingsLatestCourseSearchObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreSearchParam); - this.extraData = stream.readNEXList(stream.readNEXString); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreSearchParam', - __typeValue: this.param - }, - extraData: { - __typeName: 'List', - __typeValue: this.extraData - } - }; - } -} - -class RecommendedCourseSearchObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreSearchParam); - this.extraData = stream.readNEXList(stream.readNEXString); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreSearchParam', - __typeValue: this.param - }, - extraData: { - __typeName: 'List', - __typeValue: this.extraData - } - }; - } -} - -class ScoreRangeCascadedSearchObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreSearchParam); - this.extraData = stream.readNEXList(stream.readNEXString); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreSearchParam', - __typeValue: this.param - }, - extraData: { - __typeName: 'List', - __typeValue: this.extraData - } - }; - } -} - -class SuggestedCourseSearchObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreSearchParam); - this.extraData = stream.readNEXList(stream.readNEXString); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreSearchParam', - __typeValue: this.param - }, - extraData: { - __typeName: 'List', - __typeValue: this.extraData - } - }; - } -} - -class PreparePostObjectWithOwnerIdAndDataIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.ownerId = stream.readUInt32LE(); - this.dataId = stream.readUInt64LE(); - this.param = stream.readNEXStructure(DataStoreTypes.DataStorePreparePostParam); - } - - toJSON() { - return { - ownerId: { - __typeName: 'uint32', - __typeValue: this.ownerId - }, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - param: { - __typeName: 'DataStorePreparePostParam', - __typeValue: this.param - } - }; - } -} - -class CompletePostObjectWithOwnerIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.ownerId = stream.readUInt32LE(); - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreCompletePostParam); - } - - toJSON() { - return { - ownerId: { - __typeName: 'uint32', - __typeValue: this.ownerId - }, - param: { - __typeName: 'DataStoreCompletePostParam', - __typeValue: this.param - } - }; - } -} - -class UploadCourseRecordRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreSMMTypes.DataStoreUploadCourseRecordParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreUploadCourseRecordParam', - __typeValue: this.param - } - }; - } -} - -class GetCourseRecordRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreSMMTypes.DataStoreGetCourseRecordParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreGetCourseRecordParam', - __typeValue: this.param - } - }; - } -} - -class DeleteCourseRecordRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreSMMTypes.DataStoreGetCourseRecordParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreGetCourseRecordParam', - __typeValue: this.param - } - }; - } -} - -class GetApplicationConfigStringRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.applicationId = stream.readUInt32LE(); - } - - toJSON() { - return { - applicationId: { - __typeName: 'uint32', - __typeValue: this.applicationId - } - }; - } -} - -class SetApplicationConfigStringRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.applicationId = stream.readUInt32LE(); - this.key = stream.readUInt32LE(); - this.value = stream.readNEXString(); - } - - toJSON() { - return { - applicationId: { - __typeName: 'uint32', - __typeValue: this.applicationId - }, - key: { - __typeName: 'uint32', - __typeValue: this.key - }, - value: { - __typeName: 'String', - __typeValue: this.value - } - }; - } -} - -class GetDeletionReasonRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIdLst = stream.readNEXList(stream.readUInt64LE); - } - - toJSON() { - return { - dataIdLst: { - __typeName: 'List', - __typeValue: this.dataIdLst - } - }; - } -} - -class SetDeletionReasonRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataIdLst = stream.readNEXList(stream.readUInt64LE); - this.deletionReason = stream.readUInt32LE(); - } - - toJSON() { - return { - dataIdLst: { - __typeName: 'List', - __typeValue: this.dataIdLst - }, - deletionReason: { - __typeName: 'uint32', - __typeValue: this.deletionReason - } - }; - } -} - -class GetMetasWithCourseRecordRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.params = stream.readNEXList(DataStoreSMMTypes.DataStoreGetCourseRecordParam); - this.metaParam = stream.readNEXStructure(DataStoreTypes.DataStoreGetMetaParam); - } - - toJSON() { - return { - params: { - __typeName: 'List', - __typeValue: this.params - }, - metaParam: { - __typeName: 'DataStoreGetMetaParam', - __typeValue: this.metaParam - } - }; - } -} - -class CheckRateCustomRankingCounterRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.applicationId = stream.readUInt32LE(); - } - - toJSON() { - return { - applicationId: { - __typeName: 'uint32', - __typeValue: this.applicationId - } - }; - } -} - -class ResetRateCustomRankingCounterRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.applicationId = stream.readUInt32LE(); - } - - toJSON() { - return { - applicationId: { - __typeName: 'uint32', - __typeValue: this.applicationId - } - }; - } -} - -class BestScoreRateCourseSearchObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreSearchParam); - this.extraData = stream.readNEXList(stream.readNEXString); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreSearchParam', - __typeValue: this.param - }, - extraData: { - __typeName: 'List', - __typeValue: this.extraData - } - }; - } -} - -class CTRPickUpCourseSearchObjectRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreTypes.DataStoreSearchParam); - this.extraData = stream.readNEXList(stream.readNEXString); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreSearchParam', - __typeValue: this.param - }, - extraData: { - __typeName: 'List', - __typeValue: this.extraData - } - }; - } -} - -class SetCachedRankingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.rankingType = stream.readNEXString(); - this.rankingArgs = stream.readNEXList(stream.readNEXString); - this.dataIdLst = stream.readNEXList(stream.readUInt64LE); - } - - toJSON() { - return { - rankingType: { - __typeName: 'String', - __typeValue: this.rankingType - }, - rankingArgs: { - __typeName: 'List', - __typeValue: this.rankingArgs - }, - dataIdLst: { - __typeName: 'List', - __typeValue: this.dataIdLst - } - }; - } -} - -class DeleteCachedRankingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.rankingType = stream.readNEXString(); - this.rankingArgs = stream.readNEXList(stream.readNEXString); - } - - toJSON() { - return { - rankingType: { - __typeName: 'String', - __typeValue: this.rankingType - }, - rankingArgs: { - __typeName: 'List', - __typeValue: this.rankingArgs - } - }; - } -} - -class ChangePlayablePlatformRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.params = stream.readNEXList(DataStoreSMMTypes.DataStoreChangePlayablePlatformParam); - } - - toJSON() { - return { - params: { - __typeName: 'List', - __typeValue: this.params - } - }; - } -} - -class SearchUnknownPlatformObjectsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class ReportCourseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(DataStoreSMMTypes.DataStoreReportCourseParam); - } - - toJSON() { - return { - param: { - __typeName: 'DataStoreReportCourseParam', - __typeValue: this.param - } - }; - } -} - -module.exports = { - GetObjectInfosRequest, - GetMetaByOwnerIdRequest, - CustomSearchObjectRequest, - RateCustomRankingRequest, - GetCustomRankingRequest, - GetCustomRankingByDataIdRequest, - DeleteCustomRankingRequest, - AddToBufferQueueRequest, - AddToBufferQueuesRequest, - GetBufferQueueRequest, - GetBufferQueuesRequest, - ClearBufferQueuesRequest, - CompleteAttachFileRequest, - CompleteAttachFileV1Request, - PrepareAttachFileRequest, - ConditionalSearchObjectRequest, - GetApplicationConfigRequest, - SetApplicationConfigRequest, - DeleteApplicationConfigRequest, - LatestCourseSearchObjectRequest, - FollowingsLatestCourseSearchObjectRequest, - RecommendedCourseSearchObjectRequest, - ScoreRangeCascadedSearchObjectRequest, - SuggestedCourseSearchObjectRequest, - PreparePostObjectWithOwnerIdAndDataIdRequest, - CompletePostObjectWithOwnerIdRequest, - UploadCourseRecordRequest, - GetCourseRecordRequest, - DeleteCourseRecordRequest, - GetApplicationConfigStringRequest, - SetApplicationConfigStringRequest, - GetDeletionReasonRequest, - SetDeletionReasonRequest, - GetMetasWithCourseRecordRequest, - CheckRateCustomRankingCounterRequest, - ResetRateCustomRankingCounterRequest, - BestScoreRateCourseSearchObjectRequest, - CTRPickUpCourseSearchObjectRequest, - SetCachedRankingRequest, - DeleteCachedRankingRequest, - ChangePlayablePlatformRequest, - SearchUnknownPlatformObjectsRequest, - ReportCourseRequest -}; \ No newline at end of file diff --git a/src/protocols/requests/friends_3ds.js b/src/protocols/requests/friends_3ds.js deleted file mode 100644 index 8e55029..0000000 --- a/src/protocols/requests/friends_3ds.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const Friends3DSTypes = require('../types/friends_3ds'); - -class SyncFriendRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.localFriendCode = stream.readUInt64LE(); - this.pidList = stream.readNEXList(stream.readPID); - this.localFriendCodeList = stream.readNEXList(stream.readUInt64LE); - } - - toJSON() { - return { - localFriendCode: { - __typeName: 'uint64', - __typeValue: this.localFriendCode - }, - pidList: { - __typeName: 'List', - __typeValue: this.pidList - }, - localFriendCodeList: { - __typeName: 'List', - __typeValue: this.localFriendCodeList - } - }; - } -} - -class UpdatePresenceRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.presence = stream.readNEXStructure(Friends3DSTypes.NintendoPresence); - this.showGame = stream.readBoolean(); - } - - toJSON() { - return { - presence: { - __typeName: 'NintendoPresence', - __typeValue: this.presence - }, - showGame: { - __typeName: 'boolean', - __typeValue: this.showGame - } - }; - } -} - -class GetFriendPresenceRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pidList = stream.readNEXList(stream.readPID); - } - - toJSON() { - return { - pidList: { - __typeName: 'List', - __typeValue: this.pidList - } - }; - } -} - -class GetFriendPersistentInfoRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pidList = stream.readNEXList(stream.readPID); - } - - toJSON() { - return { - pidList: { - __typeName: 'List', - __typeValue: this.pidList - } - }; - } -} - -module.exports = { - SyncFriendRequest, - UpdatePresenceRequest, - GetFriendPresenceRequest, - GetFriendPersistentInfoRequest -}; diff --git a/src/protocols/requests/friends_wiiu.js b/src/protocols/requests/friends_wiiu.js deleted file mode 100644 index 8268fa5..0000000 --- a/src/protocols/requests/friends_wiiu.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const FriendsWiiUTypes = require('../types/friends_wiiu'); - -class UpdateAndGetAllInformationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.NNAInfo = stream.readNEXStructure(FriendsWiiUTypes.NNAInfo); - this.presence = stream.readNEXStructure(FriendsWiiUTypes.NintendoPresenceV2); - this.birthday = stream.readNEXDateTime(); - } - - toJSON() { - return { - NNAInfo: { - __typeName: 'NNAInfo', - __typeValue: this.NNAInfo - }, - presence: { - __typeName: 'NintendoPresenceV2', - __typeValue: this.presence - }, - birthday: { - __typeName: 'DateTime', - __typeValue: this.birthday - } - }; - } -} - -class UpdatePresenceRequest { - constructor(stream) { - this.presence = stream.readNEXStructure(FriendsWiiUTypes.NintendoPresenceV2); - } - - toJSON() { - return { - presence: { - __typeName: 'NintendoPresenceV2', - __typeValue: this.presence - } - }; - } -} - -module.exports = { - UpdateAndGetAllInformationRequest, - UpdatePresenceRequest -}; diff --git a/src/protocols/requests/match_making.js b/src/protocols/requests/match_making.js deleted file mode 100644 index 1a18d38..0000000 --- a/src/protocols/requests/match_making.js +++ /dev/null @@ -1,984 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); -const MatchMakingTypes = require('../types/match_making'); - -class RegisterGatheringRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.anyGathering = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - anyGathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.anyGathering - } - }; - } -} - -class UnregisterGatheringRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - } - }; - } -} - -class UnregisterGatheringsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGatherings = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - lstGatherings: { - __typeName: 'List', - __typeValue: this.lstGatherings - } - }; - } -} - -class UpdateGatheringRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.anyGathering = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - anyGathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.anyGathering - } - }; - } -} - -class InviteRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.lstPrincipals = stream.readNEXList(stream.readPID); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - lstPrincipals: { - __typeName: 'List', - __typeValue: this.lstPrincipals - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - } -} - -class AcceptInvitationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - } -} - -class DeclineInvitationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - } -} - -class CancelInvitationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.lstPrincipals = stream.readNEXList(stream.readPID); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - lstPrincipals: { - __typeName: 'List', - __typeValue: this.lstPrincipals - }, - strMessage: { - __typeName: 'List', - __typeValue: this.strMessage - } - }; - } -} - -class GetInvitationsSentRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - } - }; - } -} - -class GetInvitationsReceivedRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class ParticipateRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - } -} - -class CancelParticipationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - } -} - -class GetParticipantsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - } - }; - } -} - -class AddParticipantsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.lstPrincipals = stream.readNEXList(stream.readPID); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - lstPrincipals: { - __typeName: 'List', - __typeValue: this.lstPrincipals - }, - strMessage: { - __typeName: 'List', - __typeValue: this.strMessage - } - }; - } -} - -class GetDetailedParticipantsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - } - }; - } -} - -class GetParticipantsURLsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - } - }; - } -} - -class FindByTypeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.strType = stream.readNEXString(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - strType: { - __typeName: 'String', - __typeValue: this.strType - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class FindByDescriptionRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.strDescription = stream.readNEXString(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - strDescription: { - __typeName: 'String', - __typeValue: this.strDescription - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class FindByDescriptionRegexRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.strDescriptionRegex = stream.readNEXString(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - strDescriptionRegex: { - __typeName: 'String', - __typeValue: this.strDescriptionRegex - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class FindByIDRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstID = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - lstID: { - __typeName: 'List', - __typeValue: this.lstID - } - }; - } -} - -class FindBySingleIDRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.id = stream.readUInt32LE(); - } - - toJSON() { - return { - id: { - __typeName: 'uint32', - __typeValue: this.id - } - }; - } -} - -class FindByOwnerRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.id = stream.readPID(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - id: { - __typeName: 'PID', - __typeValue: this.id - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class FindByParticipantsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pid = stream.readNEXList(stream.readPID); - } - - toJSON() { - return { - pid: { - __typeName: 'List', - __typeValue: this.pid - } - }; - } -} - -class FindInvitationsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class FindBySQLQueryRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.strQuery = stream.readNEXString(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - strQuery: { - __typeName: 'String', - __typeValue: this.strQuery - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class LaunchSessionRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.strURL = stream.readNEXString(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - strURL: { - __typeName: 'String', - __typeValue: this.strURL - } - }; - } -} - -class UpdateSessionURLRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.strURL = stream.readNEXString(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - strURL: { - __typeName: 'String', - __typeValue: this.strURL - } - }; - } -} - -class GetSessionURLRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - } - }; - } -} - -class GetStateRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - } - }; - } -} - -class SetStateRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.uiNewState = stream.readUInt32LE(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - uiNewState: { - __typeName: 'uint32', - __typeValue: this.uiNewState - } - }; - } -} - -class ReportStatsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.lstStats = stream.readNEXList(MatchMakingTypes.GatheringStats); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - lstStats: { - __typeName: 'List', - __typeValue: this.lstStats - } - }; - } -} - -class GetStatsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.lstParticipants = stream.readNEXList(stream.readPID); - this.lstColumns = stream.readNEXList(stream.readUInt8); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - lstParticipants: { - __typeName: 'List', - __typeValue: this.lstParticipants - }, - lstColumns: { - __typeName: 'List', - __typeValue: this.lstColumns - } - }; - } -} - -class DeleteGatheringRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - } - }; - } -} - -class GetPendingDeletionsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uiReason = stream.readUInt32LE(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - uiReason: { - __typeName: 'uint32', - __typeValue: this.uiReason - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class DeleteFromDeletionsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstDeletions = stream.readNEXStructure(stream.readUInt32LE); - } - - toJSON() { - return { - lstDeletions: { - __typeName: 'List', - __typeValue: this.lstDeletions - } - }; - } -} - -class MigrateGatheringOwnershipV1Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.lstPotentialNewOwnersID = stream.readNEXList(stream.readPID); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - lstPotentialNewOwnersID: { - __typeName: 'List', - __typeValue: this.lstPotentialNewOwnersID - } - }; - } -} - -class FindByDescriptionLikeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.strDescriptionLike = stream.readNEXString(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - strDescriptionLike: { - __typeName: 'String', - __typeValue: this.strDescriptionLike - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class RegisterLocalURLRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.url = stream.readNEXStationURL(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - url: { - __typeName: 'StationURL', - __typeValue: this.url - } - }; - } -} - -class RegisterLocalURLsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.lstUrls = stream.readNEXList(stream.readNEXStationURL); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - lstUrls: { - __typeName: 'List', - __typeValue: this.lstUrls - } - }; - } -} - -class UpdateSessionHostV1Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - } - }; - } -} - -class GetSessionURLsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - } - }; - } -} - -class UpdateSessionHostRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.isMigrateOwner = stream.readBoolean(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - isMigrateOwner: { - __typeName: 'boolean', - __typeValue: this.isMigrateOwner - } - }; - } -} - -class UpdateGatheringOwnershipRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.participantsOnly = stream.readBoolean(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - participantsOnly: { - __typeName: 'boolean', - __typeValue: this.participantsOnly - } - }; - } -} - -class MigrateGatheringOwnershipRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.lstPotentialNewOwnersID = stream.readNEXList(stream.readPID); - this.participantsOnly = stream.readBoolean(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - lstPotentialNewOwnersID: { - __typeName: 'List', - __typeValue: this.lstPotentialNewOwnersID - }, - participantsOnly: { - __typeName: 'boolean', - __typeValue: this.participantsOnly - } - }; - } -} - - -module.exports = { - RegisterGatheringRequest, - UnregisterGatheringRequest, - UnregisterGatheringsRequest, - UpdateGatheringRequest, - InviteRequest, - AcceptInvitationRequest, - DeclineInvitationRequest, - CancelInvitationRequest, - GetInvitationsSentRequest, - GetInvitationsReceivedRequest, - ParticipateRequest, - CancelParticipationRequest, - GetParticipantsRequest, - AddParticipantsRequest, - GetDetailedParticipantsRequest, - GetParticipantsURLsRequest, - FindByTypeRequest, - FindByDescriptionRequest, - FindByDescriptionRegexRequest, - FindByIDRequest, - FindBySingleIDRequest, - FindByOwnerRequest, - FindByParticipantsRequest, - FindInvitationsRequest, - FindBySQLQueryRequest, - LaunchSessionRequest, - UpdateSessionURLRequest, - GetSessionURLRequest, - GetStateRequest, - SetStateRequest, - ReportStatsRequest, - GetStatsRequest, - DeleteGatheringRequest, - GetPendingDeletionsRequest, - DeleteFromDeletionsRequest, - MigrateGatheringOwnershipV1Request, - FindByDescriptionLikeRequest, - RegisterLocalURLRequest, - RegisterLocalURLsRequest, - UpdateSessionHostV1Request, - GetSessionURLsRequest, - UpdateSessionHostRequest, - UpdateGatheringOwnershipRequest, - MigrateGatheringOwnershipRequest -}; diff --git a/src/protocols/requests/match_making_ext.js b/src/protocols/requests/match_making_ext.js deleted file mode 100644 index 917942a..0000000 --- a/src/protocols/requests/match_making_ext.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class EndParticipationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - } -} - -class GetParticipantsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.bOnlyActive = stream.readBoolean(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - bOnlyActive: { - __typeName: 'boolean', - __typeValue: this.bOnlyActive - } - }; - } -} - -class GetDetailedParticipantsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.idGathering = stream.readUInt32LE(); - this.bOnlyActive = stream.readBoolean(); - } - - toJSON() { - return { - idGathering: { - __typeName: 'uint32', - __typeValue: this.idGathering - }, - bOnlyActive: { - __typeName: 'boolean', - __typeValue: this.bOnlyActive - } - }; - } -} - -class GetParticipantsURLsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGatherings = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - lstGatherings: { - __typeName: 'List', - __typeValue: this.lstGatherings - } - }; - } -} - -class GetGatheringRelationsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.id = stream.readUInt32LE(); - this.descr = stream.readNEXString(); - } - - toJSON() { - return { - id: { - __typeName: 'uint32', - __typeValue: this.id - }, - descr: { - __typeName: 'String', - __typeValue: this.descr - } - }; - } -} - -class DeleteFromDeletionsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstDeletions = stream.readNEXList(stream.readUInt32LE); - this.pid = stream.readPID(); - } - - toJSON() { - return { - lstDeletions: { - __typeName: 'List', - __typeValue: this.lstDeletions - }, - pid: { - __typeName: 'PID', - __typeValue: this.pid - } - }; - } -} - -module.exports = { - EndParticipationRequest, - GetParticipantsRequest, - GetDetailedParticipantsRequest, - GetParticipantsURLsRequest, - GetGatheringRelationsRequest, - DeleteFromDeletionsRequest -}; \ No newline at end of file diff --git a/src/protocols/requests/matchmake_extension.js b/src/protocols/requests/matchmake_extension.js deleted file mode 100644 index 3a7f501..0000000 --- a/src/protocols/requests/matchmake_extension.js +++ /dev/null @@ -1,1185 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const semver = require('semver'); -const NEXTypes = require('../../types'); -const MatchMakingTypes = require('../types/match_making'); - -class CloseParticipationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - } - }; - } -} - -class OpenParticipationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - } - }; - } -} - -class AutoMatchmake_PostponeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.anyGathering = stream.readNEXAnyDataHolder(); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - anyGathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.anyGathering - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - } -} - -class BrowseMatchmakeSessionRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.searchCriteria = stream.readNEXStructure(MatchMakingTypes.MatchmakeSessionSearchCriteria); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - searchCriteria: { - __typeName: 'MatchmakeSessionSearchCriteria', - __typeValue: this.searchCriteria - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class BrowseMatchmakeSessionWithHostUrlsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.searchCriteria = stream.readNEXStructure(MatchMakingTypes.MatchmakeSessionSearchCriteria); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - searchCriteria: { - __typeName: 'MatchmakeSessionSearchCriteria', - __typeValue: this.searchCriteria - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class CreateMatchmakeSessionRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - const nexVersion = stream.connection.title.nex_match_making_version || stream.connection.title.nex_version; - - this.anyGathering = stream.readNEXAnyDataHolder(); - this.strMessage = stream.readNEXString(); - - if (semver.gte(nexVersion, '3.4.0')) { - this.participationCount = stream.readUInt16LE(); - } - } - - toJSON() { - const data = { - anyGathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.anyGathering - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - - if (this.participationCount !== undefined) { - data.participationCount = { - __typeName: 'uint16', - __typeValue: this.participationCount - }; - } - - return data; - } -} - -class JoinMatchmakeSessionRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - } -} - -class ModifyCurrentGameAttributeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.attribIndex = stream.readUInt32LE(); - this.newValue = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - attribIndex: { - __typeName: 'uint32', - __typeValue: this.attribIndex - }, - newValue: { - __typeName: 'uint32', - __typeValue: this.newValue - } - }; - } -} - -class UpdateNotificationDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // * This has a different format on the Switch - // * On the Switch uiParam1 and uiParam2 are uint64 - this.uiType = stream.readUInt32LE(); - this.uiParam1 = stream.readUInt32LE(); - this.uiParam2 = stream.readUInt32LE(); - this.strParam = stream.readNEXString(); - } - - toJSON() { - return { - uiType: { - __typeName: 'uint32', - __typeValue: this.uiType - }, - uiParam1: { - __typeName: 'uint32', - __typeValue: this.uiParam1 - }, - uiParam2: { - __typeName: 'uint32', - __typeValue: this.uiParam2 - }, - strParam: { - __typeName: 'String', - __typeValue: this.strParam - } - }; - } -} - -class GetFriendNotificationDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uiType = stream.readInt32LE(); - } - - toJSON() { - return { - uiType: { - __typeName: 'sint32', - __typeValue: this.uiType - } - }; - } -} - -class UpdateApplicationBufferRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.applicationBuffer = stream.readNEXBuffer(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - applicationBuffer: { - __typeName: 'Buffer', - __typeValue: this.applicationBuffer - } - }; - } -} - -class UpdateMatchmakeSessionAttributeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.attribs = stream.readNEXList(stream.readInt32LE); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - attribs: { - __typeName: 'List', - __typeValue: this.attribs - } - }; - } -} - -class GetlstFriendNotificationDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstTypes = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - lstTypes: { - __typeName: 'List', - __typeValue: this.lstTypes - } - }; - } -} - -class UpdateMatchmakeSessionRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.anyGathering = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - anyGathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.anyGathering - } - }; - } -} - -class AutoMatchmakeWithSearchCriteria_PostponeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstSearchCriteria = stream.readNEXList(MatchMakingTypes.MatchmakeSessionSearchCriteria); - this.anyGathering = stream.readNEXAnyDataHolder(); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - lstSearchCriteria: { - __typeName: 'List', - __typeValue: this.lstSearchCriteria - }, - anyGathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.anyGathering - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - } -} - -class GetPlayingSessionRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstPid = stream.readNEXList(stream.readPID); - } - - toJSON() { - return { - lstPid: { - __typeName: 'List', - __typeValue: this.lstPid - } - }; - } -} - -class CreateCommunityRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.community = stream.readNEXStructure(MatchMakingTypes.PersistentGathering); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - community: { - __typeName: 'PersistentGathering', - __typeValue: this.community - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - } -} - -class UpdateCommunityRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.community = stream.readNEXStructure(MatchMakingTypes.PersistentGathering); - } - - toJSON() { - return { - community: { - __typeName: 'PersistentGathering', - __typeValue: this.community - } - }; - } -} - -class JoinCommunityRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.strMessage = stream.readNEXString(); - this.strPassword = stream.readNEXString(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - }, - strPassword: { - __typeName: 'String', - __typeValue: this.strPassword - } - }; - } -} - -class FindCommunityByGatheringIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGid = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - lstGid: { - __typeName: 'List', - __typeValue: this.lstGid - } - }; - } -} - -class FindOfficialCommunityRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.isAvailableOnly = stream.readBoolean(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - isAvailableOnly: { - __typeName: 'boolean', - __typeValue: this.isAvailableOnly - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class FindCommunityByParticipantRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pid = stream.readPID(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - pid: { - __typeName: 'PID', - __typeValue: this.pid - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class UpdatePrivacySettingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.onlineStatus = stream.readBoolean(); - this.participationCommunity = stream.readBoolean(); - } - - toJSON() { - return { - onlineStatus: { - __typeName: 'boolean', - __typeValue: this.onlineStatus - }, - participationCommunity: { - __typeName: 'boolean', - __typeValue: this.participationCommunity - } - }; - } -} - -class GetMyBlockListRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class AddToBlockListRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstPrincipalId = stream.readNEXList(stream.readPID); - } - - toJSON() { - return { - lstPrincipalId: { - __typeName: 'List', - __typeValue: this.lstPrincipalId - } - }; - } -} - -class RemoveFromBlockListRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstPrincipalId = stream.readNEXList(stream.readPID); - } - - toJSON() { - return { - lstPrincipalId: { - __typeName: 'List', - __typeValue: this.lstPrincipalId - } - }; - } -} - -class ClearMyBlockListRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class ReportViolationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pid = stream.readPID(); - this.userName = stream.readNEXString(); - this.violationCode = stream.readUInt32LE(); - } - - toJSON() { - return { - pid: { - __typeName: 'PID', - __typeValue: this.pid - }, - userName: { - __typeName: 'String', - __typeValue: this.userName - }, - violationCode: { - __typeName: 'uint32', - __typeValue: this.violationCode - } - }; - } -} - -class IsViolationUserRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class JoinMatchmakeSessionExRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - const nexVersion = stream.connection.title.nex_match_making_version || stream.connection.title.nex_version; - - this.gid = stream.readUInt32LE(); - this.strMessage = stream.readNEXString(); - this.dontCareMyBlockList = stream.readBoolean(); - - if (semver.gte(nexVersion, '3.4.0')) { - this.participationCount = stream.readUInt16LE(); - } - } - - toJSON() { - const data = { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - }, - dontCareMyBlockList: { - __typeName: 'boolean', - __typeValue: this.dontCareMyBlockList - } - }; - - if (this.participationCount !== undefined) { - data.participationCount = { - __typeName: 'uint16', - __typeValue: this.participationCount - }; - } - - return data; - } -} - -class GetSimplePlayingSessionRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstPrincipalId = stream.readNEXList(stream.readPID); - this.includeLoginUser = stream.readBoolean(); - } - - toJSON() { - return { - lstPrincipalId: { - __typeName: 'List', - __typeValue: this.lstPrincipalId - }, - includeLoginUser: { - __typeName: 'boolean', - __typeValue: this.includeLoginUser - } - }; - } -} - -class GetSimpleCommunityRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gatheringIdList = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - gatheringIdList: { - __typeName: 'List', - __typeValue: this.gatheringIdList - } - }; - } -} - -class AutoMatchmakeWithGatheringId_PostponeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGid = stream.readNEXList(stream.readUInt32LE); - this.anyGathering = stream.readNEXAnyDataHolder(); - this.strMessage = stream.readNEXString(); - } - - toJSON() { - return { - lstGid: { - __typeName: 'List', - __typeValue: this.lstGid - }, - anyGathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.anyGathering - }, - strMessage: { - __typeName: 'String', - __typeValue: this.strMessage - } - }; - } -} - -class UpdateProgressScoreRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.progressScore = stream.readUInt8(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - progressScore: { - __typeName: 'uint8', - __typeValue: this.progressScore - } - }; - } -} - -class DebugNotifyEventRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pid = stream.readPID(); - this.mainType = stream.readUInt32LE(); - this.subType = stream.readUInt32LE(); - this.param1 = stream.readUInt64LE(); - this.param2 = stream.readUInt64LE(); - this.stringParam = stream.readNEXString(); - } - - toJSON() { - return { - pid: { - __typeName: 'PID', - __typeValue: this.pid - }, - mainType: { - __typeName: 'uint32', - __typeValue: this.mainType - }, - subType: { - __typeName: 'uint32', - __typeValue: this.subType - }, - param1: { - __typeName: 'uint64', - __typeValue: this.param1 - }, - param2: { - __typeName: 'uint64', - __typeValue: this.param2 - }, - stringParam: { - __typeName: 'String', - __typeValue: this.stringParam - } - }; - } -} - -class GenerateMatchmakeSessionSystemPasswordRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - } - }; - } -} - -class ClearMatchmakeSessionSystemPasswordRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - } - }; - } -} - -class CreateMatchmakeSessionWithParamRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.createMatchmakeSessionParam = stream.readNEXStructure(MatchMakingTypes.CreateMatchmakeSessionParam); - } - - toJSON() { - return { - createMatchmakeSessionParam: { - __typeName: 'CreateMatchmakeSessionParam', - __typeValue: this.createMatchmakeSessionParam - } - }; - } -} - -class JoinMatchmakeSessionWithParamRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.joinMatchmakeSessionParam = stream.readNEXStructure(MatchMakingTypes.JoinMatchmakeSessionParam); - } - - toJSON() { - return { - joinMatchmakeSessionParam: { - __typeName: 'JoinMatchmakeSessionParam', - __typeValue: this.joinMatchmakeSessionParam - } - }; - } -} - -class AutoMatchmakeWithParam_PostponeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.autoMatchmakeParam = stream.readNEXStructure(MatchMakingTypes.AutoMatchmakeParam); - } - - toJSON() { - return { - autoMatchmakeParam: { - __typeName: 'AutoMatchmakeParam', - __typeValue: this.autoMatchmakeParam - } - }; - } -} - -class FindMatchmakeSessionByGatheringIdDetailRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - } - }; - } -} - -class BrowseMatchmakeSessionNoHolderRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.searchCriteria = stream.readNEXStructure(MatchMakingTypes.MatchmakeSessionSearchCriteria); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - searchCriteria: { - __typeName: 'MatchmakeSessionSearchCriteria', - __typeValue: this.searchCriteria - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class BrowseMatchmakeSessionWithHostUrlsNoHolderRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.searchCriteria = stream.readNEXStructure(MatchMakingTypes.MatchmakeSessionSearchCriteria); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - searchCriteria: { - __typeName: 'MatchmakeSessionSearchCriteria', - __typeValue: this.searchCriteria - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class UpdateMatchmakeSessionPartRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.updateMatchmakeSessionParam = stream.readNEXStructure(MatchMakingTypes.UpdateMatchmakeSessionParam); - } - - toJSON() { - return { - updateMatchmakeSessionParam: { - __typeName: 'UpdateMatchmakeSessionParam', - __typeValue: this.updateMatchmakeSessionParam - } - }; - } -} - -class RequestMatchmakingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.autoMatchmakeParam = stream.readNEXStructure(MatchMakingTypes.AutoMatchmakeParam); - } - - toJSON() { - return { - autoMatchmakeParam: { - __typeName: 'AutoMatchmakeParam', - __typeValue: this.autoMatchmakeParam - } - }; - } -} - -class WithdrawMatchmakingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt64LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint64', - __typeValue: this.requestId - } - }; - } -} - -class WithdrawMatchmakingAllRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class FindMatchmakeSessionByGatheringIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGid = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - lstGid: { - __typeName: 'List', - __typeValue: this.lstGid - } - }; - } -} - -class FindMatchmakeSessionBySingleGatheringIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - } - }; - } -} - -class FindMatchmakeSessionByOwnerRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.id = stream.readPID(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - id: { - __typeName: 'PID', - __typeValue: this.id - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class FindMatchmakeSessionByParticipantRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(MatchMakingTypes.FindMatchmakeSessionByParticipantParam); - } - - toJSON() { - return { - param: { - __typeName: 'FindMatchmakeSessionByParticipantParam', - __typeValue: this.param - } - }; - } -} - -class BrowseMatchmakeSessionNoHolderNoResultRangeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.searchCriteria = stream.readNEXStructure(MatchMakingTypes.MatchmakeSessionSearchCriteria); - } - - toJSON() { - return { - searchCriteria: { - __typeName: 'MatchmakeSessionSearchCriteria', - __typeValue: this.searchCriteria - } - }; - } -} - -class BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRangeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.searchCriteria = stream.readNEXStructure(MatchMakingTypes.MatchmakeSessionSearchCriteria); - } - - toJSON() { - return { - searchCriteria: { - __typeName: 'MatchmakeSessionSearchCriteria', - __typeValue: this.searchCriteria - } - }; - } -} - -module.exports = { - CloseParticipationRequest, - OpenParticipationRequest, - AutoMatchmake_PostponeRequest, - BrowseMatchmakeSessionRequest, - BrowseMatchmakeSessionWithHostUrlsRequest, - CreateMatchmakeSessionRequest, - JoinMatchmakeSessionRequest, - ModifyCurrentGameAttributeRequest, - UpdateNotificationDataRequest, - GetFriendNotificationDataRequest, - UpdateApplicationBufferRequest, - UpdateMatchmakeSessionAttributeRequest, - GetlstFriendNotificationDataRequest, - UpdateMatchmakeSessionRequest, - AutoMatchmakeWithSearchCriteria_PostponeRequest, - GetPlayingSessionRequest, - CreateCommunityRequest, - UpdateCommunityRequest, - JoinCommunityRequest, - FindCommunityByGatheringIdRequest, - FindOfficialCommunityRequest, - FindCommunityByParticipantRequest, - UpdatePrivacySettingRequest, - GetMyBlockListRequest, - AddToBlockListRequest, - RemoveFromBlockListRequest, - ClearMyBlockListRequest, - ReportViolationRequest, - IsViolationUserRequest, - JoinMatchmakeSessionExRequest, - GetSimplePlayingSessionRequest, - GetSimpleCommunityRequest, - AutoMatchmakeWithGatheringId_PostponeRequest, - UpdateProgressScoreRequest, - DebugNotifyEventRequest, - GenerateMatchmakeSessionSystemPasswordRequest, - ClearMatchmakeSessionSystemPasswordRequest, - CreateMatchmakeSessionWithParamRequest, - JoinMatchmakeSessionWithParamRequest, - AutoMatchmakeWithParam_PostponeRequest, - FindMatchmakeSessionByGatheringIdDetailRequest, - BrowseMatchmakeSessionNoHolderRequest, - BrowseMatchmakeSessionWithHostUrlsNoHolderRequest, - UpdateMatchmakeSessionPartRequest, - RequestMatchmakingRequest, - WithdrawMatchmakingRequest, - WithdrawMatchmakingAllRequest, - FindMatchmakeSessionByGatheringIdRequest, - FindMatchmakeSessionBySingleGatheringIdRequest, - FindMatchmakeSessionByOwnerRequest, - FindMatchmakeSessionByParticipantRequest, - BrowseMatchmakeSessionNoHolderNoResultRangeRequest, - BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRangeRequest -}; diff --git a/src/protocols/requests/matchmake_extension_mk8.js b/src/protocols/requests/matchmake_extension_mk8.js deleted file mode 100644 index 8783a4a..0000000 --- a/src/protocols/requests/matchmake_extension_mk8.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class JoinMatchmakeSessionWithExtraParticipantsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - this.joinMessage = stream.readNEXString(); - this.ignoreBlacklist = stream.readBoolean(); - this.participationCount = stream.readUInt16LE(); - this.extraParticipants = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - joinMessage: { - __typeName: 'String', - __typeValue: this.joinMessage - }, - ignoreBlacklist: { - __typeName: 'boolean', - __typeValue: this.ignoreBlacklist - }, - participationCount: { - __typeName: 'uint16', - __typeValue: this.participationCount - }, - extraParticipants: { - __typeName: 'uint32', - __typeValue: this.extraParticipants - } - }; - } -} - -module.exports = { - JoinMatchmakeSessionWithExtraParticipantsRequest -}; diff --git a/src/protocols/requests/message_delivery.js b/src/protocols/requests/message_delivery.js deleted file mode 100644 index 255bdc0..0000000 --- a/src/protocols/requests/message_delivery.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class DeliverMessageRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.oUserMessage = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - oUserMessage: { - __typeName: 'AnyDataHolder', - __typeValue: this.oUserMessage - } - }; - } -} - -module.exports = { - DeliverMessageRequest -}; \ No newline at end of file diff --git a/src/protocols/requests/nat_traversal.js b/src/protocols/requests/nat_traversal.js deleted file mode 100644 index becae17..0000000 --- a/src/protocols/requests/nat_traversal.js +++ /dev/null @@ -1,176 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class RequestProbeInitiationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.urlTargetList = stream.readNEXList(stream.readNEXStationURL); - } - - toJSON() { - return { - urlTargetList: { - __typeName: 'List', - __typeValue: this.urlTargetList - } - }; - } -} - -class InitiateProbeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.urlStationToProbe = stream.readNEXStationURL(); - } - - toJSON() { - return { - urlStationToProbe: { - __typeName: 'StationURL', - __typeValue: this.urlStationToProbe - } - }; - } -} - -class RequestProbeInitiationExtRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.urlTargetList = stream.readNEXList(stream.readNEXStationURL); - this.urlStationToProbe = stream.readNEXStationURL(); - } - - toJSON() { - return { - urlTargetList: { - __typeName: 'List', - __typeValue: this.urlTargetList - }, - urlStationToProbe: { - __typeName: 'StationURL', - __typeValue: this.urlStationToProbe - } - }; - } -} - -class ReportNATTraversalResultRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.cid = stream.readUInt32LE(); - this.result = stream.readBoolean(); - - if (stream.hasDataLeft()) { - this.rtt = stream.readUInt32LE(); // ! THIS IS NOT PRESENT ON 3DS, ONLY WIIU/SWITCH - } - } - - toJSON() { - const data = { - cid: { - __typeName: 'uint32', - __typeValue: this.cid - }, - result: { - __typeName: 'boolean', - __typeValue: this.result - } - }; - - if (this.rtt !== undefined) { - data.rtt = { - __typeName: 'uint32', - __typeValue: this.rtt - }; - } - - return data; - } -} - -class ReportNATPropertiesRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.natmapping = stream.readUInt32LE(); - this.natfiltering = stream.readUInt32LE(); - this.rtt = stream.readUInt32LE(); - } - - toJSON() { - return { - natmapping: { - __typeName: 'uint32', - __typeValue: this.natmapping - }, - natfiltering: { - __typeName: 'uint32', - __typeValue: this.natfiltering - }, - rtt: { - __typeName: 'uint32', - __typeValue: this.rtt - } - }; - } -} - -class GetRelaySignatureKeyRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class ReportNATTraversalResultDetailRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.cid = stream.readUInt32LE(); - this.result = stream.readBoolean(); - this.detail = stream.readInt32LE(); - this.rtt = stream.readUInt32LE(); - } - - toJSON() { - return { - cid: { - __typeName: 'uint32', - __typeValue: this.cid - }, - result: { - __typeName: 'boolean', - __typeValue: this.result - }, - detail: { - __typeName: 'sint32', - __typeValue: this.detail - }, - rtt: { - __typeName: 'uint32', - __typeValue: this.rtt - } - }; - } -} - -module.exports = { - RequestProbeInitiationRequest, - InitiateProbeRequest, - RequestProbeInitiationExtRequest, - ReportNATTraversalResultRequest, - ReportNATPropertiesRequest, - GetRelaySignatureKeyRequest, - ReportNATTraversalResultDetailRequest -}; diff --git a/src/protocols/requests/nintendo_notifications.js b/src/protocols/requests/nintendo_notifications.js deleted file mode 100644 index caad9b2..0000000 --- a/src/protocols/requests/nintendo_notifications.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NintendoNotificationsTypes = require('../types/nintendo_notifications'); - -class ProcessNintendoNotificationEvent1Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.eventObject = stream.readNEXStructure(NintendoNotificationsTypes.NintendoNotificationEvent); - } - - toJSON() { - return { - eventObject: { - __typeName: 'NintendoNotificationEvent', - __typeValue: this.eventObject - } - }; - } -} - -class ProcessNintendoNotificationEvent2Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.eventObject = stream.readNEXStructure(NintendoNotificationsTypes.NintendoNotificationEvent); - } - - toJSON() { - return { - eventObject: { - __typeName: 'NintendoNotificationEvent', - __typeValue: this.eventObject - } - }; - } -} - -module.exports = { - ProcessNintendoNotificationEvent1Request, - ProcessNintendoNotificationEvent2Request -}; \ No newline at end of file diff --git a/src/protocols/requests/notifications.js b/src/protocols/requests/notifications.js deleted file mode 100644 index fd9c8ee..0000000 --- a/src/protocols/requests/notifications.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NotificationsTypes = require('../types/notifications'); - -class ProcessNotificationEventRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.oEvent = stream.readNEXStructure(NotificationsTypes.NotificationEvent); - } - - toJSON() { - return { - oEvent: { - __typeName: 'NotificationEvent', - __typeValue: this.oEvent - } - }; - } -} - -module.exports = { - ProcessNotificationEventRequest -}; \ No newline at end of file diff --git a/src/protocols/requests/ranking.js b/src/protocols/requests/ranking.js deleted file mode 100644 index f6c1560..0000000 --- a/src/protocols/requests/ranking.js +++ /dev/null @@ -1,423 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const RankingTypes = require('../types/ranking'); - -class UploadScoreRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.scoreData = stream.readNEXStructure(RankingTypes.RankingScoreData); - this.uniqueId = stream.readUInt64LE(); - } - - toJSON() { - return { - scoreData: { - __typeName: 'RankingScoreData', - __typeValue: this.scoreData - }, - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - } - }; - } -} - -class DeleteScoreRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.category = stream.readUInt32LE(); - this.uniqueId = stream.readUInt64LE(); - } - - toJSON() { - return { - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - } - }; - } -} - -class DeleteAllScoresRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueId = stream.readUInt64LE(); - } - - toJSON() { - return { - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - } - }; - } -} - -class UploadCommonDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.commonData = stream.readNEXBuffer(); - this.uniqueId = stream.readUInt64LE(); - } - - toJSON() { - return { - commonData: { - __typeName: 'Buffer', - __typeValue: this.commonData - }, - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - } - }; - } -} - -class DeleteCommonDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueId = stream.readUInt64LE(); - } - - toJSON() { - return { - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - } - }; - } -} - -class GetCommonDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueId = stream.readUInt64LE(); - } - - toJSON() { - return { - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - } - }; - } -} - -class ChangeAttributesRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.category = stream.readUInt32LE(); - this.changeParam = stream.readNEXStructure(RankingTypes.RankingChangeAttributesParam); - this.uniqueId = stream.readUInt64LE(); - } - - toJSON() { - return { - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - changeParam: { - __typeName: 'RankingChangeAttributesParam', - __typeValue: this.changeParam - }, - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - } - }; - } -} - -class ChangeAllAttributesRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.changeParam = stream.readNEXStructure(RankingTypes.RankingChangeAttributesParam); - this.uniqueId = stream.readUInt64LE(); - } - - toJSON() { - return { - changeParam: { - __typeName: 'RankingChangeAttributesParam', - __typeValue: this.changeParam - }, - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - } - }; - } -} - -class GetRankingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.rankingMode = stream.readUInt8(); - this.category = stream.readUInt32LE(); - this.orderParam = stream.readNEXStructure(RankingTypes.RankingOrderParam); - this.uniqueId = stream.readUInt64LE(); - this.principalId = stream.readPID(); - } - - toJSON() { - return { - rankingMode: { - __typeName: 'uint8', - __typeValue: this.rankingMode - }, - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - orderParam: { - __typeName: 'RankingOrderParam', - __typeValue: this.orderParam - }, - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - }, - principalId: { - __typeName: 'PID', - __typeValue: this.principalId - } - }; - } -} - -class GetApproxOrderRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.category = stream.readUInt32LE(); - this.orderParam = stream.readNEXStructure(RankingTypes.RankingOrderParam); - this.score = stream.readUInt32LE(); - this.uniqueId = stream.readUInt64LE(); - this.principalId = stream.readPID(); - } - - toJSON() { - return { - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - orderParam: { - __typeName: 'RankingOrderParam', - __typeValue: this.orderParam - }, - score: { - __typeName: 'uint32', - __typeValue: this.score - }, - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - }, - principalId: { - __typeName: 'PID', - __typeValue: this.principalId - } - }; - } -} - -class GetStatsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.category = stream.readUInt32LE(); - this.orderParam = stream.readNEXStructure(RankingTypes.RankingOrderParam); - this.flags = stream.readUInt32LE(); - } - - toJSON() { - return { - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - orderParam: { - __typeName: 'RankingOrderParam', - __typeValue: this.orderParam - }, - flags: { - __typeName: 'uint32', - __typeValue: this.flags - } - }; - } -} - -class GetRankingByPIDListRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.principalIdList = stream.readNEXList(stream.readPID); - this.rankingMode = stream.readUInt8(); - this.category = stream.readUInt32LE(); - this.orderParam = stream.readNEXStructure(RankingTypes.RankingOrderParam); - this.uniqueId = stream.readUInt64LE(); - } - - toJSON() { - return { - principalIdList: { - __typeName: 'List', - __typeValue: this.principalIdList - }, - rankingMode: { - __typeName: 'uint8', - __typeValue: this.rankingMode - }, - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - orderParam: { - __typeName: 'RankingOrderParam', - __typeValue: this.orderParam - }, - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - } - }; - } -} - -class GetRankingByUniqueIdListRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.nexUniqueIdList = stream.readNEXList(stream.readUInt64LE); - this.rankingMode = stream.readUInt8(); - this.category = stream.readUInt32LE(); - this.orderParam = stream.readNEXStructure(RankingTypes.RankingOrderParam); - this.uniqueId = stream.readUInt64LE(); - } - - toJSON() { - return { - nexUniqueIdList: { - __typeName: 'List', - __typeValue: this.nexUniqueIdList - }, - rankingMode: { - __typeName: 'uint8', - __typeValue: this.rankingMode - }, - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - orderParam: { - __typeName: 'RankingOrderParam', - __typeValue: this.orderParam - }, - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - } - }; - } -} - -class GetCachedTopXRankingRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.category = stream.readUInt32LE(); - this.orderParam = stream.readNEXStructure(RankingTypes.RankingOrderParam); - } - - toJSON() { - return { - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - orderParam: { - __typeName: 'RankingOrderParam', - __typeValue: this.orderParam - } - }; - } -} - -class GetCachedTopXRankingsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.categories = stream.readNEXList(stream.readUInt32LE); - this.orderParams = stream.readNEXList(RankingTypes.RankingOrderParam); - } - - toJSON() { - return { - categories: { - __typeName: 'List', - __typeValue: this.categories - }, - orderParams: { - __typeName: 'List', - __typeValue: this.orderParams - } - }; - } -} - -module.exports = { - UploadScoreRequest, - DeleteScoreRequest, - DeleteAllScoresRequest, - UploadCommonDataRequest, - DeleteCommonDataRequest, - GetCommonDataRequest, - ChangeAttributesRequest, - ChangeAllAttributesRequest, - GetRankingRequest, - GetApproxOrderRequest, - GetStatsRequest, - GetRankingByPIDListRequest, - GetRankingByUniqueIdListRequest, - GetCachedTopXRankingRequest, - GetCachedTopXRankingsRequest -}; \ No newline at end of file diff --git a/src/protocols/requests/ranking_legacy.js b/src/protocols/requests/ranking_legacy.js deleted file mode 100644 index 6cd00cc..0000000 --- a/src/protocols/requests/ranking_legacy.js +++ /dev/null @@ -1,358 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class UploadCommonDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueId = stream.readUInt32LE(); - this.commonData = stream.readNEXBuffer(); - } - - toJSON() { - return { - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - }, - commonData: { - __typeName: 'Buffer', - __typeValue: this.commonData - } - }; - } -} - -class UnknownMethod0xERequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.rankingMode = stream.readUInt8(); - this.category = stream.readUInt32LE(); - this.scoreIndex = stream.readUInt8(); - this.unknown1 = stream.readUInt8(); - this.unknown2 = stream.readUInt8(); - this.unknown3 = stream.readUInt8(); - this.unknown4 = stream.readUInt8(); - this.unknown5 = stream.readUInt8(); - this.unknown6 = stream.readUInt32LE(); - this.offset = stream.readUInt32LE(); - this.length = stream.readUInt8(); - } - - toJSON() { - return { - rankingMode: { - __typeName: 'uint8', - __typeValue: this.rankingMode - }, - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - scoreIndex: { - __typeName: 'uint8', - __typeValue: this.scoreIndex - }, - unknown1: { - __typeName: 'uint8', - __typeValue: this.unknown1 - }, - unknown2: { - __typeName: 'uint8', - __typeValue: this.unknown2 - }, - unknown3: { - __typeName: 'uint8', - __typeValue: this.unknown3 - }, - unknown4: { - __typeName: 'uint8', - __typeValue: this.unknown4 - }, - unknown5: { - __typeName: 'uint8', - __typeValue: this.unknown5 - }, - unknown6: { - __typeName: 'uint32', - __typeValue: this.unknown6 - }, - offset: { - __typeName: 'uint32', - __typeValue: this.offset - }, - length: { - __typeName: 'uint8', - __typeValue: this.length - } - }; - } -} - -class UnknownMethod0xFRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueId = stream.readUInt32LE(); - this.category = stream.readUInt32LE(); - this.scoreIndex = stream.readUInt8(); - this.unknown1 = stream.readUInt8(); - this.unknown2 = stream.readUInt8(); - this.unknown3 = stream.readUInt8(); - this.unknown4 = stream.readUInt8(); - this.unknown5 = stream.readUInt8(); - this.unknown6 = stream.readUInt32LE(); - this.length = stream.readUInt8(); - } - - toJSON() { - return { - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - }, - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - scoreIndex: { - __typeName: 'uint8', - __typeValue: this.scoreIndex - }, - unknown1: { - __typeName: 'uint8', - __typeValue: this.unknown1 - }, - unknown2: { - __typeName: 'uint8', - __typeValue: this.unknown2 - }, - unknown3: { - __typeName: 'uint8', - __typeValue: this.unknown3 - }, - unknown4: { - __typeName: 'uint8', - __typeValue: this.unknown4 - }, - unknown5: { - __typeName: 'uint8', - __typeValue: this.unknown5 - }, - unknown6: { - __typeName: 'uint32', - __typeValue: this.unknown6 - }, - length: { - __typeName: 'uint8', - __typeValue: this.length - } - }; - } -} - -class GetTotalRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.category = stream.readUInt32LE(); - this.unknown1 = stream.readUInt8(); - this.unknown2 = stream.readUInt8(); - this.unknown3 = stream.readUInt8(); - this.unknown4 = stream.readUInt32LE(); - } - - toJSON() { - return { - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - unknown1: { - __typeName: 'uint8', - __typeValue: this.unknown1 - }, - unknown2: { - __typeName: 'uint8', - __typeValue: this.unknown2 - }, - unknown3: { - __typeName: 'uint8', - __typeValue: this.unknown3 - }, - unknown4: { - __typeName: 'uint32', - __typeValue: this.unknown4 - } - }; - } -} - -class UploadScoreWithLimitRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueId = stream.readUInt32LE(); - this.category = stream.readUInt32LE(); - this.scores = stream.readNEXList(stream.readUInt32LE); - this.unknown4 = stream.readUInt8(); - this.unknown5 = stream.readUInt32LE(); - this.unknown6 = stream.readUInt16LE(); - } - - toJSON() { - return { - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - }, - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - scores: { - __typeName: 'List', - __typeValue: this.scores - }, - unknown4: { - __typeName: 'uint8', - __typeValue: this.unknown4 - }, - unknown5: { - __typeName: 'uint32', - __typeValue: this.unknown5 - }, - unknown6: { - __typeName: 'uint16', - __typeValue: this.unknown6 - } - }; - } -} - -class UploadSpecificPeriodScoreRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueId = stream.readUInt32LE(); - this.category = stream.readUInt32LE(); - this.score = stream.readUInt32LE(); - this.unknown1 = stream.readUInt8(); - this.unknown2 = stream.readUInt32LE(); - this.unknown3 = stream.readUInt16LE(); - } - - toJSON() { - return { - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - }, - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - score: { - __typeName: 'uint32', - __typeValue: this.score - }, - unknown1: { - __typeName: 'uint8', - __typeValue: this.unknown1 - }, - unknown2: { - __typeName: 'uint32', - __typeValue: this.unknown2 - }, - unknown3: { - __typeName: 'uint16', - __typeValue: this.unknown3 - } - }; - } -} - -class GetSpecificPeriodDataListRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueId = stream.readUInt32LE(); - this.category = stream.readUInt32LE(); - this.unknown1 = stream.readUInt8(); - this.unknown2 = stream.readUInt8(); - this.unknown3 = stream.readUInt8(); - this.offset = stream.readUInt32LE(); - this.length = stream.readUInt8(); - } - - toJSON() { - return { - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - }, - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - unknown1: { - __typeName: 'uint8', - __typeValue: this.unknown1 - }, - unknown2: { - __typeName: 'uint8', - __typeValue: this.unknown2 - }, - unknown3: { - __typeName: 'uint8', - __typeValue: this.unknown3 - }, - offset: { - __typeName: 'uint32', - __typeValue: this.offset - }, - length: { - __typeName: 'uint8', - __typeValue: this.length - } - }; - } -} - -class GetSpecificPeriodTotalRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.category = stream.readUInt32LE(); - } - - toJSON() { - return { - category: { - __typeName: 'uint32', - __typeValue: this.category - } - }; - } -} - -module.exports = { - UploadCommonDataRequest, - UnknownMethod0xERequest, - UnknownMethod0xFRequest, - GetTotalRequest, - UploadScoreWithLimitRequest, - UploadSpecificPeriodScoreRequest, - GetSpecificPeriodDataListRequest, - GetSpecificPeriodTotalRequest -}; diff --git a/src/protocols/requests/ranking_splatoon.js b/src/protocols/requests/ranking_splatoon.js deleted file mode 100644 index ffcadd3..0000000 --- a/src/protocols/requests/ranking_splatoon.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class GetCompetitionRankingScoreRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetcompetitionRankingScoreByPeriodListRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class UploadCompetitionRankingScoreRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class DeleteCompetitionRankingScoreRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - - -module.exports = { - GetCompetitionRankingScoreRequest, - GetcompetitionRankingScoreByPeriodListRequest, - UploadCompetitionRankingScoreRequest, - DeleteCompetitionRankingScoreRequest -}; \ No newline at end of file diff --git a/src/protocols/requests/secure_connection.js b/src/protocols/requests/secure_connection.js deleted file mode 100644 index 5742b90..0000000 --- a/src/protocols/requests/secure_connection.js +++ /dev/null @@ -1,172 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class RegisterRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.vecMyURLs = stream.readNEXList(stream.readNEXStationURL); - } - - toJSON() { - return { - vecMyURLs: { - __typeName: 'List', - __typeValue: this.vecMyURLs - } - }; - } -} - -class RequestConnectionDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.cidTarget = stream.readUInt32LE(); - this.pidTarget = stream.readUInt32LE(); - } - - toJSON() { - return { - cidTarget: { - __typeName: 'uint32', - __typeValue: this.cidTarget - }, - pidTarget: { - __typeName: 'uint32', - __typeValue: this.pidTarget - } - }; - } -} - -class RequestUrlsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.cidTarget = stream.readUInt32LE(); - this.pidTarget = stream.readUInt32LE(); - } - - toJSON() { - return { - cidTarget: { - __typeName: 'uint32', - __typeValue: this.cidTarget - }, - pidTarget: { - __typeName: 'uint32', - __typeValue: this.pidTarget - } - }; - } -} - -class RegisterExRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.vecMyURLs = stream.readNEXList(stream.readNEXStationURL); - this.hCustomData = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - vecMyURLs: { - __typeName: 'List', - __typeValue: this.vecMyURLs - }, - hCustomData: { - __typeName: 'AnyDataHolder', - __typeValue: this.hCustomData - } - }; - } -} - -class TestConnectivityRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class UpdateURLsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.vecMyURLs = stream.readNEXList(stream.readNEXStationURL); - } - - toJSON() { - return { - vecMyURLs: { - __typeName: 'List', - __typeValue: this.vecMyURLs - } - }; - } -} - -class ReplaceURLRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.target = stream.readNEXStationURL(); - this.url = stream.readNEXStationURL(); - } - - toJSON() { - return { - target: { - __typeName: 'StationURL', - __typeValue: this.target - }, - url: { - __typeName: 'StationURL', - __typeValue: this.url - } - }; - } -} - -class SendReportRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.reportId = stream.readUInt32LE(); - this.reportData = stream.readNEXQBuffer(); - } - - toJSON() { - return { - reportId: { - __typeName: 'uint32', - __typeValue: this.reportId - }, - reportData: { - __typeName: 'qBuffer', - __typeValue: this.reportData - } - }; - } -} - -module.exports = { - RegisterRequest, - RequestConnectionDataRequest, - RequestUrlsRequest, - RegisterExRequest, - TestConnectivityRequest, - UpdateURLsRequest, - ReplaceURLRequest, - SendReportRequest -}; \ No newline at end of file diff --git a/src/protocols/requests/secure_connection_badge_arcade.js b/src/protocols/requests/secure_connection_badge_arcade.js deleted file mode 100644 index dc4adce..0000000 --- a/src/protocols/requests/secure_connection_badge_arcade.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class GetMaintenanceStatusRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -module.exports = { - GetMaintenanceStatusRequest -}; diff --git a/src/protocols/requests/service_item_tkcd.js b/src/protocols/requests/service_item_tkcd.js deleted file mode 100644 index 5b34c37..0000000 --- a/src/protocols/requests/service_item_tkcd.js +++ /dev/null @@ -1,435 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const ServiceItemTKCDTypes = require('../types/service_item_tkcd'); - -class GetEnvironmentRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueId = stream.readNEXString(); - this.platform = stream.readUInt8(); - } - - toJSON() { - return { - uniqueId: { - __typeName: 'String', - __typeValue: this.uniqueId - }, - platform: { - __typeName: 'uint8', - __typeValue: this.platform - } - }; - } -} - -class HttpGetRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.url = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemHttpGetParam); - } - - toJSON() { - return { - url: { - __typeName: 'ServiceItemHttpGetParam', - __typeValue: this.url - } - }; - } -} - -class HttpGetResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class PurchaseServiceItemRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.purchaseServiceItemParam = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemPurchaseServiceItemParam); - } - - toJSON() { - return { - purchaseServiceItemParam: { - __typeName: 'ServiceItemPurchaseServiceItemParam', - __typeValue: this.purchaseServiceItemParam - } - }; - } -} - -class PurchaseServiceItemResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class ListServiceItemRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.listServiceItemParam = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemListServiceItemParam); - } - - toJSON() { - return { - listServiceItemParam: { - __typeName: 'ServiceItemPurchaseServiceItemParam', - __typeValue: this.listServiceItemParam - } - }; - } -} - -class ListServiceItemResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetBalanceRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getBalanceParam = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemGetBalanceParam); - } - - toJSON() { - return { - getBalanceParam: { - __typeName: 'ServiceItemGetBalanceParam', - __typeValue: this.getBalanceParam - } - }; - } -} - -class GetBalanceResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetPrepurchaseInfoRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getPrepurchaseInfoParam = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemGetPrepurchaseInfoParam); - } - - toJSON() { - return { - getPrepurchaseInfoParam: { - __typeName: 'ServiceItemGetPrepurchaseInfoParam', - __typeValue: this.getPrepurchaseInfoParam - } - }; - } -} - -class GetPrepurchaseInfoResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetServiceItemRightRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getServiceItemRightParam = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemGetServiceItemRightParam); - this.withoutRightBinary = stream.readBoolean(); - } - - toJSON() { - return { - getServiceItemRightParam: { - __typeName: 'ServiceItemGetServiceItemRightParam', - __typeValue: this.getServiceItemRightParam - }, - withoutRightBinary: { - __typeName: 'boolean', - __typeValue: this.withoutRightBinary - } - }; - } -} - -class GetServiceItemRightResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetPurchaseHistoryRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getPurchaseHistoryParam = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemGetPurchaseHistoryParam); - } - - toJSON() { - return { - getPurchaseHistoryParam: { - __typeName: 'ServiceItemGetPurchaseHistoryParam', - __typeValue: this.getPurchaseHistoryParam - } - }; - } -} - -class GetPurchaseHistoryResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class PostRightBinaryByAccountRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.postRightBinaryByAccountParam = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemPostRightBinaryByAccountParam); - } - - toJSON() { - return { - postRightBinaryByAccountParam: { - __typeName: 'ServiceItemPostRightBinaryByAccountParam', - __typeValue: this.postRightBinaryByAccountParam - } - }; - } -} - -class UseServiceItemByAccountRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.useServiceItemByAccountParam = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemUseServiceItemByAccountParam); - } - - toJSON() { - return { - useServiceItemByAccountParam: { - __typeName: 'ServiceItemUseServiceItemByAccountParam', - __typeValue: this.useServiceItemByAccountParam - } - }; - } -} - -class UseServiceItemByAccountResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class AcquireServiceItemByAccountRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.acquireServiceItemByAccountParam = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemAcquireServiceItemByAccountParam); - } - - toJSON() { - return { - acquireServiceItemByAccountParam: { - __typeName: 'ServiceItemAcquireServiceItemByAccountParam', - __typeValue: this.acquireServiceItemByAccountParam - } - }; - } -} - -class GetSupportIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getSuppordIdParam = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemGetSupportIdParam); - } - - toJSON() { - return { - getSuppordIdParam: { - __typeName: 'ServiceItemGetSupportIdParam', - __typeValue: this.getSuppordIdParam - } - }; - } -} - -class GetLawMessageRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getLawMessageParam = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemGetLawMessageParam); - } - - toJSON() { - return { - getLawMessageParam: { - __typeName: 'ServiceItemGetLawMessageParam', - __typeValue: this.getLawMessageParam - } - }; - } -} - -class GetLawMessageResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -module.exports = { - GetEnvironmentRequest, - HttpGetRequestRequest, - HttpGetResponseRequest, - PurchaseServiceItemRequestRequest, - PurchaseServiceItemResponseRequest, - ListServiceItemRequestRequest, - ListServiceItemResponseRequest, - GetBalanceRequestRequest, - GetBalanceResponseRequest, - GetPrepurchaseInfoRequestRequest, - GetPrepurchaseInfoResponseRequest, - GetServiceItemRightRequestRequest, - GetServiceItemRightResponseRequest, - GetPurchaseHistoryRequestRequest, - GetPurchaseHistoryResponseRequest, - PostRightBinaryByAccountRequest, - UseServiceItemByAccountRequestRequest, - UseServiceItemByAccountResponseRequest, - AcquireServiceItemByAccountRequest, - GetSupportIdRequest, - GetLawMessageRequestRequest, - GetLawMessageResponseRequest -}; diff --git a/src/protocols/requests/service_item_wii_sports_club.js b/src/protocols/requests/service_item_wii_sports_club.js deleted file mode 100644 index e10f152..0000000 --- a/src/protocols/requests/service_item_wii_sports_club.js +++ /dev/null @@ -1,414 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const ServiceItemWiiSportsClubTypes = require('../types/service_item_wii_sports_club'); - -class HelloRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.name = stream.readNEXString(); - } - - toJSON() { - return { - name: { - __typeName: 'String', - __typeValue: this.name - } - }; - } -} - -class HttpGetRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.url = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemHttpGetParam); - } - - toJSON() { - return { - url: { - __typeName: 'ServiceItemHttpGetParam', - __typeValue: this.url - } - }; - } -} - -class HttpGetResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class PurchaseServiceItemRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.purchaseServiceItemParam = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemPurchaseServiceItemParam); - } - - toJSON() { - return { - purchaseServiceItemParam: { - __typeName: 'ServiceItemPurchaseServiceItemParam', - __typeValue: this.purchaseServiceItemParam - } - }; - } -} - -class PurchaseServiceItemResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class ListServiceItemRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.listServiceItemParam = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemListServiceItemParam); - } - - toJSON() { - return { - listServiceItemParam: { - __typeName: 'ServiceItemPurchaseServiceItemParam', - __typeValue: this.listServiceItemParam - } - }; - } -} - -class ListServiceItemResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetBalanceRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getBalanceParam = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemGetBalanceParam); - } - - toJSON() { - return { - getBalanceParam: { - __typeName: 'ServiceItemGetBalanceParam', - __typeValue: this.getBalanceParam - } - }; - } -} - -class GetBalanceResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetPrepurchaseInfoRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getPrepurchaseInfoParam = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemGetPrepurchaseInfoParam); - } - - toJSON() { - return { - getPrepurchaseInfoParam: { - __typeName: 'ServiceItemGetPrepurchaseInfoParam', - __typeValue: this.getPrepurchaseInfoParam - } - }; - } -} - -class GetPrepurchaseInfoResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetServiceItemRightRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getServiceItemRightParam = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemGetServiceItemRightParam); - } - - toJSON() { - return { - getServiceItemRightParam: { - __typeName: 'ServiceItemGetServiceItemRightParam', - __typeValue: this.getServiceItemRightParam - } - }; - } -} - -class GetServiceItemRightResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetPurchaseHistoryRequestRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getPurchaseHistoryParam = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemGetPurchaseHistoryParam); - } - - toJSON() { - return { - getPurchaseHistoryParam: { - __typeName: 'ServiceItemGetPurchaseHistoryParam', - __typeValue: this.getPurchaseHistoryParam - } - }; - } -} - -class GetPurchaseHistoryResponseRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetNoticeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getNoticeParam = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemGetNoticeParam); - } - - toJSON() { - return { - getNoticeParam: { - __typeName: 'ServiceItemGetNoticeParam', - __typeValue: this.getNoticeParam - } - }; - } -} - -class UpdateAndGetTicketInfoRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.forceRetrieveFromEShop = stream.readBoolean(); - } - - toJSON() { - return { - forceRetrieveFromEShop: { - __typeName: 'boolean', - __typeValue: this.forceRetrieveFromEShop - } - }; - } -} - -class LoadUserInfoRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class SaveUserInfoRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.userInfo = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemUserInfo); - } - - toJSON() { - return { - userInfo: { - __typeName: 'ServiceItemUserInfo', - __typeValue: this.userInfo - } - }; - } -} - -class StartChallengeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.startChallengeParam = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemStartChallengeParam); - } - - toJSON() { - return { - startChallengeParam: { - __typeName: 'ServiceItemStartChallengeParam', - __typeValue: this.startChallengeParam - } - }; - } -} - -class EndChallengeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.endChallengeParam = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemEndChallengeParam); - } - - toJSON() { - return { - endChallengeParam: { - __typeName: 'ServiceItemEndChallengeParam', - __typeValue: this.endChallengeParam - } - }; - } -} - -class RequestTicketRestorationRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestTicketRestorationParam = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemRequestTicketRestorationParam); - } - - toJSON() { - return { - requestTicketRestorationParam: { - __typeName: 'ServiceItemRequestTicketRestorationParam', - __typeValue: this.requestTicketRestorationParam - } - }; - } -} - -module.exports = { - HelloRequest, - HttpGetRequestRequest, - HttpGetResponseRequest, - PurchaseServiceItemRequestRequest, - PurchaseServiceItemResponseRequest, - ListServiceItemRequestRequest, - ListServiceItemResponseRequest, - GetBalanceRequestRequest, - GetBalanceResponseRequest, - GetPrepurchaseInfoRequestRequest, - GetPrepurchaseInfoResponseRequest, - GetServiceItemRightRequestRequest, - GetServiceItemRightResponseRequest, - GetPurchaseHistoryRequestRequest, - GetPurchaseHistoryResponseRequest, - GetNoticeRequest, - UpdateAndGetTicketInfoRequest, - LoadUserInfoRequest, - SaveUserInfoRequest, - StartChallengeRequest, - EndChallengeRequest, - RequestTicketRestorationRequest -}; diff --git a/src/protocols/requests/shop_badge_arcade.js b/src/protocols/requests/shop_badge_arcade.js deleted file mode 100644 index 49ecd84..0000000 --- a/src/protocols/requests/shop_badge_arcade.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const ShopBadgeArcadeTypes = require('../types/shop_badge_arcade'); - -class GetRivTokenRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.itemCode = stream.readNEXString(); - this.referenceId = stream.readNEXQBuffer(); - } - - toJSON() { - return { - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - referenceId: { - __typeName: 'qBuffer', - __typeValue: this.referenceId - } - }; - } -} - -class PostPlayLogRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.param = stream.readNEXStructure(ShopBadgeArcadeTypes.ShopPostPlayLogParam); - } - - toJSON() { - return { - param: { - __typeName: 'ShopPostPlayLogParam', - __typeValue: this.param - } - }; - } -} - -module.exports = { - GetRivTokenRequest, - PostPlayLogRequest -}; diff --git a/src/protocols/requests/shop_pokemon_bank.js b/src/protocols/requests/shop_pokemon_bank.js deleted file mode 100644 index be10af8..0000000 --- a/src/protocols/requests/shop_pokemon_bank.js +++ /dev/null @@ -1,173 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class GetItemsRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class GetChallengeBlobRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class GetRivTokenRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.itemCode = stream.readNEXString(); - this.referenceId = stream.readNEXQBuffer(); - } - - toJSON() { - return { - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - referenceId: { - __typeName: 'qBuffer', - __typeValue: this.referenceId - } - }; - } -} - -class GetRivTokenByItemIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.itemId = stream.readUInt32LE(); - } - - toJSON() { - return { - itemId: { - __typeName: 'uint32', - __typeValue: this.itemId - } - }; - } -} - -class GetItemRightsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.ticketEnvelope = stream.readNEXQBuffer(); - } - - toJSON() { - return { - ticketEnvelope: { - __typeName: 'qBuffer', - __typeValue: this.ticketEnvelope - } - }; - } -} - -class VerifyAndRegisterTicketRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.ticketEnvelope = stream.readNEXQBuffer(); - this.purchasedTime = stream.readNEXDateTime(); - } - - toJSON() { - return { - ticketEnvelope: { - __typeName: 'qBuffer', - __typeValue: this.ticketEnvelope - }, - purchasedTime: { - __typeName: 'DateTime', - __typeValue: this.purchasedTime - } - }; - } -} - -class DebugSetExpireTimeRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.expireTime = stream.readNEXDateTime(); - } - - toJSON() { - return { - expireTime: { - __typeName: 'DateTime', - __typeValue: this.expireTime - } - }; - } -} - -class PrincipalIDToSupportNumberRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pid = stream.readPID(); - } - - toJSON() { - return { - pid: { - __typeName: 'PID', - __typeValue: this.pid - } - }; - } -} - -class SupportNumberToPrincipalIDRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.supportNumber = stream.readNEXString(); - } - - toJSON() { - return { - supportNumber: { - __typeName: 'String', - __typeValue: this.supportNumber - } - }; - } -} - -class GetGameServerTimeRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -module.exports = { - GetItemsRequest, - GetChallengeBlobRequest, - GetRivTokenRequest, - GetRivTokenByItemIdRequest, - GetItemRightsRequest, - VerifyAndRegisterTicketRequest, - DebugSetExpireTimeRequest, - PrincipalIDToSupportNumberRequest, - SupportNumberToPrincipalIDRequest, - GetGameServerTimeRequest -}; diff --git a/src/protocols/requests/storage_manager.js b/src/protocols/requests/storage_manager.js deleted file mode 100644 index e2455a7..0000000 --- a/src/protocols/requests/storage_manager.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class AcquireCardIdRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class ActivateWithCardIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.unknown = stream.readUInt8(); - this.cardId = stream.readUInt64LE(); - } - - toJSON() { - return { - unknown: { - __typeName: 'uint8', - __typeValue: this.unknown - }, - cardId: { - __typeName: 'uint64', - __typeValue: this.cardId - } - }; - } -} - -module.exports = { - AcquireCardIdRequest, - ActivateWithCardIdRequest -}; diff --git a/src/protocols/requests/subscription.js b/src/protocols/requests/subscription.js deleted file mode 100644 index ccdbfcf..0000000 --- a/src/protocols/requests/subscription.js +++ /dev/null @@ -1,364 +0,0 @@ -const Stream = require('../../stream'); - -class CreateMySubscriptionDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class UpdateMySubscriptionDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class ClearMySubscriptionDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class AddTargetRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class DeleteTargetRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class ClearTargetRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetFriendSubscriptionDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetTargetSubscriptionDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetActivePlayerSubscriptionDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetSubscriptionDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class ReplaceTargetAndGetSubscriptionDataRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class SetPrivacyLevelRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetPrivacyLevelRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetSubscriptionUserFriendListRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetPrivacyLevelsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class CreateMySubscriptionDataWithNotificationParamsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class UnknownMethod17Request { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class ClearMySubscriptionDataWithNotificationParamsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -module.exports = { - CreateMySubscriptionDataRequest, - UpdateMySubscriptionDataRequest, - ClearMySubscriptionDataRequest, - AddTargetRequest, - DeleteTargetRequest, - ClearTargetRequest, - GetFriendSubscriptionDataRequest, - GetTargetSubscriptionDataRequest, - GetActivePlayerSubscriptionDataRequest, - GetSubscriptionDataRequest, - ReplaceTargetAndGetSubscriptionDataRequest, - SetPrivacyLevelRequest, - GetPrivacyLevelRequest, - GetSubscriptionUserFriendListRequest, - GetPrivacyLevelsRequest, - CreateMySubscriptionDataWithNotificationParamsRequest, - UnknownMethod17Request, - ClearMySubscriptionDataWithNotificationParamsRequest -}; \ No newline at end of file diff --git a/src/protocols/requests/utility.js b/src/protocols/requests/utility.js deleted file mode 100644 index 4c5aa64..0000000 --- a/src/protocols/requests/utility.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const UtilityTypes = require('../types/utility'); - -class AcquireNexUniqueIdRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class AcquireNexUniqueIdWithPasswordRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class AssociateNexUniqueIdWithMyPrincipalIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueIdInfo = stream.readNEXStructure(UtilityTypes.UniqueIdInfo); - } - - toJSON() { - return { - uniqueIdInfo: { - __typeName: 'UniqueIdInfo', - __typeValue: this.uniqueIdInfo - } - }; - } -} - -class AssociateNexUniqueIdsWithMyPrincipalIdRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueIdInfo = stream.readNEXList(UtilityTypes.UniqueIdInfo); - } - - toJSON() { - return { - uniqueIdInfo: { - __typeName: 'List', - __typeValue: this.uniqueIdInfo - } - }; - } -} - -class GetAssociatedNexUniqueIdWithMyPrincipalIdRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class GetAssociatedNexUniqueIdsWithMyPrincipalIdRequest { - // * Requests nothing - toJSON() { - return {}; - } -} - -class GetIntegerSettingsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.integerSettingIndex = stream.readUInt32LE(); - } - - toJSON() { - return { - integerSettingIndex: { - __typeName: 'uint32', - __typeValue: this.integerSettingIndex - } - }; - } -} - -class GetStringSettingsRequest { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.stringSettingIndex = stream.readUInt32LE(); - } - - toJSON() { - return { - stringSettingIndex: { - __typeName: 'uint32', - __typeValue: this.stringSettingIndex - } - }; - } -} - -module.exports = { - AcquireNexUniqueIdRequest, - AcquireNexUniqueIdWithPasswordRequest, - AssociateNexUniqueIdWithMyPrincipalIdRequest, - AssociateNexUniqueIdsWithMyPrincipalIdRequest, - GetAssociatedNexUniqueIdWithMyPrincipalIdRequest, - GetAssociatedNexUniqueIdsWithMyPrincipalIdRequest, - GetIntegerSettingsRequest, - GetStringSettingsRequest -}; diff --git a/src/protocols/responses/authentication.js b/src/protocols/responses/authentication.js deleted file mode 100644 index d292e9a..0000000 --- a/src/protocols/responses/authentication.js +++ /dev/null @@ -1,202 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); -const AuthenticationTypes = require('../types/authentication'); - -class LoginResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readNEXResult(); - this.pidPrincipal = stream.readPID(); - this.pbufResponse = stream.readNEXBuffer(); - this.pConnectionData = stream.readNEXStructure(NEXTypes.RVConnectionData); - this.strReturnMsg = stream.readNEXString(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'Result', - __typeValue: this.retval - }, - pidPrincipal: { - __typeName: 'PID', - __typeValue: this.pidPrincipal - }, - pbufResponse: { - __typeName: 'Buffer', - __typeValue: this.pbufResponse - }, - pConnectionData: { - __typeName: 'RVConnectionData', - __typeValue: this.pConnectionData - }, - strReturnMsg: { - __typeName: 'String', - __typeValue: this.strReturnMsg - } - }; - } -} - -class LoginExResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readNEXResult(); - this.pidPrincipal = stream.readPID(); - this.pbufResponse = stream.readNEXBuffer(); - this.pConnectionData = stream.readNEXStructure(NEXTypes.RVConnectionData); - this.strReturnMsg = stream.readNEXString(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'Result', - __typeValue: this.retval - }, - pidPrincipal: { - __typeName: 'PID', - __typeValue: this.pidPrincipal - }, - pbufResponse: { - __typeName: 'Buffer', - __typeValue: this.pbufResponse - }, - pConnectionData: { - __typeName: 'RVConnectionData', - __typeValue: this.pConnectionData - }, - strReturnMsg: { - __typeName: 'String', - __typeValue: this.strReturnMsg - } - }; - } -} - -class RequestTicketResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readNEXResult(); - this.bufResponse = stream.readNEXBuffer(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'Result', - __typeValue: this.retval - }, - bufResponse: { - __typeName: 'Buffer', - __typeValue: this.bufResponse - } - }; - } -} - -class GetPIDResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readPID(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'PID', - __typeValue: this.retval - } - }; - } -} - -class GetNameResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readNEXString(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'String', - __typeValue: this.retval - } - }; - } -} - -class LoginWithContextResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readNEXResult(); - this.pidPrincipal = stream.readPID(); - this.pbufResponse = stream.readNEXBuffer(); - this.pConnectionData = stream.readNEXStructure(NEXTypes.RVConnectionData); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'Result', - __typeValue: this.retval - }, - pidPrincipal: { - __typeName: 'PID', - __typeValue: this.pidPrincipal - }, - pbufResponse: { - __typeName: 'Buffer', - __typeValue: this.pbufResponse - }, - pConnectionData: { - __typeName: 'RVConnectionData', - __typeValue: this.pConnectionData - }, - - }; - } -} - -class ValidateAndRequestTicketWithParamResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.result = stream.readNEXStructure(AuthenticationTypes.ValidateAndRequestTicketResult); - } - - toJSON() { - return { - result: { - __typeName: 'ValidateAndRequestTicketResult', - __typeValue: this.result - } - }; - } -} - -module.exports = { - LoginResponse, - LoginExResponse, - RequestTicketResponse, - GetPIDResponse, - GetNameResponse, - LoginWithContextResponse, - ValidateAndRequestTicketWithParamResponse -}; diff --git a/src/protocols/responses/datastore.js b/src/protocols/responses/datastore.js deleted file mode 100644 index d18355c..0000000 --- a/src/protocols/responses/datastore.js +++ /dev/null @@ -1,809 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const DataStoreTypes = require('../types/datastore'); - -class PrepareGetObjectV1Response { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pReqGetInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqGetInfoV1); - } - - toJSON() { - return { - pReqGetInfo: { - __typeName: 'DataStoreReqGetInfoV1', - __typeValue: this.pReqGetInfo - } - }; - } -} - -class PreparePostObjectV1Response { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pReqPostInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqPostInfoV1); - } - - toJSON() { - return { - pReqPostInfo: { - __typeName: 'DataStoreReqPostInfoV1', - __typeValue: this.pReqPostInfo - } - }; - } -} - -class CompletePostObjectV1Response { - // * Returns nothing - toJSON() { - return {}; - } -} - -class DeleteObjectResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class DeleteObjectsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class ChangeMetaV1Response { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ChangeMetasV1Response { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class GetMetaResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pMetaInfo = stream.readNEXStructure(DataStoreTypes.DataStoreMetaInfo); - } - - toJSON() { - return { - pMetaInfo: { - __typeName: 'DataStoreMetaInfo', - __typeValue: this.pMetaInfo - } - }; - } -} - -class GetMetasResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pMetaInfo = stream.readNEXList(DataStoreTypes.DataStoreMetaInfo); - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pMetaInfo: { - __typeName: 'List', - __typeValue: this.pMetaInfo - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class PrepareUpdateObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pReqUpdateInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqUpdateInfo); - } - - toJSON() { - return { - pReqUpdateInfo: { - __typeName: 'DataStoreReqUpdateInfo', - __typeValue: this.pReqUpdateInfo - } - }; - } -} - -class CompleteUpdateObjectResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class SearchObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pSearchResult = stream.readNEXStructure(DataStoreTypes.DataStoreSearchResult); - } - - toJSON() { - return { - pSearchResult: { - __typeName: 'DataStoreSearchResult', - __typeValue: this.pSearchResult - } - }; - } -} - -class GetNotificationUrlResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.info = stream.readNEXStructure(DataStoreTypes.DataStoreReqGetNotificationUrlInfo); - } - - toJSON() { - return { - info: { - __typeName: 'DataStoreReqGetNotificationUrlInfo', - __typeValue: this.info - } - }; - } -} - -class GetNewArrivedNotificationsV1Response { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResult = stream.readNEXStructure(DataStoreTypes.DataStoreNotificationV1); - this.pHasNext = stream.readBoolean(); - } - - toJSON() { - return { - pResult: { - __typeName: 'List', - __typeValue: this.pResult - }, - pHasNext: { - __typeName: 'boolean', - __typeValue: this.pHasNext - } - }; - } -} - -class RateObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRating = stream.readNEXStructure(DataStoreTypes.DataStoreRatingInfo); - } - - toJSON() { - return { - pRating: { - __typeName: 'DataStoreRatingInfo', - __typeValue: this.pRating - } - }; - } -} - -class GetRatingResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRating = stream.readNEXStructure(DataStoreTypes.DataStoreRatingInfo); - } - - toJSON() { - return { - pRating: { - __typeName: 'DataStoreRatingInfo', - __typeValue: this.pRating - } - }; - } -} - -class GetRatingsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRatings = stream.readNEXList(() => stream.readNEXList(DataStoreTypes.DataStoreRatingInfoWithSlot)); // * 2D List - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pRatings: { - __typeName: 'List>', - __typeValue: this.pRatings - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class ResetRatingResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ResetRatingsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class GetSpecificMetaV1Response { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pMetaInfos = stream.readNEXList(DataStoreTypes.DataStoreSpecificMetaInfoV1); - } - - toJSON() { - return { - pMetaInfos: { - __typeName: 'List', - __typeValue: this.pMetaInfos - } - }; - } -} - -class PostMetaBinaryResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataId = stream.readUInt64LE(); - } - - toJSON() { - return { - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - } - }; - } -} - -class TouchObjectResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetRatingWithLogResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRating = stream.readNEXStructure(DataStoreTypes.DataStoreRatingInfo); - this.pRatingLog = stream.readNEXStructure(DataStoreTypes.DataStoreRatingInfo); - } - - toJSON() { - return { - pRating: { - __typeName: 'DataStoreRatingInfo', - __typeValue: this.pRating - }, - pRatingLog: { - __typeName: 'DataStoreRatingInfo', - __typeValue: this.pRatingLog - } - }; - } -} - -class PreparePostObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pReqPostInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqPostInfo); - } - - toJSON() { - return { - pReqPostInfo: { - __typeName: 'DataStoreReqPostInfo', - __typeValue: this.pReqPostInfo - } - }; - } -} - -class PrepareGetObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pReqGetInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqGetInfo); - } - - toJSON() { - return { - pReqGetInfo: { - __typeName: 'DataStoreReqGetInfo', - __typeValue: this.pReqGetInfo - } - }; - } -} - -class CompletePostObjectResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetNewArrivedNotificationsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResult = stream.readNEXStructure(DataStoreTypes.DataStoreNotification); - this.pHasNext = stream.readBoolean(); - } - - toJSON() { - return { - pResult: { - __typeName: 'List', - __typeValue: this.pResult - }, - pHasNext: { - __typeName: 'boolean', - __typeValue: this.pHasNext - } - }; - } -} - -class GetSpecificMetaResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pMetaInfos = stream.readNEXList(DataStoreTypes.DataStoreSpecificMetaInfo); - } - - toJSON() { - return { - pMetaInfos: { - __typeName: 'List', - __typeValue: this.pMetaInfos - } - }; - } -} - -class GetPersistenceInfoResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pPersistenceInfo = stream.readNEXStructure(DataStoreTypes.DataStorePersistenceInfo); - } - - toJSON() { - return { - pPersistenceInfo: { - __typeName: 'DataStorePersistenceInfo', - __typeValue: this.pPersistenceInfo - } - }; - } -} - -class GetPersistenceInfosResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pPersistenceInfo = stream.readNEXList(DataStoreTypes.DataStorePersistenceInfo); - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pPersistenceInfo: { - __typeName: 'List', - __typeValue: this.pPersistenceInfo - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class PerpetuateObjectResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class UnperpetuateObjectResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class PrepareGetObjectOrMetaBinaryResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pReqGetInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqGetInfo); - this.pReqGetAdditionalMeta = stream.readNEXStructure(DataStoreTypes.DataStoreReqGetAdditionalMeta); - } - - toJSON() { - return { - pReqGetInfo: { - __typeName: 'DataStoreReqGetInfo', - __typeValue: this.pReqGetInfo - }, - pReqGetAdditionalMeta: { - __typeName: 'DataStoreReqGetAdditionalMeta', - __typeValue: this.pReqGetAdditionalMeta - } - }; - } -} - -class GetPasswordInfoResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pPasswordInfo = stream.readNEXStructure(DataStoreTypes.DataStorePasswordInfo); - } - - toJSON() { - return { - pPasswordInfo: { - __typeName: 'DataStorePasswordInfo', - __typeValue: this.pPasswordInfo - } - }; - } -} - -class GetPasswordInfosResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pPasswordInfos = stream.readNEXList(DataStoreTypes.DataStorePasswordInfo); - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pPasswordInfos: { - __typeName: 'List', - __typeValue: this.pPasswordInfos - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class GetMetasMultipleParamResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pMetaInfo = stream.readNEXList(DataStoreTypes.DataStoreMetaInfo); - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pMetaInfo: { - __typeName: 'List', - __typeValue: this.pMetaInfo - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class CompletePostObjectsResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ChangeMetaResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ChangeMetasResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class RateObjectsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRatings = stream.readNEXList(DataStoreTypes.DataStoreRatingInfo); - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pRatings: { - __typeName: 'List', - __typeValue: this.pRatings - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class PostMetaBinaryWithDataIdResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class PostMetaBinariesWithDataIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class RateObjectWithPostingResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRating = stream.readNEXStructure(DataStoreTypes.DataStoreRatingInfo); - } - - toJSON() { - return { - pRating: { - __typeName: 'DataStoreRatingInfo', - __typeValue: this.pRating - } - }; - } -} - -class RateObjectsWithPostingResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRatings = stream.readNEXList(DataStoreTypes.DataStoreRatingInfo); - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pRatings: { - __typeName: 'List', - __typeValue: this.pRatings - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class GetObjectInfosResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pInfos = stream.readNEXList(DataStoreTypes.DataStoreReqGetInfo); - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pInfos: { - __typeName: 'List', - __typeValue: this.pInfos - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class SearchObjectLightResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pSearchResult = stream.readNEXStructure(DataStoreTypes.DataStoreSearchResult); - } - - toJSON() { - return { - pSearchResult: { - __typeName: 'DataStoreSearchResult', - __typeValue: this.pSearchResult - } - }; - } -} - -module.exports = { - PrepareGetObjectV1Response, - PreparePostObjectV1Response, - CompletePostObjectV1Response, - DeleteObjectResponse, - DeleteObjectsResponse, - ChangeMetaV1Response, - ChangeMetasV1Response, - GetMetaResponse, - GetMetasResponse, - PrepareUpdateObjectResponse, - CompleteUpdateObjectResponse, - SearchObjectResponse, - GetNotificationUrlResponse, - GetNewArrivedNotificationsV1Response, - RateObjectResponse, - GetRatingResponse, - GetRatingsResponse, - ResetRatingResponse, - ResetRatingsResponse, - GetSpecificMetaV1Response, - PostMetaBinaryResponse, - TouchObjectResponse, - GetRatingWithLogResponse, - PreparePostObjectResponse, - PrepareGetObjectResponse, - CompletePostObjectResponse, - GetNewArrivedNotificationsResponse, - GetSpecificMetaResponse, - GetPersistenceInfoResponse, - GetPersistenceInfosResponse, - PerpetuateObjectResponse, - UnperpetuateObjectResponse, - PrepareGetObjectOrMetaBinaryResponse, - GetPasswordInfoResponse, - GetPasswordInfosResponse, - GetMetasMultipleParamResponse, - CompletePostObjectsResponse, - ChangeMetaResponse, - ChangeMetasResponse, - RateObjectsResponse, - PostMetaBinaryWithDataIdResponse, - PostMetaBinariesWithDataIdResponse, - RateObjectWithPostingResponse, - RateObjectsWithPostingResponse, - GetObjectInfosResponse, - SearchObjectLightResponse -}; \ No newline at end of file diff --git a/src/protocols/responses/datastore_badge_arcade.js b/src/protocols/responses/datastore_badge_arcade.js deleted file mode 100644 index 911d4a1..0000000 --- a/src/protocols/responses/datastore_badge_arcade.js +++ /dev/null @@ -1,30 +0,0 @@ -const Stream = require('../../stream'); - -const DataStoreTypes = require('../types/datastore'); - -class GetMetaByOwnerIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pMetaInfo = stream.readNEXList(DataStoreTypes.DataStoreMetaInfo); - this.pHasNext = stream.readBoolean(); - } - - toJSON() { - return { - pMetaInfo: { - __typeName: 'List', - __typeValue: this.pMetaInfo - }, - pHasNext: { - __typeName: 'boolean', - __typeValue: this.pHasNext - } - }; - } -} - -module.exports = { - GetMetaByOwnerIdResponse -}; diff --git a/src/protocols/responses/datastore_pokemon_bank.js b/src/protocols/responses/datastore_pokemon_bank.js deleted file mode 100644 index 57ae672..0000000 --- a/src/protocols/responses/datastore_pokemon_bank.js +++ /dev/null @@ -1,325 +0,0 @@ -const Stream = require('../../stream'); - -const DataStoreTypes = require('../types/datastore'); -const DataStorePokemonBankTypes = require('../types/datastore_pokemon_bank'); - -class PrepareUploadPokemonResponse { - /** - * - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRecordKey = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationRecordKey); - } - - toJSON() { - return { - pRecordKey: { - __typeName: 'GlobalTradeStationRecordKey', - __typeValue: this.pRecordKey - } - }; - } -} - -class UploadPokemonResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class SearchPokemonResponse { - /** - * - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResult = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationSearchPokemonResult); - } - - toJSON() { - return { - pResult: { - __typeName: 'GlobalTradeStationSearchPokemonResult', - __typeValue: this.pResult - } - }; - } -} - -class PrepareTradePokemonResponse { - /** - * - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResult = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationPrepareTradePokemonResult); - } - - toJSON() { - return { - pResult: { - __typeName: 'GlobalTradeStationPrepareTradePokemonResult', - __typeValue: this.pResult - } - }; - } -} - -class TradePokemonResponse { - /** - * - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResult = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationTradePokemonResult); - } - - toJSON() { - return { - pResult: { - __typeName: 'GlobalTradeStationTradePokemonResult', - __typeValue: this.pResult - } - }; - } -} - -class DownloadOtherPokemonResponse { - /** - * - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResult = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationTradePokemonResult); - } - - toJSON() { - return { - pResult: { - __typeName: 'GlobalTradeStationTradePokemonResult', - __typeValue: this.pResult - } - }; - } -} - -class DownloadMyPokemonResponse { - /** - * - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResult = stream.readNEXStructure(DataStorePokemonBankTypes.GlobalTradeStationDownloadMyPokemonResult); - } - - toJSON() { - return { - pResult: { - __typeName: 'GlobalTradeStationDownloadMyPokemonResult', - __typeValue: this.pResult - } - }; - } -} - -class DeletePokemonResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetTransactionParamResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pTransactionParam = stream.readNEXStructure(DataStorePokemonBankTypes.BankTransactionParam); - this.pStatus = stream.readUInt32LE(); - this.pApplicationId = stream.readUInt16LE(); - } - - toJSON() { - return { - pTransactionParam: { - __typeName: 'BankTransactionParam', - __typeValue: this.pTransactionParam - }, - pStatus: { - __typeName: 'uint32', - __typeValue: this.pStatus - }, - pApplicationId: { - __typeName: 'uint16', - __typeValue: this.pApplicationId - } - }; - } -} - -class PreparePostBankObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pReqPostInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqPostInfo); - } - - toJSON() { - return { - pReqPostInfo: { - __typeName: 'DataStoreReqPostInfo', - __typeValue: this.pReqPostInfo - } - }; - } -} - -class CompletePostBankObjectResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class PrepareGetBankObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pTransactionParam = stream.readNEXStructure(DataStorePokemonBankTypes.BankTransactionParam); - this.pReqGetInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqGetInfo); - } - - toJSON() { - return { - pTransactionParam: { - __typeName: 'BankTransactionParam', - __typeValue: this.pTransactionParam - }, - pReqGetInfo: { - __typeName: 'DataStoreReqGetInfo', - __typeValue: this.pReqGetInfo - } - }; - } -} - -class PrepareUpdateBankObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pTransactionParam = stream.readNEXStructure(DataStorePokemonBankTypes.BankTransactionParam); - this.pReqUpdateInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqUpdateInfo); - } - - toJSON() { - return { - pTransactionParam: { - __typeName: 'BankTransactionParam', - __typeValue: this.pTransactionParam - }, - pReqUpdateInfo: { - __typeName: 'DataStoreReqUpdateInfo', - __typeValue: this.pReqUpdateInfo - } - }; - } -} - -class CompleteUpdateBankObjectResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class RollbackBankObjectResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetUnlockKeyResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pUnlockKeyList = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - pUnlockKeyList: { - __typeName: 'List', - __typeValue: this.pUnlockKeyList - } - }; - } -} - -class RequestMigrationResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.detailCode = stream.readUInt32LE(); - } - - toJSON() { - return { - detailCode: { - __typeName: 'uint32', - __typeValue: this.detailCode - } - }; - } -} - -class GetMigrationStatusResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pInfo = stream.readNEXStructure(DataStorePokemonBankTypes.BankMigrationInfo); - this.detailCode = stream.readUInt32LE(); - } - - toJSON() { - return { - pInfo: { - __typeName: 'BankMigrationInfo', - __typeValue: this.pInfo - }, - detailCode: { - __typeName: 'uint32', - __typeValue: this.detailCode - } - }; - } -} - -module.exports = { - PrepareUploadPokemonResponse, - UploadPokemonResponse, - SearchPokemonResponse, - PrepareTradePokemonResponse, - TradePokemonResponse, - DownloadOtherPokemonResponse, - DownloadMyPokemonResponse, - DeletePokemonResponse, - GetTransactionParamResponse, - PreparePostBankObjectResponse, - CompletePostBankObjectResponse, - PrepareGetBankObjectResponse, - PrepareUpdateBankObjectResponse, - CompleteUpdateBankObjectResponse, - RollbackBankObjectResponse, - GetUnlockKeyResponse, - RequestMigrationResponse, - GetMigrationStatusResponse -}; diff --git a/src/protocols/responses/datastore_smm.js b/src/protocols/responses/datastore_smm.js deleted file mode 100644 index 4408741..0000000 --- a/src/protocols/responses/datastore_smm.js +++ /dev/null @@ -1,690 +0,0 @@ -const Stream = require('../../stream'); - -const DataStoreTypes = require('../types/datastore'); -const DataStoreSMMTypes = require('../types/datastore_smm'); - -class GetObjectInfosResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pInfos = stream.readNEXList(DataStoreSMMTypes.DataStoreFileServerObjectInfo); - } - - toJSON() { - return { - pInfos: { - __typeName: 'List', - __typeValue: this.pInfos - } - }; - } -} - -class GetMetaByOwnerIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pMetaInfo = stream.readNEXList(DataStoreTypes.DataStoreMetaInfo); - this.pHasNext = stream.readBoolean(); - } - - toJSON() { - return { - pMetaInfo: { - __typeName: 'List', - __typeValue: this.pMetaInfo - }, - pHasNext: { - __typeName: 'boolean', - __typeValue: this.pHasNext - } - }; - } -} - -class CustomSearchObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pSearchResult = stream.readNEXStructure(DataStoreTypes.DataStoreSearchResult); - } - - toJSON() { - return { - pSearchResult: { - __typeName: 'DataStoreSearchResult', - __typeValue: this.pSearchResult - } - }; - } -} - -class RateCustomRankingResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetCustomRankingResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRankingResult = stream.readNEXList(DataStoreSMMTypes.DataStoreCustomRankingResult); - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pRankingResult: { - __typeName: 'List', - __typeValue: this.pRankingResult - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class GetCustomRankingByDataIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRankingResult = stream.readNEXList(DataStoreSMMTypes.DataStoreCustomRankingResult); - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pRankingResult: { - __typeName: 'List', - __typeValue: this.pRankingResult - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class DeleteCustomRankingResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class AddToBufferQueueResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class AddToBufferQueuesResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class GetBufferQueueResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pBufferQueue = stream.readNEXList(stream.readNEXQBuffer); - } - - toJSON() { - return { - pBufferQueue: { - __typeName: 'List', - __typeValue: this.pBufferQueue - } - }; - } -} - -class GetBufferQueuesResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pBufferQueueLst = stream.readNEXList(() => stream.readNEXList(stream.readNEXQBuffer)), // * 2D List; - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pBufferQueueLst: { - __typeName: 'List>', - __typeValue: this.pBufferQueue - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class ClearBufferQueuesResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class CompleteAttachFileResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pUrl = stream.readNEXString(); - } - - toJSON() { - return { - pUrl: { - __typeName: 'String', - __typeValue: this.pUrl - } - }; - } -} - -class CompleteAttachFileV1Response { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pUrl = stream.readNEXString(); - } - - toJSON() { - return { - pUrl: { - __typeName: 'String', - __typeValue: this.pUrl - } - }; - } -} - -class PrepareAttachFileResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pReqPostInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqPostInfo); - } - - toJSON() { - return { - pReqPostInfo: { - __typeName: 'DataStoreReqPostInfo', - __typeValue: this.pReqPostInfo - } - }; - } -} - -class ConditionalSearchObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRankingResults = stream.readNEXList(DataStoreSMMTypes.DataStoreCustomRankingResult); - } - - toJSON() { - return { - pRankingResults: { - __typeName: 'List', - __typeValue: this.pRankingResults - } - }; - } -} - -class GetApplicationConfigResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.config = stream.readNEXList(stream.readInt32LE); - } - - toJSON() { - return { - config: { - __typeName: 'List', - __typeValue: this.config - } - }; - } -} - -class SetApplicationConfigResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class DeleteApplicationConfigResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class LatestCourseSearchObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRankingResults = stream.readNEXList(DataStoreSMMTypes.DataStoreCustomRankingResult); - } - - toJSON() { - return { - pRankingResults: { - __typeName: 'List', - __typeValue: this.pRankingResults - } - }; - } -} - -class FollowingsLatestCourseSearchObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRankingResults = stream.readNEXList(DataStoreSMMTypes.DataStoreCustomRankingResult); - } - - toJSON() { - return { - pRankingResults: { - __typeName: 'List', - __typeValue: this.pRankingResults - } - }; - } -} - -class RecommendedCourseSearchObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRankingResults = stream.readNEXList(DataStoreSMMTypes.DataStoreCustomRankingResult); - } - - toJSON() { - return { - pRankingResults: { - __typeName: 'List', - __typeValue: this.pRankingResults - } - }; - } -} - -class ScoreRangeCascadedSearchObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRankingResults = stream.readNEXList(DataStoreSMMTypes.DataStoreCustomRankingResult); - } - - toJSON() { - return { - pRankingResults: { - __typeName: 'List', - __typeValue: this.pRankingResults - } - }; - } -} - -class SuggestedCourseSearchObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRankingResults = stream.readNEXList(DataStoreSMMTypes.DataStoreCustomRankingResult); - } - - toJSON() { - return { - pRankingResults: { - __typeName: 'List', - __typeValue: this.pRankingResults - } - }; - } -} - -class PreparePostObjectWithOwnerIdAndDataIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pReqPostInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqPostInfo); - } - - toJSON() { - return { - pReqPostInfo: { - __typeName: 'DataStoreReqPostInfo', - __typeValue: this.pReqPostInfo - } - }; - } -} - -class CompletePostObjectWithOwnerIdResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class UploadCourseRecordResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetCourseRecordResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.result = stream.readNEXStructure(DataStoreSMMTypes.DataStoreGetCourseRecordResult); - } - - toJSON() { - return { - result: { - __typeName: 'DataStoreGetCourseRecordResult', - __typeValue: this.result - } - }; - } -} - -class DeleteCourseRecordResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetApplicationConfigStringResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.config = stream.readNEXList(stream.readNEXString); - } - - toJSON() { - return { - config: { - __typeName: 'List', - __typeValue: this.config - } - }; - } -} - -class SetApplicationConfigStringResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetDeletionReasonResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pDeletionReasons = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - pDeletionReasons: { - __typeName: 'List', - __typeValue: this.pDeletionReasons - } - }; - } -} - -class SetDeletionReasonResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetMetasWithCourseRecordResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pMetaInfo = stream.readNEXList(DataStoreTypes.DataStoreMetaInfo); - this.pCourseResults = stream.readNEXList(DataStoreSMMTypes.DataStoreGetCourseRecordResult); - this.pResults = stream.readNEXList(stream.readNEXResult); - } - - toJSON() { - return { - pMetaInfo: { - __typeName: 'List', - __typeValue: this.pMetaInfo - }, - pCourseResults: { - __typeName: 'List', - __typeValue: this.pCourseResults - }, - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -class CheckRateCustomRankingCounterResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.isBelowThreshold = stream.readBoolean(); - } - - toJSON() { - return { - isBelowThreshold: { - __typeName: 'boolean', - __typeValue: this.isBelowThreshold - } - }; - } -} - -class ResetRateCustomRankingCounterResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class BestScoreRateCourseSearchObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRankingResults = stream.readNEXList(DataStoreSMMTypes.DataStoreCustomRankingResult); - } - - toJSON() { - return { - pRankingResults: { - __typeName: 'List', - __typeValue: this.pRankingResults - } - }; - } -} - -class CTRPickUpCourseSearchObjectResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRankingResults = stream.readNEXList(DataStoreSMMTypes.DataStoreCustomRankingResult); - } - - toJSON() { - return { - pRankingResults: { - __typeName: 'List', - __typeValue: this.pRankingResults - } - }; - } -} - -class SetCachedRankingResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class DeleteCachedRankingResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ChangePlayablePlatformResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class SearchUnknownPlatformObjectsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an response request format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class ReportCourseResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -module.exports = { - GetObjectInfosResponse, - GetMetaByOwnerIdResponse, - CustomSearchObjectResponse, - RateCustomRankingResponse, - GetCustomRankingResponse, - GetCustomRankingByDataIdResponse, - DeleteCustomRankingResponse, - AddToBufferQueueResponse, - AddToBufferQueuesResponse, - GetBufferQueueResponse, - GetBufferQueuesResponse, - ClearBufferQueuesResponse, - CompleteAttachFileResponse, - CompleteAttachFileV1Response, - PrepareAttachFileResponse, - ConditionalSearchObjectResponse, - GetApplicationConfigResponse, - SetApplicationConfigResponse, - DeleteApplicationConfigResponse, - LatestCourseSearchObjectResponse, - FollowingsLatestCourseSearchObjectResponse, - RecommendedCourseSearchObjectResponse, - ScoreRangeCascadedSearchObjectResponse, - SuggestedCourseSearchObjectResponse, - PreparePostObjectWithOwnerIdAndDataIdResponse, - CompletePostObjectWithOwnerIdResponse, - UploadCourseRecordResponse, - GetCourseRecordResponse, - DeleteCourseRecordResponse, - GetApplicationConfigStringResponse, - SetApplicationConfigStringResponse, - GetDeletionReasonResponse, - SetDeletionReasonResponse, - GetMetasWithCourseRecordResponse, - CheckRateCustomRankingCounterResponse, - ResetRateCustomRankingCounterResponse, - BestScoreRateCourseSearchObjectResponse, - CTRPickUpCourseSearchObjectResponse, - SetCachedRankingResponse, - DeleteCachedRankingResponse, - ChangePlayablePlatformResponse, - SearchUnknownPlatformObjectsResponse, - ReportCourseResponse -}; \ No newline at end of file diff --git a/src/protocols/responses/friends_3ds.js b/src/protocols/responses/friends_3ds.js deleted file mode 100644 index 6333321..0000000 --- a/src/protocols/responses/friends_3ds.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const Friends3DSTypes = require('../types/friends_3ds'); - -class SyncFriendResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.friendRelationships = stream.readNEXList(Friends3DSTypes.FriendRelationship); - } - - toJSON() { - return { - friendRelationships: { - __typeName: 'List', - __typeValue: this.friendRelationships - } - }; - } -} - -class UpdatePresenceResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetFriendPresenceResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.presenceList = stream.readNEXList(Friends3DSTypes.FriendPresence); - } - - toJSON() { - return { - presenceList: { - __typeName: 'List', - __typeValue: this.presenceList - } - }; - } -} - -class GetFriendPersistentInfoResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.infoList = stream.readNEXList(Friends3DSTypes.FriendPersistentInfo); - } - - toJSON() { - return { - presenceList: { - __typeName: 'List', - __typeValue: this.infoList - } - }; - } -} - -module.exports = { - SyncFriendResponse, - UpdatePresenceResponse, - GetFriendPresenceResponse, - GetFriendPersistentInfoResponse -}; diff --git a/src/protocols/responses/friends_wiiu.js b/src/protocols/responses/friends_wiiu.js deleted file mode 100644 index d92b1cf..0000000 --- a/src/protocols/responses/friends_wiiu.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const FriendsWiiUTypes = require('../types/friends_wiiu'); - -class UpdateAndGetAllInformationResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.principalPreference = stream.readNEXStructure(FriendsWiiUTypes.PrincipalPreference); - this.statusMessage = stream.readNEXStructure(FriendsWiiUTypes.Comment); - this.friendList = stream.readNEXList(FriendsWiiUTypes.FriendInfo); - this.sentFriendRequests = stream.readNEXList(FriendsWiiUTypes.FriendRequest); - this.receivedFriendRequests = stream.readNEXList(FriendsWiiUTypes.FriendRequest); - this.blacklist = stream.readNEXList(FriendsWiiUTypes.BlacklistedPrincipal); - this.unknown1 = stream.readBoolean(); - this.notifications = stream.readNEXList(FriendsWiiUTypes.PersistentNotification); - this.unknown2 = stream.readBoolean(); - } - - toJSON() { - return { - principalPreference: { - __typeName: 'PrincipalPreference', - __typeValue: this.principalPreference - }, - statusMessage: { - __typeName: 'Comment', - __typeValue: this.statusMessage - }, - friendList: { - __typeName: 'List', - __typeValue: this.friendList - }, - sentFriendRequests: { - __typeName: 'List', - __typeValue: this.sentFriendRequests - }, - receivedFriendRequests: { - __typeName: 'List', - __typeValue: this.receivedFriendRequests - }, - blacklist: { - __typeName: 'List', - __typeValue: this.blacklist - }, - unknown1: { - __typeName: 'boolean', - __typeValue: this.unknown1 - }, - notifications: { - __typeName: 'List', - __typeValue: this.notifications - }, - unknown2: { - __typeName: 'boolean', - __typeValue: this.unknown2 - } - }; - } -} - -class UpdatePresenceResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -module.exports = { - UpdateAndGetAllInformationResponse, - UpdatePresenceResponse -}; diff --git a/src/protocols/responses/match_making.js b/src/protocols/responses/match_making.js deleted file mode 100644 index 860c3ba..0000000 --- a/src/protocols/responses/match_making.js +++ /dev/null @@ -1,814 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const MatchMakingTypes = require('../types/match_making'); - -class RegisterGatheringResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readUInt32LE(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'uint32', - __typeValue: this.retval - } - }; - } -} - -class UnregisterGatheringResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class UnregisterGatheringsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class UpdateGatheringResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class InviteResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class AcceptInvitationResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class DeclineInvitationResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class CancelInvitationResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class GetInvitationsSentResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstInvitations = stream.readNEXList(MatchMakingTypes.Invitation); - } - - toJSON() { - return { - lstInvitations: { - __typeName: 'List', - __typeValue: this.lstInvitations - } - }; - } -} - -class GetInvitationsReceivedResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstInvitations = stream.readNEXList(MatchMakingTypes.Invitation); - } - - toJSON() { - return { - lstInvitations: { - __typeName: 'List', - __typeValue: this.lstInvitations - } - }; - } -} - -class ParticipateResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class CancelParticipationResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class GetParticipantsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readNEXList(stream.readPID); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'List', - __typeValue: this.retval - } - }; - } -} - -class AddParticipantsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class GetDetailedParticipantsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstParticipants = stream.readNEXList(MatchMakingTypes.ParticipantDetails); - } - - toJSON() { - return { - lstParticipants: { - __typeName: 'List', - __typeValue: this.lstParticipants - } - }; - } -} - -class GetParticipantsURLsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstStationURL = stream.readNEXList(stream.readNEXStationURL); - } - - toJSON() { - return { - lstStationURL: { - __typeName: 'List', - __typeValue: this.lstStationURL - } - }; - } -} - -class FindByTypeResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGathering = stream.readNEXList(stream.readNEXAnyDataHolder); - } - - toJSON() { - return { - lstGathering: { - __typeName: 'List', - __typeValue: this.lstGathering - } - }; - } -} - -class FindByDescriptionResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGathering = stream.readNEXList(stream.readNEXAnyDataHolder); - } - - toJSON() { - return { - lstGathering: { - __typeName: 'List', - __typeValue: this.lstGathering - } - }; - } -} - -class FindByDescriptionRegexResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGathering = stream.readNEXList(stream.readNEXAnyDataHolder); - } - - toJSON() { - return { - lstGathering: { - __typeName: 'List', - __typeValue: this.lstGathering - } - }; - } -} - -class FindByIDResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGathering = stream.readNEXList(stream.readNEXAnyDataHolder); - } - - toJSON() { - return { - lstGathering: { - __typeName: 'List', - __typeValue: this.lstGathering - } - }; - } -} - -class FindBySingleIDResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.bResult = stream.readBoolean(); - this.pGathering = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - bResult: { - __typeName: 'boolean', - __typeValue: this.bResult - }, - pGathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.pGathering - } - }; - } -} - -class FindByOwnerResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGathering = stream.readNEXList(stream.readNEXAnyDataHolder); - } - - toJSON() { - return { - lstGathering: { - __typeName: 'List', - __typeValue: this.lstGathering - } - }; - } -} - -class FindByParticipantsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGathering = stream.readNEXList(stream.readNEXAnyDataHolder); - } - - toJSON() { - return { - lstGathering: { - __typeName: 'List', - __typeValue: this.lstGathering - } - }; - } -} - -class FindInvitationsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGathering = stream.readNEXList(stream.readNEXAnyDataHolder); - } - - toJSON() { - return { - lstGathering: { - __typeName: 'List', - __typeValue: this.lstGathering - } - }; - } -} - -class FindBySQLQueryResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGathering = stream.readNEXList(stream.readNEXAnyDataHolder); - } - - toJSON() { - return { - lstGathering: { - __typeName: 'List', - __typeValue: this.lstGathering - } - }; - } -} - -class LaunchSessionResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class UpdateSessionURLResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class GetSessionURLResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - this.strURL = stream.readNEXString(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - }, - strURL: { - __typeName: 'String', - __typeValue: this.strURL - } - }; - } -} - -class GetStateResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - this.uiState = stream.readUInt32LE(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - }, - uiState: { - __typeName: 'uint32', - __typeValue: this.uiState - } - }; - } -} - -class SetStateResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class ReportStatsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class GetStatsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - this.lstStats = stream.readNEXList(MatchMakingTypes.GatheringStats); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - }, - lstStats: { - __typeName: 'List', - __typeValue: this.lstStats - } - }; - } -} - -class DeleteGatheringResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class GetPendingDeletionsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - this.lstDeletions = stream.readNEXList(MatchMakingTypes.DeletionEntry); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - }, - lstDeletions: { - __typeName: 'List', - __typeValue: this.lstDeletions - } - }; - } -} - -class DeleteFromDeletionsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class MigrateGatheringOwnershipV1Response { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class FindByDescriptionLikeResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGathering = stream.readNEXList(stream.readNEXAnyDataHolder); - } - - toJSON() { - return { - lstGathering: { - __typeName: 'List', - __typeValue: this.lstGathering - } - }; - } -} - -class RegisterLocalURLResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class RegisterLocalURLsResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class UpdateSessionHostV1Response { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetSessionURLsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstURLs = stream.readNEXList(stream.readNEXStationURL); - } - - toJSON() { - return { - lstURLs: { - __typeName: 'List', - __typeValue: this.lstURLs - } - }; - } -} - -class UpdateSessionHostResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class UpdateGatheringOwnershipResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class MigrateGatheringOwnershipResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - - -module.exports = { - RegisterGatheringResponse, - UnregisterGatheringResponse, - UnregisterGatheringsResponse, - UpdateGatheringResponse, - InviteResponse, - AcceptInvitationResponse, - DeclineInvitationResponse, - CancelInvitationResponse, - GetInvitationsSentResponse, - GetInvitationsReceivedResponse, - ParticipateResponse, - CancelParticipationResponse, - GetParticipantsResponse, - AddParticipantsResponse, - GetDetailedParticipantsResponse, - GetParticipantsURLsResponse, - FindByTypeResponse, - FindByDescriptionResponse, - FindByDescriptionRegexResponse, - FindByIDResponse, - FindBySingleIDResponse, - FindByOwnerResponse, - FindByParticipantsResponse, - FindInvitationsResponse, - FindBySQLQueryResponse, - LaunchSessionResponse, - UpdateSessionURLResponse, - GetSessionURLResponse, - GetStateResponse, - SetStateResponse, - ReportStatsResponse, - GetStatsResponse, - DeleteGatheringResponse, - GetPendingDeletionsResponse, - DeleteFromDeletionsResponse, - MigrateGatheringOwnershipV1Response, - FindByDescriptionLikeResponse, - RegisterLocalURLResponse, - RegisterLocalURLsResponse, - UpdateSessionHostV1Response, - GetSessionURLsResponse, - UpdateSessionHostResponse, - UpdateGatheringOwnershipResponse, - MigrateGatheringOwnershipResponse -}; \ No newline at end of file diff --git a/src/protocols/responses/match_making_ext.js b/src/protocols/responses/match_making_ext.js deleted file mode 100644 index b7e42ba..0000000 --- a/src/protocols/responses/match_making_ext.js +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const MatchMakingTypes = require('../types/match_making'); - -class EndParticipationResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - } - }; - } -} - -class GetParticipantsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstParticipants = stream.readNEXList(stream.readPID); - } - - toJSON() { - return { - lstParticipants: { - __typeName: 'List', - __typeValue: this.lstParticipants - } - }; - } -} - -class GetDetailedParticipantsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstParticipants = stream.readNEXList(MatchMakingTypes.ParticipantDetails); - } - - toJSON() { - return { - lstParticipants: { - __typeName: 'List', - __typeValue: this.lstParticipants - } - }; - } -} - -class GetParticipantsURLsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGatheringURLs = stream.readNEXList(MatchMakingTypes.GatheringURLs); - } - - toJSON() { - return { - lstGatheringURLs: { - __typeName: 'List', - __typeValue: this.lstGatheringURLs - } - }; - } -} - -class GetGatheringRelationsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readNEXString(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'String', - __typeValue: this.retval - } - }; - } -} - -class DeleteFromDeletionsResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -module.exports = { - EndParticipationResponse, - GetParticipantsResponse, - GetDetailedParticipantsResponse, - GetParticipantsURLsResponse, - GetGatheringRelationsResponse, - DeleteFromDeletionsResponse -}; \ No newline at end of file diff --git a/src/protocols/responses/matchmake_extension.js b/src/protocols/responses/matchmake_extension.js deleted file mode 100644 index 4208199..0000000 --- a/src/protocols/responses/matchmake_extension.js +++ /dev/null @@ -1,840 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const semver = require('semver'); -const MatchMakingTypes = require('../types/match_making'); -const NotificationsTypes = require('../types/notifications'); - -class CloseParticipationResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class OpenParticipationResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class AutoMatchmake_PostponeResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.joinedGathering = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - joinedGathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.joinedGathering - } - }; - } -} - -class BrowseMatchmakeSessionResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGathering = stream.readNEXList(stream.readNEXAnyDataHolder); - } - - toJSON() { - return { - lstGathering: { - __typeName: 'List', - __typeValue: this.lstGathering - } - }; - } -} - -class BrowseMatchmakeSessionWithHostUrlsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstGathering = stream.readNEXList(stream.readNEXAnyDataHolder); - this.lstGatheringUrls = stream.readNEXList(MatchMakingTypes.GatheringURLs); - } - - toJSON() { - return { - lstGathering: { - __typeName: 'List', - __typeValue: this.lstGathering - }, - lstGatheringUrls: { - __typeName: 'List', - __typeValue: this.lstGatheringUrls - } - }; - } -} - -class CreateMatchmakeSessionResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - const nexVersion = stream.connection.title.nex_match_making_version || stream.connection.title.nex_version; - - this.gid = stream.readUInt32LE(); - - if (semver.gte(nexVersion, '3.0.0')) { - this.sessionKey = stream.readNEXBuffer(); - } - } - - toJSON() { - const data = { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - } - }; - - if (this.sessionKey !== undefined) { - data.sessionKey = { - __typeName: 'Buffer', - __typeValue: this.sessionKey - }; - } - - return data; - } -} - -class JoinMatchmakeSessionResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - const nexVersion = stream.connection.title.nex_match_making_version || stream.connection.title.nex_version; - - if (semver.gte(nexVersion, '3.0.0')) { - this.sessionKey = stream.readNEXBuffer(); - } - } - - toJSON() { - const data = {}; - - if (this.sessionKey !== undefined) { - data.sessionKey = { - __typeName: 'Buffer', - __typeValue: this.sessionKey - }; - } - - return data; - } -} - -class ModifyCurrentGameAttributeResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class UpdateNotificationDataResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetFriendNotificationDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataList = stream.readNEXList(NotificationsTypes.NotificationEvent); - } - - toJSON() { - return { - dataList: { - __typeName: 'List', - __typeValue: this.dataList - } - }; - } -} - -class UpdateApplicationBufferResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class UpdateMatchmakeSessionAttributeResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetlstFriendNotificationDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.dataList = stream.readNEXList(NotificationsTypes.NotificationEvent); - } - - toJSON() { - return { - dataList: { - __typeName: 'List', - __typeValue: this.dataList - } - }; - } -} - -class UpdateMatchmakeSessionResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class AutoMatchmakeWithSearchCriteria_PostponeResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.joinedGathering = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - joinedGathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.joinedGathering - } - }; - } -} - -class GetPlayingSessionResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstPlayingSession = stream.readNEXList(MatchMakingTypes.PlayingSession); - } - - toJSON() { - return { - lstPlayingSession: { - __typeName: 'List', - __typeValue: this.lstPlayingSession - } - }; - } -} - -class CreateCommunityResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.gid = stream.readUInt32LE(); - } - - toJSON() { - return { - gid: { - __typeName: 'uint32', - __typeValue: this.gid - } - }; - } -} - -class UpdateCommunityResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class JoinCommunityResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class FindCommunityByGatheringIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstCommunity = stream.readNEXList(MatchMakingTypes.PersistentGathering); - } - - toJSON() { - return { - lstCommunity: { - __typeName: 'List', - __typeValue: this.lstCommunity - } - }; - } -} - -class FindOfficialCommunityResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstCommunity = stream.readNEXList(MatchMakingTypes.PersistentGathering); - } - - toJSON() { - return { - lstCommunity: { - __typeName: 'List', - __typeValue: this.lstCommunity - } - }; - } -} - -class FindCommunityByParticipantResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstCommunity = stream.readNEXList(MatchMakingTypes.PersistentGathering); - } - - toJSON() { - return { - lstCommunity: { - __typeName: 'List', - __typeValue: this.lstCommunity - } - }; - } -} - -class UpdatePrivacySettingResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetMyBlockListResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstPrincipalId = stream.readNEXList(stream.readPID); - } - - toJSON() { - return { - lstPrincipalId: { - __typeName: 'List', - __typeValue: this.lstPrincipalId - } - }; - } -} - -class AddToBlockListResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class RemoveFromBlockListResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ClearMyBlockListResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ReportViolationResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class IsViolationUserResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.flag = stream.readBoolean(); - this.score = stream.readUInt32LE(); - } - - toJSON() { - return { - flag: { - __typeName: 'boolean', - __typeValue: this.flag - }, - score: { - __typeName: 'uint32', - __typeValue: this.score - } - }; - } -} - -class JoinMatchmakeSessionExResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.sessionKey = stream.readNEXBuffer(); - } - - toJSON() { - return { - sessionKey: { - __typeName: 'Buffer', - __typeValue: this.sessionKey - } - }; - } -} - -class GetSimplePlayingSessionResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstSimplePlayingSession = stream.readNEXList(MatchMakingTypes.SimplePlayingSession); - } - - toJSON() { - return { - lstSimplePlayingSession: { - __typeName: 'List', - __typeValue: this.lstSimplePlayingSession - } - }; - } -} - -class GetSimpleCommunityResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstSimpleCommunityList = stream.readNEXList(MatchMakingTypes.SimpleCommunity); - } - - toJSON() { - return { - lstSimpleCommunityList: { - __typeName: 'List', - __typeValue: this.lstSimpleCommunityList - } - }; - } -} - -class AutoMatchmakeWithGatheringId_PostponeResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.joinedGathering = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - joinedGathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.joinedGathering - } - }; - } -} - -class UpdateProgressScoreResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class DebugNotifyEventResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GenerateMatchmakeSessionSystemPasswordResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.password = stream.readNEXString(); - } - - toJSON() { - return { - password: { - __typeName: 'String', - __typeValue: this.password - } - }; - } -} - -class ClearMatchmakeSessionSystemPasswordResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class CreateMatchmakeSessionWithParamResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.joinedMatchmakeSession = stream.readNEXStructure(MatchMakingTypes.MatchmakeSession); - } - - toJSON() { - return { - joinedMatchmakeSession: { - __typeName: 'MatchmakeSession', - __typeValue: this.joinedMatchmakeSession - } - }; - } -} - -class JoinMatchmakeSessionWithParamResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.joinedMatchmakeSession = stream.readNEXStructure(MatchMakingTypes.MatchmakeSession); - } - - toJSON() { - return { - joinedMatchmakeSession: { - __typeName: 'MatchmakeSession', - __typeValue: this.joinedMatchmakeSession - } - }; - } -} - -class AutoMatchmakeWithParam_PostponeResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.joinedMatchmakeSession = stream.readNEXStructure(MatchMakingTypes.MatchmakeSession); - } - - toJSON() { - return { - joinedMatchmakeSession: { - __typeName: 'MatchmakeSession', - __typeValue: this.joinedMatchmakeSession - } - }; - } -} - -class FindMatchmakeSessionByGatheringIdDetailResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.matchmakeSession = stream.readNEXStructure(MatchMakingTypes.MatchmakeSession); - } - - toJSON() { - return { - matchmakeSession: { - __typeName: 'MatchmakeSession', - __typeValue: this.matchmakeSession - } - }; - } -} - -class BrowseMatchmakeSessionNoHolderResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstMatchmakeSession = stream.readNEXList(MatchMakingTypes.MatchmakeSession); - } - - toJSON() { - return { - lstMatchmakeSession: { - __typeName: 'List', - __typeValue: this.lstMatchmakeSession - } - }; - } -} - -class BrowseMatchmakeSessionWithHostUrlsNoHolderResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstMatchmakeSession = stream.readNEXList(MatchMakingTypes.MatchmakeSession); - this.lstGatheringUrls = stream.readNEXList(MatchMakingTypes.GatheringURLs); - } - - toJSON() { - return { - lstMatchmakeSession: { - __typeName: 'List', - __typeValue: this.lstMatchmakeSession - }, - lstGatheringUrls: { - __typeName: 'List', - __typeValue: this.lstGatheringUrls - } - }; - } -} - -class UpdateMatchmakeSessionPartResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class RequestMatchmakingResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt64LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint64', - __typeValue: this.requestId - } - }; - } -} - -class WithdrawMatchmakingResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class WithdrawMatchmakingAllResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class FindMatchmakeSessionByGatheringIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstMatchmakeSession = stream.readNEXList(MatchMakingTypes.MatchmakeSession); - } - - toJSON() { - return { - lstMatchmakeSession: { - __typeName: 'List', - __typeValue: this.lstMatchmakeSession - } - }; - } -} - -class FindMatchmakeSessionBySingleGatheringIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.matchmakeSession = stream.readNEXStructure(MatchMakingTypes.MatchmakeSession); - } - - toJSON() { - return { - matchmakeSession: { - __typeName: 'MatchmakeSession', - __typeValue: this.matchmakeSession - } - }; - } -} - -class FindMatchmakeSessionByOwnerResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstMatchmakeSession = stream.readNEXList(MatchMakingTypes.MatchmakeSession); - } - - toJSON() { - return { - lstMatchmakeSession: { - __typeName: 'List', - __typeValue: this.lstMatchmakeSession - } - }; - } -} - -class FindMatchmakeSessionByParticipantResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstSession = stream.readNEXList(MatchMakingTypes.FindMatchmakeSessionByParticipantResult); - } - - toJSON() { - return { - lstSession: { - __typeName: 'List', - __typeValue: this.lstSession - } - }; - } -} - -class BrowseMatchmakeSessionNoHolderNoResultRangeResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstMatchmakeSession = stream.readNEXList(MatchMakingTypes.MatchmakeSession); - } - - toJSON() { - return { - lstMatchmakeSession: { - __typeName: 'List', - __typeValue: this.lstMatchmakeSession - } - }; - } -} - -class BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRangeResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.lstMatchmakeSession = stream.readNEXList(MatchMakingTypes.MatchmakeSession); - this.lstGatheringUrls = stream.readNEXList(MatchMakingTypes.GatheringURLs); - } - - toJSON() { - return { - lstMatchmakeSession: { - __typeName: 'List', - __typeValue: this.lstMatchmakeSession - }, - lstGatheringUrls: { - __typeName: 'List', - __typeValue: this.lstGatheringUrls - } - }; - } -} - -module.exports = { - CloseParticipationResponse, - OpenParticipationResponse, - AutoMatchmake_PostponeResponse, - BrowseMatchmakeSessionResponse, - BrowseMatchmakeSessionWithHostUrlsResponse, - CreateMatchmakeSessionResponse, - JoinMatchmakeSessionResponse, - ModifyCurrentGameAttributeResponse, - UpdateNotificationDataResponse, - GetFriendNotificationDataResponse, - UpdateApplicationBufferResponse, - UpdateMatchmakeSessionAttributeResponse, - GetlstFriendNotificationDataResponse, - UpdateMatchmakeSessionResponse, - AutoMatchmakeWithSearchCriteria_PostponeResponse, - GetPlayingSessionResponse, - CreateCommunityResponse, - UpdateCommunityResponse, - JoinCommunityResponse, - FindCommunityByGatheringIdResponse, - FindOfficialCommunityResponse, - FindCommunityByParticipantResponse, - UpdatePrivacySettingResponse, - GetMyBlockListResponse, - AddToBlockListResponse, - RemoveFromBlockListResponse, - ClearMyBlockListResponse, - ReportViolationResponse, - IsViolationUserResponse, - JoinMatchmakeSessionExResponse, - GetSimplePlayingSessionResponse, - GetSimpleCommunityResponse, - AutoMatchmakeWithGatheringId_PostponeResponse, - UpdateProgressScoreResponse, - DebugNotifyEventResponse, - GenerateMatchmakeSessionSystemPasswordResponse, - ClearMatchmakeSessionSystemPasswordResponse, - CreateMatchmakeSessionWithParamResponse, - JoinMatchmakeSessionWithParamResponse, - AutoMatchmakeWithParam_PostponeResponse, - FindMatchmakeSessionByGatheringIdDetailResponse, - BrowseMatchmakeSessionNoHolderResponse, - BrowseMatchmakeSessionWithHostUrlsNoHolderResponse, - UpdateMatchmakeSessionPartResponse, - RequestMatchmakingResponse, - WithdrawMatchmakingResponse, - WithdrawMatchmakingAllResponse, - FindMatchmakeSessionByGatheringIdResponse, - FindMatchmakeSessionBySingleGatheringIdResponse, - FindMatchmakeSessionByOwnerResponse, - FindMatchmakeSessionByParticipantResponse, - BrowseMatchmakeSessionNoHolderNoResultRangeResponse, - BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRangeResponse -}; diff --git a/src/protocols/responses/matchmake_extension_mk8.js b/src/protocols/responses/matchmake_extension_mk8.js deleted file mode 100644 index 09c80e1..0000000 --- a/src/protocols/responses/matchmake_extension_mk8.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class JoinMatchmakeSessionWithExtraParticipantsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.sessionKey = stream.readNEXBuffer(); - } - - toJSON() { - return { - sessionKey: { - __typeName: 'Buffer', - __typeValue: this.sessionKey - } - }; - } -} - -module.exports = { - JoinMatchmakeSessionWithExtraParticipantsResponse -}; diff --git a/src/protocols/responses/message_delivery.js b/src/protocols/responses/message_delivery.js deleted file mode 100644 index 14e7481..0000000 --- a/src/protocols/responses/message_delivery.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class DeliverMessageResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -module.exports = { - DeliverMessageResponse -}; \ No newline at end of file diff --git a/src/protocols/responses/nat_traversal.js b/src/protocols/responses/nat_traversal.js deleted file mode 100644 index 5889aa9..0000000 --- a/src/protocols/responses/nat_traversal.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class RequestProbeInitiationResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class InitiateProbeResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class RequestProbeInitiationExtResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ReportNATTraversalResultResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ReportNATPropertiesResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetRelaySignatureKeyResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.relayMode = stream.readInt32LE(); - this.currentUTCTime = stream.readNEXDateTime(); - this.address = stream.readNEXString(); - this.port = stream.readUInt16LE(); - this.relayAddressType = stream.readInt32LE(); - this.gameServerID = stream.readUInt32LE(); - } - - toJSON() { - return { - relayMode: { - __typeName: 'sint32', - __typeValue: this.relayMode - }, - currentUTCTime: { - __typeName: 'DateTime', - __typeValue: this.currentUTCTime - }, - address: { - __typeName: 'String', - __typeValue: this.address - }, - port: { - __typeName: 'uint16', - __typeValue: this.port - }, - relayAddressType: { - __typeName: 'sint32', - __typeValue: this.relayAddressType - }, - gameServerID: { - __typeName: 'uint32', - __typeValue: this.gameServerID - } - }; - } -} - -class ReportNATTraversalResultDetailResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -module.exports = { - RequestProbeInitiationResponse, - InitiateProbeResponse, - RequestProbeInitiationExtResponse, - ReportNATTraversalResultResponse, - ReportNATPropertiesResponse, - GetRelaySignatureKeyResponse, - ReportNATTraversalResultDetailResponse -}; \ No newline at end of file diff --git a/src/protocols/responses/nintendo_notifications.js b/src/protocols/responses/nintendo_notifications.js deleted file mode 100644 index 497cc52..0000000 --- a/src/protocols/responses/nintendo_notifications.js +++ /dev/null @@ -1,18 +0,0 @@ -class ProcessNintendoNotificationEvent1Response { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ProcessNintendoNotificationEvent2Response { - // * Returns nothing - toJSON() { - return {}; - } -} - -module.exports = { - ProcessNintendoNotificationEvent1Response, - ProcessNintendoNotificationEvent2Response -}; \ No newline at end of file diff --git a/src/protocols/responses/notifications.js b/src/protocols/responses/notifications.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/protocols/responses/ranking.js b/src/protocols/responses/ranking.js deleted file mode 100644 index a9b6323..0000000 --- a/src/protocols/responses/ranking.js +++ /dev/null @@ -1,216 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const RankingTypes = require('../types/ranking'); - -class UploadScoreResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class DeleteScoreResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class DeleteAllScoresResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class UploadCommonDataResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class DeleteCommonDataResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetCommonDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.commonData = stream.readNEXBuffer(); - } - - toJSON() { - return { - commonData: { - __typeName: 'Buffer', - __typeValue: this.commonData - } - }; - } -} - -class ChangeAttributesResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ChangeAllAttributesResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetRankingResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResult = stream.readNEXStructure(RankingTypes.RankingResult); - } - - toJSON() { - return { - pResult: { - __typeName: 'RankingResult', - __typeValue: this.pResult - } - }; - } -} - -class GetApproxOrderResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pOrder = stream.readUInt32LE(); - } - - toJSON() { - return { - pOrder: { - __typeName: 'uint32', - __typeValue: this.pOrder - } - }; - } -} - -class GetStatsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pStats = stream.readNEXStructure(RankingTypes.RankingStats); - } - - toJSON() { - return { - pStats: { - __typeName: 'RankingStats', - __typeValue: this.pStats - } - }; - } -} - -class GetRankingByPIDListResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResult = stream.readNEXStructure(RankingTypes.RankingResult); - } - - toJSON() { - return { - pResult: { - __typeName: 'RankingResult', - __typeValue: this.pResult - } - }; - } -} - -class GetRankingByUniqueIdListResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResult = stream.readNEXStructure(RankingTypes.RankingResult); - } - - toJSON() { - return { - pResult: { - __typeName: 'RankingResult', - __typeValue: this.pResult - } - }; - } -} - -class GetCachedTopXRankingResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResult = stream.readNEXStructure(RankingTypes.RankingCachedResult); - } - - toJSON() { - return { - pResult: { - __typeName: 'RankingCachedResult', - __typeValue: this.pResult - } - }; - } -} - -class GetCachedTopXRankingsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pResults = stream.readNEXList(RankingTypes.RankingCachedResult); - } - - toJSON() { - return { - pResults: { - __typeName: 'List', - __typeValue: this.pResults - } - }; - } -} - -module.exports = { - UploadScoreResponse, - DeleteScoreResponse, - DeleteAllScoresResponse, - UploadCommonDataResponse, - DeleteCommonDataResponse, - GetCommonDataResponse, - ChangeAttributesResponse, - ChangeAllAttributesResponse, - GetRankingResponse, - GetApproxOrderResponse, - GetStatsResponse, - GetRankingByPIDListResponse, - GetRankingByUniqueIdListResponse, - GetCachedTopXRankingResponse, - GetCachedTopXRankingsResponse -}; \ No newline at end of file diff --git a/src/protocols/responses/ranking_legacy.js b/src/protocols/responses/ranking_legacy.js deleted file mode 100644 index fab256d..0000000 --- a/src/protocols/responses/ranking_legacy.js +++ /dev/null @@ -1,190 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const RankingLegacyTypes = require('../types/ranking_legacy'); - -class UploadCommonDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.unknown = stream.readUInt16LE(); - } - - toJSON() { - return { - unknown: { - __typeName: 'uint16', - __typeValue: this.unknown - } - }; - } -} - -class UnknownMethod0xEResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.unknown = stream.readUInt16LE(); - this.rankDataList = stream.readNEXList(RankingLegacyTypes.RankingData); - } - - toJSON() { - return { - unknown: { - __typeName: 'uint16', - __typeValue: this.unknown - }, - rankDataList: { - __typeName: 'List', - __typeValue: this.rankDataList - } - }; - } -} - -class UnknownMethod0xFResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.unknown = stream.readUInt16LE(); - this.rankDataList = stream.readNEXList(RankingLegacyTypes.RankingData); - } - - toJSON() { - return { - unknown: { - __typeName: 'uint16', - __typeValue: this.unknown - }, - rankDataList: { - __typeName: 'List', - __typeValue: this.rankDataList - } - }; - } -} - -class GetTotalResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.unknown = stream.readUInt16LE(); - this.total = stream.readUInt32LE(); - } - - toJSON() { - return { - unknown: { - __typeName: 'uint16', - __typeValue: this.unknown - }, - total: { - __typeName: 'uint32', - __typeValue: this.total - } - }; - } -} - -class UploadScoreWithLimitResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.unknown = stream.readUInt16LE(); - } - - toJSON() { - return { - unknown: { - __typeName: 'uint16', - __typeValue: this.unknown - } - }; - } -} - -class UploadSpecificPeriodScoreResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.unknown = stream.readUInt16LE(); - } - - toJSON() { - return { - unknown: { - __typeName: 'uint16', - __typeValue: this.unknown - } - }; - } -} - -class GetSpecificPeriodDataListResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.unknown = stream.readUInt16LE(); - this.myScore = stream.readUInt32LE(); - this.rankDataList = stream.readNEXList(RankingLegacyTypes.RankingData); - } - - toJSON() { - return { - unknown: { - __typeName: 'uint16', - __typeValue: this.unknown - }, - myScore: { - __typeName: 'uint32', - __typeValue: this.myScore - }, - rankDataList: { - __typeName: 'List', - __typeValue: this.rankDataList - } - }; - } -} - -class GetSpecificPeriodTotalResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.unknown = stream.readUInt16LE(); - this.totalCount = stream.readUInt32LE(); - } - - toJSON() { - return { - unknown: { - __typeName: 'uint16', - __typeValue: this.unknown - }, - totalCount: { - __typeName: 'uint32', - __typeValue: this.totalCount - } - }; - } -} - -module.exports = { - UploadCommonDataResponse, - UnknownMethod0xEResponse, - UnknownMethod0xFResponse, - GetTotalResponse, - UploadScoreWithLimitResponse, - UploadSpecificPeriodScoreResponse, - GetSpecificPeriodDataListResponse, - GetSpecificPeriodTotalResponse -}; diff --git a/src/protocols/responses/ranking_splatoon.js b/src/protocols/responses/ranking_splatoon.js deleted file mode 100644 index 38cbc3c..0000000 --- a/src/protocols/responses/ranking_splatoon.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class GetCompetitionRankingScoreResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetcompetitionRankingScoreByPeriodListResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class UploadCompetitionRankingScoreResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class DeleteCompetitionRankingScoreResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - - -module.exports = { - GetCompetitionRankingScoreResponse, - GetcompetitionRankingScoreByPeriodListResponse, - UploadCompetitionRankingScoreResponse, - DeleteCompetitionRankingScoreResponse -}; \ No newline at end of file diff --git a/src/protocols/responses/secure_connection.js b/src/protocols/responses/secure_connection.js deleted file mode 100644 index 86a8be5..0000000 --- a/src/protocols/responses/secure_connection.js +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); -const SecureConnectionTypes = require('../types/secure_connection'); - -class RegisterResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readUInt32LE(); - this.pidConnectionID = stream.readUInt32LE(); - this.urlPublic = stream.readNEXStationURL(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'Result', - __typeValue: this.retval - }, - pidConnectionID: { - __typeName: 'uint32', - __typeValue: this.pidConnectionID - }, - urlPublic: { - __typeName: 'StationURL', - __typeValue: this.urlPublic - } - }; - } -} - -class RequestConnectionDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - this.pvecConnectionsData = stream.readNEXList(SecureConnectionTypes.ConnectionData); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'Result', - __typeValue: this.retval - }, - pvecConnectionsData: { - __typeName: 'List', - __typeValue: this.pvecConnectionsData - } - }; - } -} - -class RequestUrlsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readBoolean(); - this.plstURLs = stream.readNEXList(NEXTypes.StationURL); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'boolean', - __typeValue: this.retval - }, - plstURLs: { - __typeName: 'List', - __typeValue: this.plstURLs - } - }; - } -} - -class RegisterExResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.retval = stream.readUInt32LE(); - this.pidConnectionID = stream.readUInt32LE(); - this.urlPublic = stream.readNEXStationURL(); - } - - toJSON() { - return { - '%retval%': { - __typeName: 'Result', - __typeValue: this.retval - }, - pidConnectionID: { - __typeName: 'uint32', - __typeValue: this.pidConnectionID - }, - urlPublic: { - __typeName: 'StationURL', - __typeValue: this.urlPublic - } - }; - } -} - -class TestConnectivityResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class UpdateURLsResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class ReplaceURLResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class SendReportResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -module.exports = { - RegisterResponse, - RequestConnectionDataResponse, - RequestUrlsResponse, - RegisterExResponse, - TestConnectivityResponse, - UpdateURLsResponse, - ReplaceURLResponse, - SendReportResponse -}; \ No newline at end of file diff --git a/src/protocols/responses/secure_connection_badge_arcade.js b/src/protocols/responses/secure_connection_badge_arcade.js deleted file mode 100644 index f7490ea..0000000 --- a/src/protocols/responses/secure_connection_badge_arcade.js +++ /dev/null @@ -1,33 +0,0 @@ -const Stream = require('../../stream'); - -class GetMaintenanceStatusResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.maintenanceStatus = stream.readUInt16LE(); - this.maintenanceTime = stream.readUInt32LE(); - this.isSuccess = stream.readBoolean(); - } - - toJSON() { - return { - maintenanceStatus: { - __typeName: 'uint16', - __typeValue: this.maintenanceStatus - }, - maintenanceTime: { - __typeName: 'uint32', - __typeValue: this.maintenanceTime - }, - isSuccess: { - __typeName: 'boolean', - __typeValue: this.isSuccess - } - }; - } -} - -module.exports = { - GetMaintenanceStatusResponse -}; diff --git a/src/protocols/responses/service_item_tkcd.js b/src/protocols/responses/service_item_tkcd.js deleted file mode 100644 index 60f606f..0000000 --- a/src/protocols/responses/service_item_tkcd.js +++ /dev/null @@ -1,426 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const ServiceItemTKCDTypes = require('../types/service_item_tkcd'); - -class GetEnvironmentResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.str = stream.readNEXString(); - } - - toJSON() { - return { - str: { - __typeName: 'String', - __typeValue: this.str - } - }; - } -} - -class HttpGetRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class HttpGetResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.response = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemHttpGetResponse); - } - - toJSON() { - return { - response: { - __typeName: 'ServiceItemHttpGetResponse', - __typeValue: this.response - } - }; - } -} - -class PurchaseServiceItemRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class PurchaseServiceItemResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.purchaseServiceItemResponse = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemPurchaseServiceItemResponse); - } - - toJSON() { - return { - purchaseServiceItemResponse: { - __typeName: 'ServiceItemPurchaseServiceItemResponse', - __typeValue: this.purchaseServiceItemResponse - } - }; - } -} - -class ListServiceItemRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class ListServiceItemResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.listServiceItemResponse = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemListServiceItemResponse); - } - - toJSON() { - return { - listServiceItemResponse: { - __typeName: 'ServiceItemListServiceItemResponse', - __typeValue: this.listServiceItemResponse - } - }; - } -} - -class GetBalanceRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetBalanceResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getBalanceResponse = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemGetBalanceResponse); - } - - toJSON() { - return { - getBalanceResponse: { - __typeName: 'ServiceItemGetBalanceResponse', - __typeValue: this.getBalanceResponse - } - }; - } -} - -class GetPrepurchaseInfoRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetPrepurchaseInfoResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getPrepurchaseInfoResponse = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemGetPrepurchaseInfoResponse); - } - - toJSON() { - return { - getPrepurchaseInfoResponse: { - __typeName: 'ServiceItemGetPrepurchaseInfoResponse', - __typeValue: this.getPrepurchaseInfoResponse - } - }; - } -} - -class GetServiceItemRightRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetServiceItemRightResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getServiceItemRightResponse = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemGetServiceItemRightResponse); - } - - toJSON() { - return { - getServiceItemRightResponse: { - __typeName: 'ServiceItemGetServiceItemRightResponse', - __typeValue: this.getServiceItemRightResponse - } - }; - } -} - -class GetPurchaseHistoryRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetPurchaseHistoryResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getPurchaseHistoryResponse = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemGetPurchaseHistoryResponse); - } - - toJSON() { - return { - getPurchaseHistoryResponse: { - __typeName: 'ServiceItemGetPurchaseHistoryResponse', - __typeValue: this.getPurchaseHistoryResponse - } - }; - } -} - -class PostRightBinaryByAccountResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.postRightBinaryResponse = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemPostRightBinaryResponse); - } - - toJSON() { - return { - postRightBinaryResponse: { - __typeName: 'ServiceItemPostRightBinaryResponse', - __typeValue: this.postRightBinaryResponse - } - }; - } -} - -class UseServiceItemByAccountRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class UseServiceItemByAccountResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.useServiceItemResponse = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemUseServiceItemResponse); - } - - toJSON() { - return { - useServiceItemResponse: { - __typeName: 'ServiceItemUseServiceItemResponse', - __typeValue: this.useServiceItemResponse - } - }; - } -} - -class AcquireServiceItemByAccountResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.acquireServiceItemResponse = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemAcquireServiceItemResponse); - } - - toJSON() { - return { - acquireServiceItemResponse: { - __typeName: 'ServiceItemAcquireServiceItemResponse', - __typeValue: this.acquireServiceItemResponse - } - }; - } -} - -class GetSupportIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.supportId = stream.readNEXString(); - } - - toJSON() { - return { - supportId: { - __typeName: 'String', - __typeValue: this.supportId - } - }; - } -} - -class GetLawMessageRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetLawMessageResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getLawMessageResponse = stream.readNEXStructure(ServiceItemTKCDTypes.ServiceItemGetLawMessageResponse); - } - - toJSON() { - return { - getLawMessageResponse: { - __typeName: 'ServiceItemGetLawMessageResponse', - __typeValue: this.getLawMessageResponse - } - }; - } -} - -module.exports = { - GetEnvironmentResponse, - HttpGetRequestResponse, - HttpGetResponseResponse, - PurchaseServiceItemRequestResponse, - PurchaseServiceItemResponseResponse, - ListServiceItemRequestResponse, - ListServiceItemResponseResponse, - GetBalanceRequestResponse, - GetBalanceResponseResponse, - GetPrepurchaseInfoRequestResponse, - GetPrepurchaseInfoResponseResponse, - GetServiceItemRightRequestResponse, - GetServiceItemRightResponseResponse, - GetPurchaseHistoryRequestResponse, - GetPurchaseHistoryResponseResponse, - PostRightBinaryByAccountResponse, - UseServiceItemByAccountRequestResponse, - UseServiceItemByAccountResponseResponse, - AcquireServiceItemByAccountResponse, - GetSupportIdResponse, - GetLawMessageRequestResponse, - GetLawMessageResponseResponse -}; diff --git a/src/protocols/responses/service_item_wii_sports_club.js b/src/protocols/responses/service_item_wii_sports_club.js deleted file mode 100644 index 0201b2c..0000000 --- a/src/protocols/responses/service_item_wii_sports_club.js +++ /dev/null @@ -1,387 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const ServiceItemWiiSportsClubTypes = require('../types/service_item_wii_sports_club'); - -class HelloResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.str = stream.readNEXString(); - } - - toJSON() { - return { - str: { - __typeName: 'String', - __typeValue: this.str - } - }; - } -} - -class HttpGetRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class HttpGetResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.response = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemHttpGetResponse); - } - - toJSON() { - return { - response: { - __typeName: 'ServiceItemHttpGetResponse', - __typeValue: this.response - } - }; - } -} - -class PurchaseServiceItemRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class PurchaseServiceItemResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.purchaseServiceItemResponse = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemPurchaseServiceItemResponse); - } - - toJSON() { - return { - purchaseServiceItemResponse: { - __typeName: 'ServiceItemPurchaseServiceItemResponse', - __typeValue: this.purchaseServiceItemResponse - } - }; - } -} - -class ListServiceItemRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class ListServiceItemResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.listServiceItemResponse = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemListServiceItemResponse); - } - - toJSON() { - return { - listServiceItemResponse: { - __typeName: 'ServiceItemListServiceItemResponse', - __typeValue: this.listServiceItemResponse - } - }; - } -} - -class GetBalanceRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetBalanceResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getBalanceResponse = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemGetBalanceResponse); - } - - toJSON() { - return { - getBalanceResponse: { - __typeName: 'ServiceItemGetBalanceResponse', - __typeValue: this.getBalanceResponse - } - }; - } -} - -class GetPrepurchaseInfoRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetPrepurchaseInfoResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getPrepurchaseInfoResponse = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemGetPrepurchaseInfoResponse); - } - - toJSON() { - return { - getPrepurchaseInfoResponse: { - __typeName: 'ServiceItemGetPrepurchaseInfoResponse', - __typeValue: this.getPrepurchaseInfoResponse - } - }; - } -} - -class GetServiceItemRightRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetServiceItemRightResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getServiceItemRightResponse = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemGetServiceItemRightResponse); - } - - toJSON() { - return { - getServiceItemRightResponse: { - __typeName: 'ServiceItemGetServiceItemRightResponse', - __typeValue: this.getServiceItemRightResponse - } - }; - } -} - -class GetPurchaseHistoryRequestResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.requestId = stream.readUInt32LE(); - } - - toJSON() { - return { - requestId: { - __typeName: 'uint32', - __typeValue: this.requestId - } - }; - } -} - -class GetPurchaseHistoryResponseResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.getPurchaseHistoryResponse = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemGetPurchaseHistoryResponse); - } - - toJSON() { - return { - getPurchaseHistoryResponse: { - __typeName: 'ServiceItemGetPurchaseHistoryResponse', - __typeValue: this.getPurchaseHistoryResponse - } - }; - } -} - -class GetNoticeResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.notice = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemNotice); - } - - toJSON() { - return { - notice: { - __typeName: 'ServiceItemNotice', - __typeValue: this.notice - } - }; - } -} - -class UpdateAndGetTicketInfoResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.ticketInfos = stream.readNEXList(ServiceItemWiiSportsClubTypes.ServiceItemTicketInfo); - this.events = stream.readNEXList(ServiceItemWiiSportsClubTypes.ServiceItemEvent); - } - - toJSON() { - return { - ticketInfos: { - __typeName: 'List', - __typeValue: this.ticketInfos - }, - events: { - __typeName: 'List', - __typeValue: this.events - } - }; - } -} - -class LoadUserInfoResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.userInfo = stream.readNEXStructure(ServiceItemWiiSportsClubTypes.ServiceItemUserInfo); - } - - toJSON() { - return { - userInfo: { - __typeName: 'ServiceItemUserInfo', - __typeValue: this.userInfo - } - }; - } -} - -class SaveUserInfoResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class StartChallengeResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class EndChallengeResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class RequestTicketRestorationResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -module.exports = { - HelloResponse, - HttpGetRequestResponse, - HttpGetResponseResponse, - PurchaseServiceItemRequestResponse, - PurchaseServiceItemResponseResponse, - ListServiceItemRequestResponse, - ListServiceItemResponseResponse, - GetBalanceRequestResponse, - GetBalanceResponseResponse, - GetPrepurchaseInfoRequestResponse, - GetPrepurchaseInfoResponseResponse, - GetServiceItemRightRequestResponse, - GetServiceItemRightResponseResponse, - GetPurchaseHistoryRequestResponse, - GetPurchaseHistoryResponseResponse, - GetNoticeResponse, - UpdateAndGetTicketInfoResponse, - LoadUserInfoResponse, - SaveUserInfoResponse, - StartChallengeResponse, - EndChallengeResponse, - RequestTicketRestorationResponse -}; diff --git a/src/protocols/responses/shop_badge_arcade.js b/src/protocols/responses/shop_badge_arcade.js deleted file mode 100644 index ae5d578..0000000 --- a/src/protocols/responses/shop_badge_arcade.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class GetRivTokenResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRivToken = stream.readNEXString(); - } - - toJSON() { - return { - pRivToken: { - __typeName: 'String', - __typeValue: this.pRivToken - } - }; - } -} - -class PostPlayLogResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -module.exports = { - GetRivTokenResponse, - PostPlayLogResponse -}; diff --git a/src/protocols/responses/shop_pokemon_bank.js b/src/protocols/responses/shop_pokemon_bank.js deleted file mode 100644 index 5225b91..0000000 --- a/src/protocols/responses/shop_pokemon_bank.js +++ /dev/null @@ -1,187 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const ShopPokemonBankTypes = require('../types/shop_pokemon_bank'); - -class GetItemsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pItems = stream.readNEXList(ShopPokemonBankTypes.ShopItem); - } - - toJSON() { - return { - pItems: { - __typeName: 'List', - __typeValue: this.pItems - } - }; - } -} - -class GetChallengeBlobResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pChallengeBlob = stream.readNEXBuffer(); - } - - toJSON() { - return { - pChallengeBlob: { - __typeName: 'Buffer', - __typeValue: this.pChallengeBlob - } - }; - } -} - -class GetRivTokenResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRivToken = stream.readNEXString(); - } - - toJSON() { - return { - pRivToken: { - __typeName: 'String', - __typeValue: this.pRivToken - } - }; - } -} - -class GetRivTokenByItemIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pRivToken = stream.readNEXString(); - } - - toJSON() { - return { - pRivToken: { - __typeName: 'String', - __typeValue: this.pRivToken - } - }; - } -} - -class GetItemRightsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pItemRights = stream.readNEXList(ShopPokemonBankTypes.ShopItemRights); - } - - toJSON() { - return { - pItemRights: { - __typeName: 'List', - __typeValue: this.pItemRights - } - }; - } -} - -class VerifyAndRegisterTicketResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.expireTime = stream.readNEXDateTime(); - } - - toJSON() { - return { - expireTime: { - __typeName: 'DateTime', - __typeValue: this.expireTime - } - }; - } -} - -class DebugSetExpireTimeResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class PrincipalIDToSupportNumberResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.supportNumber = stream.readNEXString(); - } - - toJSON() { - return { - supportNumber: { - __typeName: 'String', - __typeValue: this.supportNumber - } - }; - } -} - -class SupportNumberToPrincipalIDResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pid = stream.readPID(); - } - - toJSON() { - return { - pid: { - __typeName: 'PID', - __typeValue: this.pid - } - }; - } -} - -class GetGameServerTimeResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pServerTime = stream.readNEXDateTime(); - } - - toJSON() { - return { - pServerTime: { - __typeName: 'DateTime', - __typeValue: this.pServerTime - } - }; - } -} - -module.exports = { - GetItemsResponse, - GetChallengeBlobResponse, - GetRivTokenResponse, - GetRivTokenByItemIdResponse, - GetItemRightsResponse, - VerifyAndRegisterTicketResponse, - DebugSetExpireTimeResponse, - PrincipalIDToSupportNumberResponse, - SupportNumberToPrincipalIDResponse, - GetGameServerTimeResponse -}; diff --git a/src/protocols/responses/storage_manager.js b/src/protocols/responses/storage_manager.js deleted file mode 100644 index da8d9bf..0000000 --- a/src/protocols/responses/storage_manager.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -class AcquireCardIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.cardId = stream.readUInt64LE(); - } - - toJSON() { - return { - cardId: { - __typeName: 'uint64', - __typeValue: this.cardId - } - }; - } -} - -class ActivateWithCardIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.uniqueId = stream.readUInt32LE(); - this.firstTime = stream.readBoolean(); - } - - toJSON() { - return { - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - }, - firstTime: { - __typeName: 'boolean', - __typeValue: this.firstTime - } - }; - } -} - -module.exports = { - AcquireCardIdResponse, - ActivateWithCardIdResponse -}; diff --git a/src/protocols/responses/subscription.js b/src/protocols/responses/subscription.js deleted file mode 100644 index 7ec9c86..0000000 --- a/src/protocols/responses/subscription.js +++ /dev/null @@ -1,363 +0,0 @@ -const Stream = require('../../stream'); - -class CreateMySubscriptionDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class UpdateMySubscriptionDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class ClearMySubscriptionDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class AddTargetResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class DeleteTargetResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class ClearTargetResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetFriendSubscriptionDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetTargetSubscriptionDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetActivePlayerSubscriptionDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetSubscriptionDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class ReplaceTargetAndGetSubscriptionDataResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class SetPrivacyLevelResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetPrivacyLevelResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class GetSubscriptionUserFriendListResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pids = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - pids: { - __typeName: 'pids', - __typeValue: this.pids - } - }; - } -} - -class GetPrivacyLevelsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class CreateMySubscriptionDataWithNotificationParamsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class UnknownMethod17Response { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -class ClearMySubscriptionDataWithNotificationParamsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - // ! This function has an unknown response format - this.unknown = stream.readRest(); - } - - toJSON() { - return { - unknown: { - __typeName: 'unknown', - __typeValue: this.unknown - } - }; - } -} - -module.exports = { - CreateMySubscriptionDataResponse, - UpdateMySubscriptionDataResponse, - ClearMySubscriptionDataResponse, - AddTargetResponse, - DeleteTargetResponse, - ClearTargetResponse, - GetFriendSubscriptionDataResponse, - GetTargetSubscriptionDataResponse, - GetActivePlayerSubscriptionDataResponse, - GetSubscriptionDataResponse, - ReplaceTargetAndGetSubscriptionDataResponse, - SetPrivacyLevelResponse, - GetPrivacyLevelResponse, - GetSubscriptionUserFriendListResponse, - GetPrivacyLevelsResponse, - CreateMySubscriptionDataWithNotificationParamsResponse, - UnknownMethod17Response, - ClearMySubscriptionDataWithNotificationParamsResponse -}; \ No newline at end of file diff --git a/src/protocols/responses/utility.js b/src/protocols/responses/utility.js deleted file mode 100644 index 8a36c24..0000000 --- a/src/protocols/responses/utility.js +++ /dev/null @@ -1,138 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const UtilityTypes = require('../types/utility'); - -class AcquireNexUniqueIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pNexUniqueId = stream.readUInt64LE(); - } - - toJSON() { - return { - pNexUniqueId: { - __typeName: 'uint64', - __typeValue: this.pNexUniqueId - } - }; - } -} - -class AcquireNexUniqueIdWithPasswordResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pNexUniqueIdInfo = stream.readStructure(UtilityTypes.UniqueIdInfo); - } - - toJSON() { - return { - pNexUniqueIdInfo: { - __typeName: 'UniqueIdInfo', - __typeValue: this.pNexUniqueIdInfo - } - }; - } -} - -class AssociateNexUniqueIdWithMyPrincipalIdResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class AssociateNexUniqueIdsWithMyPrincipalIdResponse { - // * Returns nothing - toJSON() { - return {}; - } -} - -class GetAssociatedNexUniqueIdWithMyPrincipalIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pNexUniqueIdInfo = stream.readNEXStructure(UtilityTypes.UniqueIdInfo); - } - - toJSON() { - return { - pNexUniqueIdInfo: { - __typeName: 'UniqueIdInfo', - __typeValue: this.pNexUniqueIdInfo - } - }; - } -} - -class GetAssociatedNexUniqueIdsWithMyPrincipalIdResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.pNexUniqueIdInfo = stream.readNEXList(UtilityTypes.UniqueIdInfo); - } - - toJSON() { - return { - pNexUniqueIdInfo: { - __typeName: 'List', - __typeValue: this.pNexUniqueIdInfo - } - }; - } -} - -class GetIntegerSettingsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.integerSettings = stream.readNEXMap(stream.readUInt16LE, stream.readInt32LE); - } - - toJSON() { - return { - integerSettings: { - __typeName: 'Map', - __typeValue: this.integerSettings - } - }; - } -} - -class GetStringSettingsResponse { - /** - * @param {Stream} stream NEX data stream - */ - constructor(stream) { - this.stringSettings = stream.readNEXMap(stream.readUInt16LE, stream.readNEXString); - } - - toJSON() { - return { - stringSettings: { - __typeName: 'Map', - __typeValue: this.stringSettings - } - }; - } -} - -module.exports = { - AcquireNexUniqueIdResponse, - AcquireNexUniqueIdWithPasswordResponse, - AssociateNexUniqueIdWithMyPrincipalIdResponse, - AssociateNexUniqueIdsWithMyPrincipalIdResponse, - GetAssociatedNexUniqueIdWithMyPrincipalIdResponse, - GetAssociatedNexUniqueIdsWithMyPrincipalIdResponse, - GetIntegerSettingsResponse, - GetStringSettingsResponse -}; diff --git a/src/protocols/secure_connection.js b/src/protocols/secure_connection.js deleted file mode 100644 index 8c09473..0000000 --- a/src/protocols/secure_connection.js +++ /dev/null @@ -1,189 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const SecureConnectionBadgeArcade = require('./patches/secure_connection_badge_arcade'); - -const Requests = require('./requests/secure_connection'); -const Responses = require('./responses/secure_connection'); - -class SecureConnection { - static ProtocolID = 0xB; - - static ProtocolName = 'Secure Connection'; - - static Methods = { - Register: 0x1, - RequestConnectionData: 0x2, - RequestUrls: 0x3, - RegisterEx: 0x4, - TestConnectivity: 0x5, - UpdateURLs: 0x6, - ReplaceURL: 0x7, - SendReport: 0x8 - }; - - static MethodNames = Object.entries(SecureConnection.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x1: SecureConnection.Register, - 0x2: SecureConnection.RequestConnectionData, - 0x3: SecureConnection.RequestUrls, - 0x4: SecureConnection.RegisterEx, - 0x5: SecureConnection.TestConnectivity, - 0x6: SecureConnection.UpdateURLs, - 0x7: SecureConnection.ReplaceURL, - 0x8: SecureConnection.SendReport - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - // Check if method is a Badge Arcade patched method - if (packet.connection.accessKey === '82d5962d' && methodId >= 0x9) { - SecureConnectionBadgeArcade.handlePacket(packet); - return; - } - - const handler = SecureConnection.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown SecureConnection method ID ${methodId} (0x${methodId?.toString(16)}) (${SecureConnection.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static Register(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RegisterRequest(stream); - } else { - return new Responses.RegisterResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RequestConnectionData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RequestConnectionDataRequest(stream); - } else { - return new Responses.RequestConnectionDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RequestUrls(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RequestUrlsRequest(stream); - } else { - return new Responses.RequestUrlsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static RegisterEx(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.RegisterExRequest(stream); - } else { - return new Responses.RegisterExResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @returns {object} Parsed RMC body - */ - static TestConnectivity(rmcMessage) { - if (rmcMessage.isRequest()) { - return new Requests.TestConnectivityRequest(); - } else { - return new Responses.TestConnectivityResponse(); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateURLs(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateURLsRequest(stream); - } else { - return new Responses.UpdateURLsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ReplaceURL(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ReplaceURLRequest(stream); - } else { - return new Responses.ReplaceURLResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SendReport(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SendReportRequest(stream); - } else { - return new Responses.SendReportResponse(stream); - } - } -} - - -module.exports = SecureConnection; diff --git a/src/protocols/service_item.js b/src/protocols/service_item.js deleted file mode 100644 index 3153fc9..0000000 --- a/src/protocols/service_item.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - */ - -const ServiceItemTKCD = require('./patches/service_item_tkcd'); -const ServiceItemWiiSportsClub = require('./patches/service_item_wii_sports_club'); - -// * This protocol has game-specific implementations, -// * so we check what game is using it and redirect -// * the packet to the proper handler. -class ServiceItem { - static ProtocolID = 0x77; - - static ProtocolName = 'Service Item'; - - static MethodNames = {}; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - // Check if game is TKCD - if (packet.connection.accessKey === 'e0c85605') { - ServiceItemTKCD.handlePacket(packet); - return; - } - - // Check if game is Wii Sports Club - if (packet.connection.accessKey === '4d324052') { - ServiceItemWiiSportsClub.handlePacket(packet); - return; - } - - console.log(`Unknown Service Item protocol ID ${ServiceItem.ProtocolID} (0x${ServiceItem.ProtocolID.toString(16)}) used in ${packet.connection.title.name}`); - } -} - -module.exports = ServiceItem; diff --git a/src/protocols/shop.js b/src/protocols/shop.js deleted file mode 100644 index ca4ee5e..0000000 --- a/src/protocols/shop.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - */ - -const ShopBadgeArcade = require('./patches/shop_badge_arcade'); -const ShopPokemonBank = require('./patches/shop_pokemon_bank'); - -// * This protocol has game-specific implementations, -// * so we check what game is using it and redirect -// * the packet to the proper handler. -class Shop { - static ProtocolID = 0xC8; - - static ProtocolName = 'Shop'; - - static MethodNames = {}; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - // Check if game is Badge Arcade - if (packet.connection.accessKey === '82d5962d') { - ShopBadgeArcade.handlePacket(packet); - return; - } - - // Check if game is Pokémon Bank - if (packet.connection.accessKey === '9a2961d8') { - ShopPokemonBank.handlePacket(packet); - return; - } - - console.log(`Unknown Shop protocol ID ${Shop.ProtocolID} (0x${Shop.ProtocolID.toString(16)}) used in ${packet.connection.title.name}`); - } -} - -module.exports = Shop; diff --git a/src/protocols/storage_manager.js b/src/protocols/storage_manager.js deleted file mode 100644 index 9b0209e..0000000 --- a/src/protocols/storage_manager.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const Requests = require('./requests/storage_manager'); -const Responses = require('./responses/storage_manager'); - -// * This is the predecessor of the current Utility protocol. -// * It has been replaced on NEX 3.0.0 with Utility -class StorageManager { - static ProtocolID = 0x6e; - - static ProtocolName = 'Storage Manager'; - - static Methods = { - AcquireCardId: 0x4, - ActivateWithCardId: 0x5 - }; - - static MethodNames = Object.entries(StorageManager.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x4: StorageManager.AcquireCardId, - 0x5: StorageManager.ActivateWithCardId - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = StorageManager.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Storage Manager method ID ${methodId} (0x${methodId?.toString(16)}) (${StorageManager.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - protocolName: this.ProtocolName, - methodName: this.MethodNames[methodId], - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AcquireCardId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AcquireCardIdRequest(stream); - } else { - return new Responses.AcquireCardIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ActivateWithCardId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ActivateWithCardIdRequest(stream); - } else { - return new Responses.ActivateWithCardIdResponse(stream); - } - } -} - -module.exports = StorageManager; diff --git a/src/protocols/subscription.js b/src/protocols/subscription.js deleted file mode 100644 index 8f6a1db..0000000 --- a/src/protocols/subscription.js +++ /dev/null @@ -1,342 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const Stream = require('../stream'); - -const Requests = require('./requests/subscription'); -const Responses = require('./responses/subscription'); - -class Subscription { - static ProtocolID = 0x75; - - static ProtocolName = 'Subscription'; - - static Methods = { - CreateMySubscriptionData: 0x1, - UpdateMySubscriptionData: 0x2, - ClearMySubscriptionData: 0x3, - AddTarget: 0x4, - DeleteTarget: 0x5, - ClearTarget: 0x6, - GetFriendSubscriptionData: 0x7, - GetTargetSubscriptionData: 0x8, - GetActivePlayerSubscriptionData: 0x9, - GetSubscriptionData: 0xA, - ReplaceTargetAndGetSubscriptionData: 0xB, - SetPrivacyLevel: 0xC, - GetPrivacyLevel: 0xD, - GetSubscriptionUserFriendList: 0xE, - GetPrivacyLevels: 0xF, - CreateMySubscriptionDataWithNotificationParams: 0x10, - UnknownMethod17: 0x11, - ClearMySubscriptionDataWithNotificationParams: 0x12 - }; - - static MethodNames = Object.entries(Subscription.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x01: Subscription.CreateMySubscriptionData, - 0x02: Subscription.UpdateMySubscriptionData, - 0x03: Subscription.ClearMySubscriptionData, - 0x04: Subscription.AddTarget, - 0x05: Subscription.DeleteTarget, - 0x06: Subscription.ClearTarget, - 0x07: Subscription.GetFriendSubscriptionData, - 0x08: Subscription.GetTargetSubscriptionData, - 0x09: Subscription.GetActivePlayerSubscriptionData, - 0x0A: Subscription.GetSubscriptionData, - 0x0B: Subscription.ReplaceTargetAndGetSubscriptionData, - 0x0C: Subscription.SetPrivacyLevel, - 0x0D: Subscription.GetPrivacyLevel, - 0x0E: Subscription.GetSubscriptionUserFriendList, - 0x0F: Subscription.GetPrivacyLevels, - 0x10: Subscription.CreateMySubscriptionDataWithNotificationParams, - 0x11: Subscription.UnknownMethod17, - 0x12: Subscription.ClearMySubscriptionDataWithNotificationParams - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const handler = Subscription.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Subscription method ID ${methodId} (0x${methodId?.toString(16)}) (${Subscription.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CreateMySubscriptionData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CreateMySubscriptionDataRequest(stream); - } else { - return new Responses.CreateMySubscriptionDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UpdateMySubscriptionData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UpdateMySubscriptionDataRequest(stream); - } else { - return new Responses.UpdateMySubscriptionDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ClearMySubscriptionData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ClearMySubscriptionDataRequest(stream); - } else { - return new Responses.ClearMySubscriptionDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AddTarget(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AddTargetRequest(stream); - } else { - return new Responses.AddTargetResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static DeleteTarget(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.DeleteTargetRequest(stream); - } else { - return new Responses.DeleteTargetResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ClearTarget(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ClearTargetRequest(stream); - } else { - return new Responses.ClearTargetResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetFriendSubscriptionData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetFriendSubscriptionDataRequest(stream); - } else { - return new Responses.GetFriendSubscriptionDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetTargetSubscriptionData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetTargetSubscriptionDataRequest(stream); - } else { - return new Responses.GetTargetSubscriptionDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetActivePlayerSubscriptionData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetActivePlayerSubscriptionDataRequest(stream); - } else { - return new Responses.GetActivePlayerSubscriptionDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetSubscriptionData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetSubscriptionDataRequest(stream); - } else { - return new Responses.GetSubscriptionDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ReplaceTargetAndGetSubscriptionData(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ReplaceTargetAndGetSubscriptionDataRequest(stream); - } else { - return new Responses.ReplaceTargetAndGetSubscriptionDataResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static SetPrivacyLevel(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.SetPrivacyLevelRequest(stream); - } else { - return new Responses.SetPrivacyLevelResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPrivacyLevel(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPrivacyLevelRequest(stream); - } else { - return new Responses.GetPrivacyLevelResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetSubscriptionUserFriendList(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetSubscriptionUserFriendListRequest(stream); - } else { - return new Responses.GetSubscriptionUserFriendListResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetPrivacyLevels(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetPrivacyLevelsRequest(stream); - } else { - return new Responses.GetPrivacyLevelsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static CreateMySubscriptionDataWithNotificationParams(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.CreateMySubscriptionDataWithNotificationParamsRequest(stream); - } else { - return new Responses.CreateMySubscriptionDataWithNotificationParamsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static UnknownMethod17(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.UnknownMethod17Request(stream); - } else { - return new Responses.UnknownMethod17Response(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static ClearMySubscriptionDataWithNotificationParams(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.ClearMySubscriptionDataWithNotificationParamsRequest(stream); - } else { - return new Responses.ClearMySubscriptionDataWithNotificationParamsResponse(stream); - } - } -} - - -module.exports = Subscription; diff --git a/src/protocols/types/authentication.js b/src/protocols/types/authentication.js deleted file mode 100644 index 4d33c3e..0000000 --- a/src/protocols/types/authentication.js +++ /dev/null @@ -1,181 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class AuthenticationInfo extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_authToken = stream.readNEXString(); - this.m_ngsVersion = stream.readUInt32LE(); - - if (this.m_ngsVersion > 2) { - this.m_authTokenType = stream.readUInt8(); - this.m_serverVersion = stream.readUInt32LE(); - } - } - - toJSON() { - const data = { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_authToken: { - __typeName: 'String', - __typeValue: this.m_authToken - }, - m_ngsVersion: { - __typeName: 'uint32', - __typeValue: this.m_ngsVersion - } - }; - - if (this.m_ngsVersion > 2) { - data.m_authTokenType = { - __typeName: 'uint8', - __typeValue: this.m_authTokenType - }; - - data.m_serverVersion = { - __typeName: 'uint32', - __typeValue: this.m_serverVersion - }; - } - - return data; - } -} -NEXTypes.AnyDataHolder.addType('AuthenticationInfo', AuthenticationInfo); - -class ValidateAndRequestTicketParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.platformType = stream.readUInt32LE(); - this.userName = stream.readNEXString(); - this.extraData = stream.readNEXAnyDataHolder(); - this.ignoreApiVersionCheck = stream.readBoolean(); - this.apiVersionGeneral = stream.readUInt32LE(); - this.apiVersionCustom = stream.readUInt32LE(); - - if (stream.hasDataLeft()) { - this.platformTypeForPlatformPid = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - platformType: { - __typeName: 'uint32', - __typeValue: this.platformType - }, - userName: { - __typeName: 'String', - __typeValue: this.userName - }, - extraData: { - __typeName: 'AnyDataHolder', - __typeValue: this.extraData - }, - ignoreApiVersionCheck: { - __typeName: 'boolean', - __typeValue: this.ignoreApiVersionCheck - }, - apiVersionGeneral: { - __typeName: 'uint32', - __typeValue: this.apiVersionGeneral - }, - apiVersionCustom: { - __typeName: 'uint32', - __typeValue: this.apiVersionCustom - } - }; - - if (this.platformTypeForPlatformPid !== undefined) { - data.platformTypeForPlatformPid = { - __typeName: 'uint8', - __typeValue: this.platformTypeForPlatformPid - }; - } - - return data; - } -} - -class ValidateAndRequestTicketResult extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.sourcePid = stream.readPID(); - this.bufResponse = stream.readNEXBuffer(); - this.serviceNodeUrl = stream.readNEXStationURL(); - this.currentUtcTime = stream.readNEXDateTime(); - this.returnMsg = stream.readNEXString(); - this.sourceKey = stream.readNEXString(); - - if (stream.hasDataLeft()) { - this.platformPid = stream.readPID(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - sourcePid: { - __typeName: 'PID', - __typeValue: this.sourcePid - }, - bufResponse: { - __typeName: 'Buffer', - __typeValue: this.bufResponse - }, - serviceNodeUrl: { - __typeName: 'StationURL', - __typeValue: this.serviceNodeUrl - }, - currentUtcTime: { - __typeName: 'DateTime', - __typeValue: this.currentUtcTime - }, - returnMsg: { - __typeName: 'String', - __typeValue: this.returnMsg - }, - sourceKey: { - __typeName: 'String', - __typeValue: this.sourceKey - } - }; - - if (this.platformPid !== undefined) { - data.platformPid = { - __typeName: 'PID', - __typeValue: this.platformPid - }; - } - - return data; - } -} - -module.exports = { - AuthenticationInfo, - ValidateAndRequestTicketParam, - ValidateAndRequestTicketResult -}; diff --git a/src/protocols/types/datastore.js b/src/protocols/types/datastore.js deleted file mode 100644 index c394f9c..0000000 --- a/src/protocols/types/datastore.js +++ /dev/null @@ -1,1835 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const semver = require('semver'); -const NEXTypes = require('../../types'); - -// ************************** -// * Common DataStore types * -// ************************** - -class DataStoreKeyValue extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.key = stream.readNEXString(); - this.value = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - key: { - __typeName: 'String', - __typeValue: this.key - }, - value: { - __typeName: 'String', - __typeValue: this.value - } - }; - } -} - -class DataStorePermission extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.permission = stream.readUInt8(); - this.recipientIds = stream.readNEXList(stream.readPID); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - permission: { - __typeName: 'uint8', - __typeValue: this.permission - }, - recipientIds: { - __typeName: 'List', - __typeValue: this.recipientIds - } - }; - } -} - -class DataStorePrepareGetParamV1 extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt32LE(); - this.lockId = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint32', - __typeValue: this.dataId - }, - lockId: { - __typeName: 'uint32', - __typeValue: this.lockId - } - }; - } -} - -class DataStoreRatingInitParamWithSlot extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.slot = stream.readInt8(); - this.param = stream.readNEXStructure(DataStoreRatingInitParam); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - slot: { - __typeName: 'sint8', - __typeValue: this.slot - }, - param: { - __typeName: 'DataStoreRatingInitParam', - __typeValue: this.param - } - }; - } -} - -class DataStoreRatingInitParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.flag = stream.readUInt8(); - this.internalFlag = stream.readUInt8(); - this.lockType = stream.readUInt8(); - this.initialValue = stream.readInt64LE(); - this.rangeMin = stream.readInt32LE(); - this.rangeMax = stream.readInt32LE(); - this.periodHour = stream.readUInt8(); - this.periodDuration = stream.readUInt16LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - flag: { - __typeName: 'uint8', - __typeValue: this.flag - }, - internalFlag: { - __typeName: 'uint8', - __typeValue: this.internalFlag - }, - lockType: { - __typeName: 'uint8', - __typeValue: this.lockType - }, - initialValue: { - __typeName: 'sint64', - __typeValue: this.initialValue - }, - rangeMin: { - __typeName: 'sint32', - __typeValue: this.rangeMin - }, - rangeMax: { - __typeName: 'sint32', - __typeValue: this.rangeMax - }, - periodHour: { - __typeName: 'sint8', - __typeValue: this.periodHour - }, - periodDuration: { - __typeName: 'sint16', - __typeValue: this.periodDuration - } - }; - } -} - -class DataStorePersistenceTarget extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.ownerId = stream.readPID(); - this.persistenceSlotId = stream.readUInt16LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - ownerId: { - __typeName: 'PID', - __typeValue: this.ownerId - }, - persistenceSlotId: { - __typeName: 'uint16', - __typeValue: this.persistenceSlotId - } - }; - } -} - -// ***************************** -// * Types specific to methods * -// ***************************** - -class DataStoreReqGetInfoV1 extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.url = stream.readNEXString(); - this.requestHeaders = stream.readNEXList(DataStoreKeyValue); - this.size = stream.readUInt32LE(); - this.rootCaCert = stream.readNEXBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - url: { - __typeName: 'String', - __typeValue: this.url - }, - requestHeaders: { - __typeName: 'List', - __typeValue: this.requestHeaders - }, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - rootCaCert: { - __typeName: 'Buffer', - __typeValue: this.rootCaCert - } - }; - } -} - -class DataStoreReqGetInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - const nexVersion = stream.connection.title.nex_datastore_version || stream.connection.title.nex_version; - - this.url = stream.readNEXString(); - this.requestHeaders = stream.readNEXList(DataStoreKeyValue); - this.size = stream.readUInt32LE(); - this.rootCaCert = stream.readNEXBuffer(); - - if (semver.gte(nexVersion, '3.5.0')) { - this.dataId = stream.readUInt64LE(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - url: { - __typeName: 'String', - __typeValue: this.url - }, - requestHeaders: { - __typeName: 'List', - __typeValue: this.requestHeaders - }, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - rootCaCert: { - __typeName: 'Buffer', - __typeValue: this.rootCaCert - } - }; - - if (this.dataId !== undefined) { - data.dataId = { - __typeName: 'uint64', - __typeValue: this.dataId - }; - } - - return data; - } -} - -class DataStorePreparePostParamV1 extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.size = stream.readUInt32LE(); - this.name = stream.readNEXString(); - this.dataType = stream.readUInt16LE(); - this.metaBinary = stream.readNEXQBuffer(); - this.permission = stream.readNEXStructure(DataStorePermission); - this.delPermission = stream.readNEXStructure(DataStorePermission); - this.flag = stream.readUInt32LE(); - this.period = stream.readUInt16LE(); - this.referDataId = stream.readUInt32LE(); - this.tags = stream.readNEXList(stream.readNEXString); - this.ratingInitParams = stream.readNEXList(DataStoreRatingInitParamWithSlot); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - name: { - __typeName: 'String', - __typeValue: this.name - }, - dataType: { - __typeName: 'uint16', - __typeValue: this.dataType - }, - metaBinary: { - __typeName: 'qBuffer', - __typeValue: this.metaBinary - }, - permission: { - __typeName: 'DataStorePermission', - __typeValue: this.permission - }, - delPermission: { - __typeName: 'DataStorePermission', - __typeValue: this.delPermission - }, - flag: { - __typeName: 'uint32', - __typeValue: this.flag - }, - period: { - __typeName: 'uint16', - __typeValue: this.period - }, - referDataId: { - __typeName: 'uint32', - __typeValue: this.referDataId - }, - tags: { - __typeName: 'List', - __typeValue: this.tags - }, - ratingInitParams: { - __typeName: 'List', - __typeValue: this.ratingInitParams - } - }; - } -} - - -class DataStoreReqPostInfoV1 extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt32LE(); - this.url = stream.readNEXString(); - this.requestHeaders = stream.readNEXList(DataStoreKeyValue); - this.formFields = stream.readNEXList(DataStoreKeyValue); - this.rootCaCert = stream.readNEXBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint32', - __typeValue: this.dataId - }, - url: { - __typeName: 'String', - __typeValue: this.url - }, - requestHeaders: { - __typeName: 'List', - __typeValue: this.requestHeaders - }, - formFields: { - __typeName: 'List', - __typeValue: this.formFields - }, - rootCaCert: { - __typeName: 'Buffer', - __typeValue: this.rootCaCert - } - }; - } -} - -class DataStoreCompletePostParamV1 extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt32LE(); - this.isSuccess = stream.readBoolean(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint32', - __typeValue: this.dataId - }, - isSuccess: { - __typeName: 'boolean', - __typeValue: this.isSuccess - } - }; - } -} - -class DataStoreDeleteParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.updatePassword = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - updatePassword: { - __typeName: 'uint64', - __typeValue: this.updatePassword - } - }; - } -} - -class DataStoreChangeMetaParamV1 extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.modifiesFlag = stream.readUInt32LE(); - this.name = stream.readNEXString(); - this.permission = stream.readNEXStructure(DataStorePermission); - this.delPermission = stream.readNEXStructure(DataStorePermission); - this.period = stream.readUInt16LE(); - this.metaBinary = stream.readNEXQBuffer(); - this.tags = stream.readNEXList(stream.readNEXString); - this.updatePassword = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - modifiesFlag: { - __typeName: 'uint32', - __typeValue: this.modifiesFlag - }, - name: { - __typeName: 'String', - __typeValue: this.name - }, - permission: { - __typeName: 'DataStorePermission', - __typeValue: this.permission - }, - delPermission: { - __typeName: 'DataStorePermission', - __typeValue: this.delPermission - }, - period: { - __typeName: 'uint16', - __typeValue: this.period - }, - metaBinary: { - __typeName: 'qBuffer', - __typeValue: this.metaBinary - }, - tags: { - __typeName: 'List', - __typeValue: this.tags - }, - updatePassword: { - __typeName: 'uint64', - __typeValue: this.updatePassword - } - }; - } -} - -class DataStoreChangeMetaParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.modifiesFlag = stream.readUInt32LE(); - this.name = stream.readNEXString(); - this.permission = stream.readNEXStructure(DataStorePermission); - this.delPermission = stream.readNEXStructure(DataStorePermission); - this.period = stream.readUInt16LE(); - this.metaBinary = stream.readNEXQBuffer(); - this.tags = stream.readNEXList(stream.readNEXString); - this.updatePassword = stream.readUInt64LE(); - this.referredCnt = stream.readUInt32LE(); - this.dataType = stream.readUInt16LE(); - this.status = stream.readUInt8(); - this.compareParam = stream.readNEXStructure(DataStoreChangeMetaCompareParam); - - if (this._structureHeader.version >= 1) { - this.persistenceTarget = stream.readNEXStructure(DataStorePersistenceTarget); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - modifiesFlag: { - __typeName: 'uint32', - __typeValue: this.modifiesFlag - }, - name: { - __typeName: 'String', - __typeValue: this.name - }, - permission: { - __typeName: 'DataStorePermission', - __typeValue: this.permission - }, - delPermission: { - __typeName: 'DataStorePermission', - __typeValue: this.delPermission - }, - period: { - __typeName: 'uint16', - __typeValue: this.period - }, - metaBinary: { - __typeName: 'qBuffer', - __typeValue: this.metaBinary - }, - tags: { - __typeName: 'List', - __typeValue: this.tags - }, - updatePassword: { - __typeName: 'uint64', - __typeValue: this.updatePassword - }, - referredCnt: { - __typeName: 'uint32', - __typeValue: this.referredCnt - }, - dataType: { - __typeName: 'uint16', - __typeValue: this.dataType - }, - status: { - __typeName: 'uint8', - __typeValue: this.status - }, - compareParam: { - __typeName: 'DataStoreChangeMetaCompareParam', - __typeValue: this.compareParam - } - }; - - if (this.persistenceTarget !== undefined) { - data.persistenceTarget = { - __typeName: 'DataStorePersistenceTarget', - __typeValue: this.persistenceTarget - }; - } - - return data; - } -} - -class DataStoreGetMetaParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.persistenceTarget = stream.readNEXStructure(DataStorePersistenceTarget); - this.resultOption = stream.readUInt8(); - this.accessPassword = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - persistenceTarget: { - __typeName: 'DataStorePersistenceTarget', - __typeValue: this.persistenceTarget - }, - resultOption: { - __typeName: 'uint8', - __typeValue: this.resultOption - }, - accessPassword: { - __typeName: 'uint64', - __typeValue: this.accessPassword - } - }; - } -} - -class DataStoreMetaInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.ownerId = stream.readPID(); - this.size = stream.readUInt32LE(); - this.name = stream.readNEXString(); - this.dataType = stream.readUInt16LE(); - this.metaBinary = stream.readNEXQBuffer(); - this.permission = stream.readNEXStructure(DataStorePermission); - this.delPermission = stream.readNEXStructure(DataStorePermission); - this.createdTime = stream.readNEXDateTime(); - this.updatedTime = stream.readNEXDateTime(); - this.period = stream.readUInt16LE(); - this.status = stream.readUInt8(); - this.referredCnt = stream.readUInt32LE(); - this.referDataId = stream.readUInt32LE(); - this.flag = stream.readUInt32LE(); - this.referredTime = stream.readNEXDateTime(); - this.expireTime = stream.readNEXDateTime(); - this.tags = stream.readNEXList(stream.readNEXString); - this.ratings = stream.readNEXList(DataStoreRatingInfoWithSlot); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - ownerId: { - __typeName: 'PID', - __typeValue: this.ownerId - }, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - name: { - __typeName: 'String', - __typeValue: this.name - }, - dataType: { - __typeName: 'uint16', - __typeValue: this.dataType - }, - metaBinary: { - __typeName: 'qBuffer', - __typeValue: this.metaBinary - }, - permission: { - __typeName: 'DataStorePermission', - __typeValue: this.permission - }, - delPermission: { - __typeName: 'DataStorePermission', - __typeValue: this.delPermission - }, - createdTime: { - __typeName: 'DateTime', - __typeValue: this.createdTime - }, - updatedTime: { - __typeName: 'DateTime', - __typeValue: this.updatedTime - }, - period: { - __typeName: 'uint16', - __typeValue: this.period - }, - status: { - __typeName: 'uint8', - __typeValue: this.status - }, - referredCnt: { - __typeName: 'uint32', - __typeValue: this.referredCnt - }, - referDataId: { - __typeName: 'uint32', - __typeValue: this.referDataId - }, - flag: { - __typeName: 'uint32', - __typeValue: this.flag - }, - referredTime: { - __typeName: 'DateTime', - __typeValue: this.referredTime - }, - expireTime: { - __typeName: 'DateTime', - __typeValue: this.expireTime - }, - tags: { - __typeName: 'List', - __typeValue: this.tags - }, - ratings: { - __typeName: 'List', - __typeValue: this.ratings - } - }; - } -} - -class DataStoreRatingInfoWithSlot extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.slot = stream.readInt8(); - this.rating = stream.readNEXStructure(DataStoreRatingInfo); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - slot: { - __typeName: 'sint8', - __typeValue: this.slot - }, - rating: { - __typeName: 'DataStoreRatingInfo', - __typeValue: this.rating - } - }; - } -} - -class DataStoreRatingInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.totalValue = stream.readInt64LE(); - this.count = stream.readUInt32LE(); - this.initialValue = stream.readInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - totalValue: { - __typeName: 'sint64', - __typeValue: this.totalValue - }, - count: { - __typeName: 'uint32', - __typeValue: this.count - }, - initialValue: { - __typeName: 'sint64', - __typeValue: this.initialValue - } - }; - } -} - -class DataStorePrepareUpdateParam extends NEXTypes.Structure { - #dataIdType; - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - const nexVersion = stream.connection.title.nex_datastore_version || stream.connection.title.nex_version; - - if (semver.gte(nexVersion, '3.0.0')) { - this.dataId = stream.readUInt64LE(); - - // * Hack to get the proper type when encoding to JSON - this.#dataIdType = 'uint64'; - } else { - this.dataId = stream.readUInt32LE(); - this.#dataIdType = 'uint32'; - } - - this.size = stream.readUInt32LE(); - - if (semver.gte(nexVersion, '3.0.0')) { - this.updatePassword = stream.readUInt64LE(); - } - - if (semver.gte(nexVersion, '3.5.0')) { - this.extraData = stream.readNEXList(stream.readNEXString); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: this.#dataIdType, - __typeValue: this.dataId - }, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - }; - - if (this.updatePassword !== undefined) { - data.updatePassword = { - __typeName: 'uint64', - __typeValue: this.updatePassword - }; - } - - if (this.extraData !== undefined) { - data.extraData = { - __typeName: 'List', - __typeValue: this.extraData - }; - } - - return data; - } -} - -class DataStoreReqUpdateInfo extends NEXTypes.Structure { - #versionType; - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - const nexVersion = stream.connection.title.nex_datastore_version || stream.connection.title.nex_version; - - if (semver.gte(nexVersion, '3.5.0')) { - this.version = stream.readUInt32LE(); - - // * Hack to get the proper type when encoding to JSON - this.#versionType = 'uint32'; - } else { - this.version = stream.readUInt16LE(); - this.#versionType = 'uint16'; - } - - this.url = stream.readNEXString(); - this.requestHeaders = stream.readNEXList(DataStoreKeyValue); - this.formFields = stream.readNEXList(DataStoreKeyValue); - this.rootCaCert = stream.readNEXBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - version: { - __typeName: this.#versionType, - __typeValue: this.version - }, - url: { - __typeName: 'String', - __typeValue: this.url - }, - requestHeaders: { - __typeName: 'List', - __typeValue: this.requestHeaders - }, - formFields: { - __typeName: 'List', - __typeValue: this.formFields - }, - rootCaCert: { - __typeName: 'Buffer', - __typeValue: this.rootCaCert - } - }; - } -} - -class DataStoreCompleteUpdateParam extends NEXTypes.Structure { - #dataIdType; - #versionType; - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - const nexVersion = stream.connection.title.nex_datastore_version || stream.connection.title.nex_version; - - if (semver.gte(nexVersion, '3.5.0')) { - this.dataId = stream.readUInt64LE(); - - // * Hack to get the proper type when encoding to JSON - this.#dataIdType = 'uint64'; - } else { - this.dataId = stream.readUInt32LE(); - this.#dataIdType = 'uint32'; - } - - if (semver.gte(nexVersion, '3.5.0')) { - this.version = stream.readUInt32LE(); - this.#versionType = 'uint32'; - } else { - this.version = stream.readUInt16LE(); - this.#versionType = 'uint16'; - } - - this.isSuccess = stream.readBoolean(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: this.#dataIdType, - __typeValue: this.dataId - }, - version: { - __typeName: this.#versionType, - __typeValue: this.version - }, - isSuccess: { - __typeName: 'boolean', - __typeValue: this.isSuccess - } - }; - } -} - -class DataStoreSearchParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.searchTarget = stream.readUInt8(); - this.ownerIds = stream.readNEXList(stream.readPID); - this.ownerType = stream.readUInt8(); - this.destinationIds = stream.readNEXList(stream.readInt64LE); - this.dataType = stream.readUInt16LE(); - this.createdAfter = stream.readNEXDateTime(); - this.createdBefore = stream.readNEXDateTime(); - this.updatedAfter = stream.readNEXDateTime(); - this.updatedBefore = stream.readNEXDateTime(); - this.referDataId = stream.readUInt32LE(); - this.tags = stream.readNEXList(stream.readNEXString); - this.resultOrderColumn = stream.readUInt8(); - this.resultOrder = stream.readUInt8(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - this.resultOption = stream.readUInt8(); - this.minimalRatingFrequency = stream.readUInt32LE(); - - if (this._structureHeader.version >= 1) { - this.useCache = stream.readBoolean(); - } - - if (this._structureHeader.version >= 3) { - this.totalCountEnabled = stream.readBoolean(); - } - - if (this._structureHeader.version >= 2) { - this.dataTypes = stream.readNEXList(stream.readUInt16LE); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - searchTarget: { - __typeName: 'uint8', - __typeValue: this.searchTarget - }, - ownerIds: { - __typeName: 'List', - __typeValue: this.ownerIds - }, - ownerType: { - __typeName: 'uint8', - __typeValue: this.ownerType - }, - destinationIds: { - __typeName: 'List', - __typeValue: this.destinationIds - }, - dataType: { - __typeName: 'uint16', - __typeValue: this.dataType - }, - createdAfter: { - __typeName: 'DateTime', - __typeValue: this.createdAfter - }, - createdBefore: { - __typeName: 'DateTime', - __typeValue: this.createdBefore - }, - updatedAfter: { - __typeName: 'DateTime', - __typeValue: this.updatedAfter - }, - updatedBefore: { - __typeName: 'DateTime', - __typeValue: this.updatedBefore - }, - referDataId: { - __typeName: 'uint32', - __typeValue: this.referDataId - }, - tags: { - __typeName: 'List', - __typeValue: this.tags - }, - resultOrderColumn: { - __typeName: 'uint8', - __typeValue: this.resultOrderColumn - }, - resultOrder: { - __typeName: 'uint8', - __typeValue: this.resultOrder - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - }, - resultOption: { - __typeName: 'uint8', - __typeValue: this.resultOption - }, - minimalRatingFrequency: { - __typeName: 'uint32', - __typeValue: this.minimalRatingFrequency - } - }; - - if (this.useCache !== undefined) { - data.useCache = { - __typeName: 'boolean', - __typeValue: this.useCache - }; - } - - if (this.totalCountEnabled !== undefined) { - data.totalCountEnabled = { - __typeName: 'boolean', - __typeValue: this.totalCountEnabled - }; - } - - if (this.dataTypes !== undefined) { - data.dataTypes = { - __typeName: 'List', - __typeValue: this.dataTypes - }; - } - - return data; - } -} - -class DataStoreSearchResult extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.totalCount = stream.readUInt32LE(); - this.result = stream.readNEXList(DataStoreMetaInfo); - this.totalCountType = stream.readUInt8(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - totalCount: { - __typeName: 'uint32', - __typeValue: this.totalCount - }, - result: { - __typeName: 'List', - __typeValue: this.result - }, - totalCountType: { - __typeName: 'uint8', - __typeValue: this.totalCountType - } - }; - } -} - -class DataStoreGetNotificationUrlParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.previousUrl = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - previousUrl: { - __typeName: 'String', - __typeValue: this.previousUrl - } - }; - } -} - -class DataStoreReqGetNotificationUrlInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.url = stream.readNEXString(); - this.key = stream.readNEXString(); - this.query = stream.readNEXString(); - this.rootCaCert = stream.readNEXBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - url: { - __typeName: 'String', - __typeValue: this.url - }, - key: { - __typeName: 'String', - __typeValue: this.key - }, - query: { - __typeName: 'String', - __typeValue: this.query - }, - rootCaCert: { - __typeName: 'Buffer', - __typeValue: this.rootCaCert - } - }; - } -} - -class DataStoreGetNewArrivedNotificationsParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.lastNotificationId = stream.readUInt64LE(); - this.limit = stream.readUInt16LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - lastNotificationId: { - __typeName: 'uint64', - __typeValue: this.lastNotificationId - }, - limit: { - __typeName: 'uint16', - __typeValue: this.limit - } - }; - } -} - -class DataStoreNotificationV1 extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.notificationId = stream.readUInt64LE(); - this.dataId = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - notificationId: { - __typeName: 'uint64', - __typeValue: this.notificationId - }, - dataId: { - __typeName: 'uint32', - __typeValue: this.dataId - } - }; - } -} - -class DataStoreRatingTarget extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.slot = stream.readInt8(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - slot: { - __typeName: 'sint8', - __typeValue: this.slot - } - }; - } -} - -class DataStoreRateObjectParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.ratingValue = stream.readInt32LE(); - this.accessPassword = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - ratingValue: { - __typeName: 'sint32', - __typeValue: this.ratingValue - }, - accessPassword: { - __typeName: 'uint64', - __typeValue: this.accessPassword - } - }; - } -} - - -class DataStoreGetSpecificMetaParamV1 extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataIds = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataIds: { - __typeName: 'List', - __typeValue: this.dataIds - } - }; - } -} - -class DataStoreSpecificMetaInfoV1 extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt32LE(); - this.ownerId = stream.readPID(); - this.size = stream.readUInt32LE(); - this.dataType = stream.readUInt16LE(); - this.version = stream.readUInt16LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint32', - __typeValue: this.dataId - }, - ownerId: { - __typeName: 'PID', - __typeValue: this.ownerId - }, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - dataType: { - __typeName: 'uint16', - __typeValue: this.dataType - }, - version: { - __typeName: 'uint16', - __typeValue: this.version - } - }; - } -} - -class DataStoreTouchObjectParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.lockId = stream.readUInt32LE(); - this.accessPassword = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - lockId: { - __typeName: 'uint32', - __typeValue: this.lockId - }, - accessPassword: { - __typeName: 'uint64', - __typeValue: this.accessPassword - } - }; - } -} - -class DataStoreRatingLog extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.isRated = stream.readBoolean(); - this.pid = stream.readPID(); - this.ratingValue = stream.readInt32LE(); - this.lockExpirationTime = stream.readNEXDateTime(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - isRated: { - __typeName: 'boolean', - __typeValue: this.isRated - }, - pid: { - __typeName: 'PID', - __typeValue: this.pid - }, - ratingValue: { - __typeName: 'sint32', - __typeValue: this.ratingValue - }, - lockExpirationTime: { - __typeName: 'DateTime', - __typeValue: this.lockExpirationTime - } - }; - } -} - -class DataStorePersistenceInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.ownerId = stream.readPID(); - this.persistenceSlotId = stream.readUInt16LE(); - this.dataId = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - ownerId: { - __typeName: 'PID', - __typeValue: this.ownerId - }, - persistenceSlotId: { - __typeName: 'uint16', - __typeValue: this.persistenceSlotId - }, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - } - }; - } -} - -class DataStoreReqGetAdditionalMeta extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.ownerId = stream.readPID(); - this.dataType = stream.readUInt16LE(); - this.version = stream.readUInt16LE(); - this.metaBinary = stream.readNEXQBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - ownerId: { - __typeName: 'PID', - __typeValue: this.ownerId - }, - dataType: { - __typeName: 'uint16', - __typeValue: this.dataType - }, - version: { - __typeName: 'uint16', - __typeValue: this.version - }, - metaBinary: { - __typeName: 'qBuffer', - __typeValue: this.metaBinary - } - }; - } -} - -class DataStorePasswordInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.accessPassword = stream.readUInt64LE(); - this.updatePassword = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - accessPassword: { - __typeName: 'uint64', - __typeValue: this.accessPassword - }, - updatePassword: { - __typeName: 'uint64', - __typeValue: this.updatePassword - } - }; - } -} - -class DataStorePrepareGetParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - const nexVersion = stream.connection.title.nex_datastore_version || stream.connection.title.nex_version; - - this.dataId = stream.readUInt64LE(); - this.lockId = stream.readUInt32LE(); - this.persistenceTarget = stream.readNEXStructure(DataStorePersistenceTarget); - this.accessPassword = stream.readUInt64LE(); - - if (semver.gte(nexVersion, '3.5.0')) { - this.extraData = stream.readNEXList(stream.readNEXString); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - lockId: { - __typeName: 'uint32', - __typeValue: this.lockId - }, - persistenceTarget: { - __typeName: 'DataStorePersistenceTarget', - __typeValue: this.persistenceTarget - }, - accessPassword: { - __typeName: 'uint64', - __typeValue: this.accessPassword - } - }; - - if (this.extraData !== undefined) { - data.extraData = { - __typeName: 'List', - __typeValue: this.extraData - }; - } - - return data; - } -} - -class DataStorePreparePostParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - const nexVersion = stream.connection.title.nex_datastore_version || stream.connection.title.nex_version; - - this.size = stream.readUInt32LE(); - this.name = stream.readNEXString(); - this.dataType = stream.readUInt16LE(); - this.metaBinary = stream.readNEXQBuffer(); - this.permission = stream.readNEXStructure(DataStorePermission); - this.delPermission = stream.readNEXStructure(DataStorePermission); - this.flag = stream.readUInt32LE(); - this.period = stream.readUInt16LE(); - this.referDataId = stream.readUInt32LE(); - this.tags = stream.readNEXList(stream.readNEXString); - this.ratingInitParams = stream.readNEXList(DataStoreRatingInitParamWithSlot); - this.persistenceInitParam = stream.readNEXStructure(DataStorePersistenceInitParam); - - if (semver.gte(nexVersion, '3.5.0')) { - this.extraData = stream.readNEXList(stream.readNEXString); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - name: { - __typeName: 'String', - __typeValue: this.name - }, - dataType: { - __typeName: 'uint16', - __typeValue: this.dataType - }, - metaBinary: { - __typeName: 'qBuffer', - __typeValue: this.metaBinary - }, - permission: { - __typeName: 'DataStorePermission', - __typeValue: this.permission - }, - delPermission: { - __typeName: 'DataStorePermission', - __typeValue: this.delPermission - }, - flag: { - __typeName: 'uint32', - __typeValue: this.flag - }, - period: { - __typeName: 'uint16', - __typeValue: this.period - }, - referDataId: { - __typeName: 'uint32', - __typeValue: this.referDataId - }, - tags: { - __typeName: 'List', - __typeValue: this.tags - }, - ratingInitParams: { - __typeName: 'List', - __typeValue: this.ratingInitParams - }, - persistenceInitParam: { - __typeName: 'DataStorePersistenceInitParam', - __typeValue: this.persistenceInitParam - } - }; - - if (this.extraData !== undefined) { - data.extraData = { - __typeName: 'List', - __typeValue: this.extraData - }; - } - - return data; - } -} - -class DataStorePersistenceInitParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.persistenceSlotId = stream.readUInt16LE(); - this.deleteLastObject = stream.readBoolean(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - persistenceSlotId: { - __typeName: 'uint16', - __typeValue: this.persistenceSlotId - }, - deleteLastObject: { - __typeName: 'boolean', - __typeValue: this.deleteLastObject - } - }; - } -} - -class DataStoreReqPostInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.url = stream.readNEXString(); - this.requestHeaders = stream.readNEXList(DataStoreKeyValue); - this.formFields = stream.readNEXList(DataStoreKeyValue); - this.rootCaCert = stream.readNEXBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - url: { - __typeName: 'String', - __typeValue: this.url - }, - requestHeaders: { - __typeName: 'List', - __typeValue: this.requestHeaders - }, - formFields: { - __typeName: 'List', - __typeValue: this.formFields - }, - rootCaCert: { - __typeName: 'Buffer', - __typeValue: this.rootCaCert - } - }; - } -} - -class DataStoreCompletePostParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.isSuccess = stream.readBoolean(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - isSuccess: { - __typeName: 'boolean', - __typeValue: this.isSuccess - } - }; - } -} - -class DataStoreChangeMetaCompareParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.comparisonFlag = stream.readUInt32LE(); - this.name = stream.readNEXString(); - this.permission = stream.readNEXStructure(DataStorePermission); - this.delPermission = stream.readNEXStructure(DataStorePermission); - this.period = stream.readUInt16LE(); - this.metaBinary = stream.readNEXQBuffer(); - this.tags = stream.readNEXList(stream.readNEXString); - this.referredCnt = stream.readUInt32LE(); - this.dataType = stream.readUInt16LE(); - this.status = stream.readUInt8(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - comparisonFlag: { - __typeName: 'uint32', - __typeValue: this.comparisonFlag - }, - name: { - __typeName: 'String', - __typeValue: this.name - }, - permission: { - __typeName: 'DataStorePermission', - __typeValue: this.permission - }, - delPermission: { - __typeName: 'DataStorePermission', - __typeValue: this.delPermission - }, - period: { - __typeName: 'uint16', - __typeValue: this.period - }, - metaBinary: { - __typeName: 'qBuffer', - __typeValue: this.metaBinary - }, - tags: { - __typeName: 'List', - __typeValue: this.tags - }, - referredCnt: { - __typeName: 'uint32', - __typeValue: this.referredCnt - }, - dataType: { - __typeName: 'uint16', - __typeValue: this.dataType - }, - status: { - __typeName: 'uint8', - __typeValue: this.status - } - }; - } -} - -module.exports = { - DataStoreKeyValue, - DataStorePermission, - DataStorePrepareGetParamV1, - DataStoreRatingInitParamWithSlot, - DataStoreRatingInitParam, - DataStorePersistenceTarget, - DataStoreReqGetInfoV1, - DataStoreReqGetInfo, - DataStorePreparePostParamV1, - DataStoreReqPostInfoV1, - DataStoreCompletePostParamV1, - DataStoreDeleteParam, - DataStoreChangeMetaParamV1, - DataStoreChangeMetaParam, - DataStoreGetMetaParam, - DataStoreMetaInfo, - DataStoreRatingInfoWithSlot, - DataStoreRatingInfo, - DataStorePrepareUpdateParam, - DataStoreReqUpdateInfo, - DataStoreCompleteUpdateParam, - DataStoreSearchParam, - DataStoreSearchResult, - DataStoreGetNotificationUrlParam, - DataStoreReqGetNotificationUrlInfo, - DataStoreGetNewArrivedNotificationsParam, - DataStoreNotificationV1, - DataStoreRatingTarget, - DataStoreRateObjectParam, - DataStoreGetSpecificMetaParamV1, - DataStoreSpecificMetaInfoV1, - DataStoreTouchObjectParam, - DataStoreRatingLog, - DataStorePersistenceInfo, - DataStoreReqGetAdditionalMeta, - DataStorePasswordInfo, - DataStorePrepareGetParam, - DataStorePreparePostParam, - DataStorePersistenceInitParam, - DataStoreReqPostInfo, - DataStoreCompletePostParam, - DataStoreChangeMetaCompareParam -}; diff --git a/src/protocols/types/datastore_badge_arcade.js b/src/protocols/types/datastore_badge_arcade.js deleted file mode 100644 index 07625d9..0000000 --- a/src/protocols/types/datastore_badge_arcade.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class DataStoreGetMetaByOwnerIdParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.ownerIds = stream.readNEXList(stream.readUInt32LE); - this.dataTypes = stream.readNEXList(stream.readUInt16LE); - this.resultOption = stream.readUInt8(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - ownerIds: { - __typeName: 'List', - __typeValue: this.ownerIds - }, - dataTypes: { - __typeName: 'List', - __typeValue: this.dataTypes - }, - resultOption: { - __typeName: 'uint8', - __typeValue: this.resultOption - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -module.exports = { - DataStoreGetMetaByOwnerIdParam -}; diff --git a/src/protocols/types/datastore_pokemon_bank.js b/src/protocols/types/datastore_pokemon_bank.js deleted file mode 100644 index 87601ba..0000000 --- a/src/protocols/types/datastore_pokemon_bank.js +++ /dev/null @@ -1,549 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class GlobalTradeStationRecordKey extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.password = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - password: { - __typeName: 'uint64', - __typeValue: this.password - } - }; - } -} - -class GlobalTradeStationUploadPokemonParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.prepareUploadKey = stream.readNEXStructure(GlobalTradeStationRecordKey); - this.period = stream.readUInt16LE(); - this.indexData = stream.readNEXQBuffer(); - this.pokemonData = stream.readNEXQBuffer(); - this.signature = stream.readNEXQBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - prepareUploadKey: { - __typeName: 'GlobalTradeStationRecordKey', - __typeValue: this.prepareUploadKey - }, - period: { - __typeName: 'uint16', - __typeValue: this.period - }, - indexData: { - __typeName: 'qBuffer', - __typeValue: this.indexData - }, - pokemonData: { - __typeName: 'qBuffer', - __typeValue: this.pokemonData - }, - signature: { - __typeName: 'qBuffer', - __typeValue: this.signature - } - }; - } -} - -class GlobalTradeStationSearchPokemonParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.prepareUploadKey = stream.readNEXStructure(GlobalTradeStationRecordKey); - this.conditions = stream.readNEXList(stream.readUInt32); - this.resultOrderColumn = stream.readUInt8(); - this.resultOrder = stream.readUInt8(); - this.uploadedAfter = stream.readNEXDateTime(); - this.uploadedBefore = stream.readNEXDateTime(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - prepareUploadKey: { - __typeName: 'GlobalTradeStationRecordKey', - __typeValue: this.prepareUploadKey - }, - conditions: { - __typeName: 'List', - __typeValue: this.conditions - }, - resultOrderColumn: { - __typeName: 'uint8', - __typeValue: this.resultOrderColumn - }, - resultOrder: { - __typeName: 'uint8', - __typeValue: this.resultOrder - }, - uploadedAfter: { - __typeName: 'DateTime', - __typeValue: this.uploadedAfter - }, - uploadedBefore: { - __typeName: 'DateTime', - __typeValue: this.uploadedBefore - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class GlobalTradeStationTradeKey extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.version = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - version: { - __typeName: 'uint32', - __typeValue: this.version - } - }; - } -} - -class GlobalTradeStationData extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.ownerId = stream.readPID(); - this.uploadedTime = stream.readNEXDateTime(); - this.indexData = stream.readNEXQBuffer(); - this.version = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - ownerId: { - __typeName: 'PID', - __typeValue: this.ownerId - }, - uploadedTime: { - __typeName: 'DateTime', - __typeValue: this.uploadedTime - }, - indexData: { - __typeName: 'qBuffer', - __typeValue: this.indexData - }, - version: { - __typeName: 'uint32', - __typeValue: this.version - } - }; - } -} - -class GlobalTradeStationSearchPokemonResult extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.totalCount = stream.readUInt32LE(); - this.result = stream.readNEXList(GlobalTradeStationData); - this.totalCountType = stream.readUInt8(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - totalCount: { - __typeName: 'uint32', - __typeValue: this.totalCount - }, - result: { - __typeName: 'List', - __typeValue: this.result - }, - totalCountType: { - __typeName: 'uint8', - __typeValue: this.totalCountType - } - }; - } -} - -class GlobalTradeStationTradePokemonParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.tradeKey = stream.readNEXStructure(GlobalTradeStationTradeKey); - this.prepareTradeKey = stream.readNEXStructure(GlobalTradeStationRecordKey); - this.prepareUploadKey = stream.readNEXStructure(GlobalTradeStationRecordKey); - this.period = stream.readUInt16LE(); - this.indexData = stream.readNEXQBuffer(); - this.pokemonData = stream.readNEXQBuffer(); - this.signature = stream.readNEXQBuffer(); - this.needData = stream.readBoolean(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - tradeKey: { - __typeName: 'GlobalTradeStationTradeKey', - __typeValue: this.tradeKey - }, - prepareTradeKey: { - __typeName: 'GlobalTradeStationRecordKey', - __typeValue: this.prepareTradeKey - }, - prepareUploadKey: { - __typeName: 'GlobalTradeStationRecordKey', - __typeValue: this.prepareUploadKey - }, - period: { - __typeName: 'uint16', - __typeValue: this.period - }, - indexData: { - __typeName: 'qBuffer', - __typeValue: this.indexData - }, - pokemonData: { - __typeName: 'qBuffer', - __typeValue: this.pokemonData - }, - signature: { - __typeName: 'qBuffer', - __typeValue: this.signature - }, - needData: { - __typeName: 'boolean', - __typeValue: this.needData - } - }; - } -} - -class GlobalTradeStationDownloadOtherPokemonParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.prepareUploadKey = stream.readNEXStructure(GlobalTradeStationRecordKey); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - prepareUploadKey: { - __typeName: 'GlobalTradeStationRecordKey', - __typeValue: this.prepareUploadKey - } - }; - } -} - -class GlobalTradeStationDownloadMyPokemonParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.prepareUploadKey = stream.readNEXStructure(GlobalTradeStationRecordKey); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - prepareUploadKey: { - __typeName: 'GlobalTradeStationRecordKey', - __typeValue: this.prepareUploadKey - } - }; - } -} - -class GlobalTradeStationTradePokemonResult extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.result = stream.readNEXStructure(GlobalTradeStationDownloadPokemonResult); - this.myDataId = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - result: { - __typeName: 'GlobalTradeStationDownloadPokemonResult', - __typeValue: this.result - }, - myDataId: { - __typeName: 'uint64', - __typeValue: this.myDataId - } - }; - } -} - -class GlobalTradeStationDownloadMyPokemonResult extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.result = stream.readNEXStructure(GlobalTradeStationDownloadPokemonResult); - this.isTraded = stream.readBoolean(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - result: { - __typeName: 'GlobalTradeStationDownloadPokemonResult', - __typeValue: this.result - }, - isTraded: { - __typeName: 'boolean', - __typeValue: this.isTraded - } - }; - } -} - -class GlobalTradeStationPrepareTradePokemonParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.tradeKey = stream.readNEXStructure(GlobalTradeStationTradeKey); - this.prepareUploadKey = stream.readNEXStructure(GlobalTradeStationRecordKey); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - tradeKey: { - __typeName: 'GlobalTradeStationTradeKey', - __typeValue: this.tradeKey - }, - prepareUploadKey: { - __typeName: 'GlobalTradeStationRecordKey', - __typeValue: this.prepareUploadKey - } - }; - } -} - -class GlobalTradeStationPrepareTradePokemonResult extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.result = stream.readNEXStructure(GlobalTradeStationDownloadPokemonResult); - this.prepareTradeKey = stream.readNEXStructure(GlobalTradeStationRecordKey); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - result: { - __typeName: 'GlobalTradeStationDownloadPokemonResult', - __typeValue: this.result - }, - prepareUploadKey: { - __typeName: 'GlobalTradeStationRecordKey', - __typeValue: this.prepareTradeKey - } - }; - } -} - -class GlobalTradeStationDeletePokemonParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.prepareUploadKey = stream.readNEXStructure(GlobalTradeStationRecordKey); - this.deleteFlag = stream.readUInt8(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - prepareUploadKey: { - __typeName: 'GlobalTradeStationRecordKey', - __typeValue: this.prepareUploadKey - }, - deleteFlag: { - __typeName: 'uint8', - __typeValue: this.deleteFlag - } - }; - } -} - -class GlobalTradeStationDownloadPokemonResult extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.indexData = stream.readNEXQBuffer(); - this.pokemonData = stream.readNEXQBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - indexData: { - __typeName: 'qBuffer', - __typeValue: this.indexData - }, - pokemonData: { - __typeName: 'qBuffer', - __typeValue: this.pokemonData - } - }; - } -} - -class BankTransactionParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.curVersion = stream.readUInt32LE(); - this.updateVersion = stream.readUInt32LE(); - this.size = stream.readUInt32LE(); - this.transactionPassword = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - curVersion: { - __typeName: 'uint32', - __typeValue: this.curVersion - }, - updateVersion: { - __typeName: 'uint32', - __typeValue: this.updateVersion - }, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - transactionPassword: { - __typeName: 'uint64', - __typeValue: this.transactionPassword - } - }; - } -} - -class BankMigrationInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.migrationStatus = stream.readUInt32LE(); - this.updatedTime = stream.readNEXDateTime(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - migrationStatus: { - __typeName: 'uint32', - __typeValue: this.migrationStatus - }, - updatedTime: { - __typeName: 'DateTime', - __typeValue: this.updatedTime - } - }; - } -} - -module.exports = { - GlobalTradeStationRecordKey, - GlobalTradeStationUploadPokemonParam, - GlobalTradeStationSearchPokemonParam, - GlobalTradeStationTradeKey, - GlobalTradeStationData, - GlobalTradeStationSearchPokemonResult, - GlobalTradeStationTradePokemonParam, - GlobalTradeStationDownloadOtherPokemonParam, - GlobalTradeStationDownloadMyPokemonParam, - GlobalTradeStationTradePokemonResult, - GlobalTradeStationDownloadMyPokemonResult, - GlobalTradeStationPrepareTradePokemonParam, - GlobalTradeStationPrepareTradePokemonResult, - GlobalTradeStationDeletePokemonParam, - GlobalTradeStationDownloadPokemonResult, - BankTransactionParam, - BankMigrationInfo -}; diff --git a/src/protocols/types/datastore_smm.js b/src/protocols/types/datastore_smm.js deleted file mode 100644 index a87c47e..0000000 --- a/src/protocols/types/datastore_smm.js +++ /dev/null @@ -1,463 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -const DataStoreTypes = require('./datastore'); - -class DataStoreFileServerObjectInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.getInfo = stream.readNEXStructure(DataStoreTypes.DataStoreReqGetInfo); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - getInfo: { - __typeName: 'DataStoreReqGetInfo', - __typeValue: this.getInfo - } - }; - } -} - -class DataStoreGetMetaByOwnerIdParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.ownerIds = stream.readNEXList(stream.readUInt32LE); - this.dataTypes = stream.readNEXList(stream.readUInt16LE); - this.resultOption = stream.readUInt8(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - ownerIds: { - __typeName: 'List', - __typeValue: this.ownerIds - }, - dataTypes: { - __typeName: 'List', - __typeValue: this.dataTypes - }, - resultOption: { - __typeName: 'uint8', - __typeValue: this.resultOption - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class DataStoreRateCustomRankingParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.applicationId = stream.readUInt32LE(); - this.score = stream.readUInt32LE(); - this.period = stream.readUInt16LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - applicationId: { - __typeName: 'uint32', - __typeValue: this.applicationId - }, - score: { - __typeName: 'uint32', - __typeValue: this.score - }, - period: { - __typeName: 'uint16', - __typeValue: this.period - } - }; - } -} - -class DataStoreGetCustomRankingParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.applicationId = stream.readUInt32LE(); - this.condition = stream.readNEXStructure(DataStoreCustomRankingRatingCondition); - this.resultOption = stream.readUInt8(); - this.resultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - applicationId: { - __typeName: 'uint32', - __typeValue: this.applicationId - }, - condition: { - __typeName: 'DataStoreCustomRankingRatingCondition', - __typeValue: this.condition - }, - resultOption: { - __typeName: 'uint8', - __typeValue: this.resultOption - }, - resultRange: { - __typeName: 'ResultRange', - __typeValue: this.resultRange - } - }; - } -} - -class DataStoreCustomRankingRatingCondition extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.slot = stream.readInt8(); - this.minValue = stream.readInt32LE(); - this.maxValue = stream.readInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - slot: { - __typeName: 'sint8', - __typeValue: this.slot - }, - minValue: { - __typeName: 'sint32', - __typeValue: this.minValue - }, - maxValue: { - __typeName: 'sint32', - __typeValue: this.maxValue - } - }; - } -} - -class DataStoreCustomRankingResult extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.order = stream.readUInt32LE(); - this.score = stream.readUInt32LE(); - this.metaInfo = stream.readNEXStructure(DataStoreTypes.DataStoreMetaInfo); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - order: { - __typeName: 'uint32', - __typeValue: this.order - }, - score: { - __typeName: 'uint32', - __typeValue: this.score - }, - metaInfo: { - __typeName: 'DataStoreMetaInfo', - __typeValue: this.metaInfo - } - }; - } -} - -class DataStoreGetCustomRankingByDataIdParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.applicationId = stream.readUInt32LE(); - this.metaInfo = stream.readNEXList(stream.readUInt64LE); - this.resultOption = stream.readUInt8(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - applicationId: { - __typeName: 'uint32', - __typeValue: this.applicationId - }, - metaInfo: { - __typeName: 'List', - __typeValue: this.metaInfo - }, - resultOption: { - __typeName: 'uint8', - __typeValue: this.resultOption - } - }; - } -} - -class BufferQueueParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.slot = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - slot: { - __typeName: 'uint32', - __typeValue: this.slot - } - }; - } -} - -class DataStoreAttachFileParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.postParam = stream.readNEXStructure(DataStoreTypes.DataStorePreparePostParam); - this.referDataId = stream.readUInt64LE(); - this.contentType = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - postParam: { - __typeName: 'DataStorePreparePostParam', - __typeValue: this.postParam - }, - referDataId: { - __typeName: 'uint32', - __typeValue: this.referDataId - }, - contentType: { - __typeName: 'String', - __typeValue: this.contentType - } - }; - } -} - -class DataStoreUploadCourseRecordParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.slot = stream.readUInt8(); - this.score = stream.readInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - slot: { - __typeName: 'uint8', - __typeValue: this.slot - }, - score: { - __typeName: 'sint32', - __typeValue: this.score - } - }; - } -} - -class DataStoreGetCourseRecordParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.slot = stream.readUInt8(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - slot: { - __typeName: 'uint8', - __typeValue: this.slot - } - }; - } -} - -class DataStoreGetCourseRecordResult extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.slot = stream.readUInt8(); - this.firstPid = stream.readUInt32LE(); // * NEX stores this as uint32 but is actually PID? - this.bestPid = stream.readUInt32LE(); // * NEX stores this as uint32 but is actually PID? - this.bestScore = stream.readInt32LE(); - this.createdTime = stream.readNEXDateTime(); - this.updatedTime = stream.readNEXDateTime(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - slot: { - __typeName: 'uint8', - __typeValue: this.slot - }, - firstPid: { - __typeName: 'uint32', - __typeValue: this.firstPid - }, - bestPid: { - __typeName: 'uint32', - __typeValue: this.bestPid - }, - bestScore: { - __typeName: 'sint32', - __typeValue: this.bestScore - }, - createdTime: { - __typeName: 'DateTime', - __typeValue: this.createdTime - }, - updatedTime: { - __typeName: 'DateTime', - __typeValue: this.updatedTime - } - }; - } -} - -class DataStoreChangePlayablePlatformParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.playablePlatform = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - playablePlatform: { - __typeName: 'uint32', - __typeValue: this.playablePlatform - } - }; - } -} - -class DataStoreReportCourseParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.dataId = stream.readUInt64LE(); - this.miiName = stream.readNEXString(); - this.reportCategory = stream.readUInt8(); - this.reportReason = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - dataId: { - __typeName: 'uint64', - __typeValue: this.dataId - }, - miiName: { - __typeName: 'String', - __typeValue: this.miiName - }, - reportCategory: { - __typeName: 'uint8', - __typeValue: this.reportCategory - }, - reportReason: { - __typeName: 'String', - __typeValue: this.reportReason - } - }; - } -} - -module.exports = { - DataStoreFileServerObjectInfo, - DataStoreGetMetaByOwnerIdParam, - DataStoreRateCustomRankingParam, - DataStoreGetCustomRankingParam, - DataStoreCustomRankingRatingCondition, - DataStoreCustomRankingResult, - DataStoreGetCustomRankingByDataIdParam, - BufferQueueParam, - DataStoreAttachFileParam, - DataStoreUploadCourseRecordParam, - DataStoreGetCourseRecordParam, - DataStoreGetCourseRecordResult, - DataStoreChangePlayablePlatformParam, - DataStoreReportCourseParam -}; \ No newline at end of file diff --git a/src/protocols/types/friends_3ds.js b/src/protocols/types/friends_3ds.js deleted file mode 100644 index 7769e94..0000000 --- a/src/protocols/types/friends_3ds.js +++ /dev/null @@ -1,279 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class GameKey extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.titleId = stream.readUInt64LE(); - this.titleVersion = stream.readUInt16LE(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - titleId: { - __typeName: 'uint64', - __typeValue: this.titleId - }, - titleVersion: { - __typeName: 'uint16', - __typeValue: this.titleVersion - } - }; - } -} -NEXTypes.AnyDataHolder.addType('GameKey', GameKey); - -class NintendoPresence extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_changedBitFlag = stream.readUInt32LE(); - this.m_gameKey = stream.readNEXStructure(GameKey); - this.m_gameModeDescription = stream.readNEXString(); - this.m_joinAvailabilityFlag = stream.readUInt32LE(); - this.m_matchmakeSystemType = stream.readUInt8(); - this.m_joinGameID = stream.readUInt32LE(); - this.m_joinGameMode = stream.readUInt32LE(); - this.m_ownerPrincipalID = stream.readPID(); - this.m_joinGroupID = stream.readUInt32LE(); - this.m_applicationArg = stream.readNEXBuffer(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_changedBitFlag: { - __typeName: 'uint32', - __typeValue: this.m_changedBitFlag - }, - m_gameKey: { - __typeName: 'GameKey', - __typeValue: this.m_gameKey - }, - m_gameModeDescription: { - __typeName: 'String', - __typeValue: this.m_gameModeDescription - }, - m_joinAvailabilityFlag: { - __typeName: 'uint32', - __typeValue: this.m_joinAvailabilityFlag - }, - m_matchmakeSystemType: { - __typeName: 'uint8', - __typeValue: this.m_matchmakeSystemType - }, - m_joinGameID: { - __typeName: 'uint32', - __typeValue: this.m_joinGameID - }, - m_joinGameMode: { - __typeName: 'uint32', - __typeValue: this.m_joinGameMode - }, - m_ownerPrincipalID: { - __typeName: 'PID', - __typeValue: this.m_ownerPrincipalID - }, - m_joinGroupID: { - __typeName: 'uint32', - __typeValue: this.m_joinGroupID - }, - m_applicationArg: { - __typeName: 'Buffer', - __typeValue: this.m_applicationArg - } - }; - } -} -NEXTypes.AnyDataHolder.addType('NintendoPresence', NintendoPresence); - -class FriendPresence extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.pid = stream.readPID(); - this.presence = stream.readNEXStructure(NintendoPresence); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_ownerPrincipalID: { - __typeName: 'PID', - __typeValue: this.pid - }, - m_gameKey: { - __typeName: 'NintendoPresence', - __typeValue: this.presence - } - }; - } -} - -class FriendRelationship extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.pid = stream.readPID(); - this.localFriendCode = stream.readUInt64LE(); - this.relationshipType = stream.readUInt8(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - pid: { - __typeName: 'PID', - __typeValue: this.pid - }, - localFriendCode: { - __typeName: 'uint64', - __typeValue: this.localFriendCode - }, - relationshipType: { - __typeName: 'uint8', - __typeValue: this.relationshipType - } - }; - } -} - -class FriendPersistentInfo extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.pid = stream.readPID(); - this.region = stream.readUInt8(); - this.country = stream.readUInt8(); - this.area = stream.readUInt8(); - this.language = stream.readUInt8(); - this.platform = stream.readUInt8(); - this.gameKey = stream.readNEXStructure(GameKey); - this.message = stream.readNEXString(); - this.messageUpdatedAt = stream.readNEXDateTime(); - this.friendedAt = stream.readNEXDateTime(); - this.lastOnline = stream.readNEXDateTime(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - pid: { - __typeName: 'uint32', - __typeValue: this.pid - }, - region: { - __typeName: 'uint8', - __typeValue: this.region - }, - country: { - __typeName: 'uint8', - __typeValue: this.country - }, - area: { - __typeName: 'uint8', - __typeValue: this.area - }, - language: { - __typeName: 'uint8', - __typeValue: this.language - }, - platform: { - __typeName: 'uint8', - __typeValue: this.platform - }, - gameKey: { - __typeName: 'GameKey', - __typeValue: this.gameKey - }, - message: { - __typeName: 'String', - __typeValue: this.message - }, - messageUpdatedAt: { - __typeName: 'DateTime', - __typeValue: this.messageUpdatedAt - }, - friendedAt: { - __typeName: 'DateTime', - __typeValue: this.friendedAt - }, - lastOnline: { - __typeName: 'DateTime', - __typeValue: this.lastOnline - } - }; - } -} - -module.exports = { - GameKey, - NintendoPresence, - FriendPresence, - FriendRelationship, - FriendPersistentInfo -}; diff --git a/src/protocols/types/friends_wiiu.js b/src/protocols/types/friends_wiiu.js deleted file mode 100644 index d0d2a3d..0000000 --- a/src/protocols/types/friends_wiiu.js +++ /dev/null @@ -1,661 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class NNAInfo extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.principalBasicInfo = stream.readNEXStructure(PrincipalBasicInfo); - this.unknown1 = stream.readUInt8(); - this.unknown2 = stream.readUInt8(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - principalBasicInfo: { - __typeName: 'PrincipalBasicInfo', - __typeValue: this.principalBasicInfo - }, - unknown1: { - __typeName: 'uint8', - __typeValue: this.unknown1 - }, - unknown2: { - __typeName: 'uint8', - __typeValue: this.unknown2 - } - }; - } -} -NEXTypes.AnyDataHolder.addType('NNAInfo', NNAInfo); - -class PrincipalBasicInfo extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.pid = stream.readPID(); - this.nnid = stream.readNEXString(); - this.mii = stream.readNEXStructure(MiiV2); - this.unknown2 = stream.readUInt8(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - pid: { - __typeName: 'PID', - __typeValue: this.pid - }, - nnid: { - __typeName: 'String', - __typeValue: this.nnid - }, - mii: { - __typeName: 'MiiV2', - __typeValue: this.mii - }, - unknown2: { - __typeName: 'uint8', - __typeValue: this.unknown2 - } - }; - } -} - -class MiiV2 extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.name = stream.readNEXString(); - this.unknown1 = stream.readUInt8(); - this.unknown2 = stream.readUInt8(); - this.data = stream.readNEXBuffer(); - this.unknown3 = stream.readNEXDateTime(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - name: { - __typeName: 'String', - __typeValue: this.name - }, - unknown1: { - __typeName: 'uint8', - __typeValue: this.unknown1 - }, - unknown2: { - __typeName: 'uint8', - __typeValue: this.unknown2 - }, - data: { - __typeName: 'Buffer', - __typeValue: this.data - }, - unknown3: { - __typeName: 'DateTime', - __typeValue: this.unknown3 - } - }; - } -} - -class NintendoPresenceV2 extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.changedFlags = stream.readUInt32LE(); - this.isOnline = stream.readBoolean(); - this.gameKey = stream.readNEXStructure(GameKey); - this.unknown1 = stream.readUInt8(); - this.message = stream.readNEXString(); - this.unknown2 = stream.readUInt32LE(); - this.unknown3 = stream.readUInt8(); - this.gameServerId = stream.readUInt32LE(); - this.unknown4 = stream.readUInt32LE(); - this.pid = stream.readPID(); - this.gatheringId = stream.readUInt32LE(); - this.applicationData = stream.readNEXBuffer(); - this.unknown5 = stream.readUInt8(); - this.unknown6 = stream.readUInt8(); - this.unknown7 = stream.readUInt8(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - changedFlags: { - __typeName: 'uint32', - __typeValue: this.changedFlags - }, - isOnline: { - __typeName: 'boolean', - __typeValue: this.isOnline - }, - gameKey: { - __typeName: 'GameKey', - __typeValue: this.gameKey - }, - unknown1: { - __typeName: 'uint8', - __typeValue: this.unknown1 - }, - message: { - __typeName: 'String', - __typeValue: this.message - }, - unknown2: { - __typeName: 'uint32', - __typeValue: this.unknown2 - }, - unknown3: { - __typeName: 'uint8', - __typeValue: this.unknown3 - }, - gameServerId: { - __typeName: 'uint32', - __typeValue: this.gameServerId - }, - unknown4: { - __typeName: 'uint32', - __typeValue: this.unknown4 - }, - pid: { - __typeName: 'PID', - __typeValue: this.pid - }, - gatheringId: { - __typeName: 'uint32', - __typeValue: this.gatheringId - }, - applicationData: { - __typeName: 'Buffer', - __typeValue: this.applicationData - }, - unknown5: { - __typeName: 'uint8', - __typeValue: this.unknown5 - }, - unknown6: { - __typeName: 'uint8', - __typeValue: this.unknown6 - }, - unknown7: { - __typeName: 'uint8', - __typeValue: this.unknown7 - } - }; - } -} -NEXTypes.AnyDataHolder.addType('NintendoPresenceV2', NintendoPresenceV2); - -class GameKey extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.titleId = stream.readUInt64LE(); - this.titleVersion = stream.readUInt16LE(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - titleId: { - __typeName: 'uint64', - __typeValue: this.titleId - }, - titleVersion: { - __typeName: 'uint16', - __typeValue: this.titleVersion - } - }; - } -} - -class PrincipalPreference extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.showOnlinePresence = stream.readBoolean(); - this.showCurrentlyPlayingTitle = stream.readBoolean(); - this.blockFriendRequests = stream.readBoolean(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - showOnlinePresence: { - __typeName: 'boolean', - __typeValue: this.showOnlinePresence - }, - showCurrentlyPlayingTitle: { - __typeName: 'boolean', - __typeValue: this.showCurrentlyPlayingTitle - }, - blockFriendRequests: { - __typeName: 'boolean', - __typeValue: this.blockFriendRequests - } - }; - } -} -NEXTypes.AnyDataHolder.addType('PrincipalPreference', PrincipalPreference); - -class Comment extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.unknown = stream.readUInt8(); - this.statusMessage = stream.readNEXString(); - this.lastChangedOn = stream.readNEXDateTime(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - unknown: { - __typeName: 'uint8', - __typeValue: this.unknown - }, - statusMessage: { - __typeName: 'String', - __typeValue: this.statusMessage - }, - lastChangedOn: { - __typeName: 'DateTime', - __typeValue: this.lastChangedOn - } - }; - } -} - -class FriendInfo extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.NNAInfo = stream.readNEXStructure(NNAInfo); - this.presence = stream.readNEXStructure(NintendoPresenceV2); - this.statusMessage = stream.readNEXStructure(Comment); - this.becameFriend = stream.readNEXDateTime(); - this.lastOnline = stream.readNEXDateTime(); - this.unknown = stream.readUInt64LE(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - NNAInfo: { - __typeName: 'NNAInfo', - __typeValue: this.NNAInfo - }, - presence: { - __typeName: 'NintendoPresenceV2', - __typeValue: this.presence - }, - statusMessage: { - __typeName: 'Comment', - __typeValue: this.statusMessage - }, - becameFriend: { - __typeName: 'DateTime', - __typeValue: this.becameFriend - }, - lastOnline: { - __typeName: 'DateTime', - __typeValue: this.lastOnline - }, - unknown: { - __typeName: 'uint64', - __typeValue: this.unknown - } - }; - } -} -NEXTypes.AnyDataHolder.addType('FriendInfo', FriendInfo); - -class FriendRequest extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.principalBasicInfo = stream.readNEXStructure(PrincipalBasicInfo); - this.message = stream.readNEXStructure(FriendRequestMessage); - this.sentOn = stream.readNEXDateTime(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - principalBasicInfo: { - __typeName: 'PrincipalBasicInfo', - __typeValue: this.principalBasicInfo - }, - message: { - __typeName: 'FriendRequestMessage', - __typeValue: this.message - }, - sentOn: { - __typeName: 'DateTime', - __typeValue: this.sentOn - } - }; - } -} -NEXTypes.AnyDataHolder.addType('FriendRequest', FriendRequest); - -class FriendRequestMessage extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.friendRequestId = stream.readUInt64LE(); - this.isRecieved = stream.readBoolean(); - this.unknown1 = stream.readUInt8(); - this.message = stream.readNEXString(); - this.unknown2 = stream.readUInt8(); - this.unknown3 = stream.readNEXString(); - this.gameKey = stream.readNEXStructure(GameKey); - this.unknown4 = stream.readNEXDateTime(); - this.expiresOn = stream.readNEXDateTime(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - friendRequestId: { - __typeName: 'uint64', - __typeValue: this.friendRequestId - }, - isRecieved: { - __typeName: 'uint8', - __typeValue: this.isRecieved - }, - unknown1: { - __typeName: 'uint8', - __typeValue: this.unknown1 - }, - message: { - __typeName: 'String', - __typeValue: this.message - }, - unknown2: { - __typeName: 'uint8', - __typeValue: this.unknown2 - }, - unknown3: { - __typeName: 'String', - __typeValue: this.unknown3 - }, - gameKey: { - __typeName: 'GameKey', - __typeValue: this.gameKey - }, - unknown4: { - __typeName: 'DateTime', - __typeValue: this.unknown4 - }, - expiresOn: { - __typeName: 'DateTime', - __typeValue: this.expiresOn - } - }; - } -} - -class BlacklistedPrincipal extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.principalBasicInfo = stream.readNEXStructure(PrincipalBasicInfo); - this.gameKey = stream.readNEXStructure(GameKey); - this.blacklistedSince = stream.readNEXDateTime(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - principalBasicInfo: { - __typeName: 'PrincipalBasicInfo', - __typeValue: this.principalBasicInfo - }, - gameKey: { - __typeName: 'GameKey', - __typeValue: this.gameKey - }, - blacklistedSince: { - __typeName: 'DateTime', - __typeValue: this.blacklistedSince - } - }; - } -} - -class PersistentNotification extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.unknown1 = stream.readUInt64LE(); - this.unknown2 = stream.readUInt32LE(); - this.unknown3 = stream.readUInt32LE(); - this.unknown4 = stream.readUInt32LE(); - this.unknown5 = stream.readNEXString(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - unknown1: { - __typeName: 'uint64', - __typeValue: this.unknown1 - }, - unknown2: { - __typeName: 'uint32', - __typeValue: this.unknown2 - }, - unknown3: { - __typeName: 'uint32', - __typeValue: this.unknown3 - }, - unknown4: { - __typeName: 'uint32', - __typeValue: this.unknown4 - }, - unknown5: { - __typeName: 'String', - __typeValue: this.unknown5 - } - }; - } -} - -class PersistentNotificationList extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.notifications = stream.readNEXString(PersistentNotification); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - notifications: { - __typeName: 'List', - __typeValue: this.notifications - } - }; - } -} -NEXTypes.AnyDataHolder.addType('PersistentNotificationList', PersistentNotificationList); - -module.exports = { - NNAInfo, - PrincipalBasicInfo, - MiiV2, - NintendoPresenceV2, - GameKey, - PrincipalPreference, - Comment, - FriendInfo, - FriendRequest, - FriendRequestMessage, - BlacklistedPrincipal, - PersistentNotification, - PersistentNotificationList -}; \ No newline at end of file diff --git a/src/protocols/types/match_making.js b/src/protocols/types/match_making.js deleted file mode 100644 index 3581e98..0000000 --- a/src/protocols/types/match_making.js +++ /dev/null @@ -1,1106 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const semver = require('semver'); -const NEXTypes = require('../../types'); - -class Gathering extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_idMyself = stream.readUInt32LE(); - this.m_pidOwner = stream.readPID(); - this.m_pidHost = stream.readPID(); - this.m_uiMinParticipants = stream.readUInt16LE(); - this.m_uiMaxParticipants = stream.readUInt16LE(); - this.m_uiParticipationPolicy = stream.readUInt32LE(); - this.m_uiPolicyArgument = stream.readUInt32LE(); - this.m_uiFlags = stream.readUInt32LE(); - this.m_uiState = stream.readUInt32LE(); - this.m_strDescription = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_idMyself: { - __typeName: 'uint32', - __typeValue: this.m_idMyself - }, - m_pidOwner: { - __typeName: 'PID', - __typeValue: this.m_pidOwner - }, - m_pidHost: { - __typeName: 'PID', - __typeValue: this.m_pidHost - }, - m_uiMinParticipants: { - __typeName: 'uint16', - __typeValue: this.m_uiMinParticipants - }, - m_uiMaxParticipants: { - __typeName: 'uint16', - __typeValue: this.m_uiMaxParticipants - }, - m_uiParticipationPolicy: { - __typeName: 'uint32', - __typeValue: this.m_uiParticipationPolicy - }, - m_uiPolicyArgument: { - __typeName: 'uint32', - __typeValue: this.m_uiPolicyArgument - }, - m_uiFlags: { - __typeName: 'uint32', - __typeValue: this.m_uiFlags - }, - m_uiState: { - __typeName: 'uint32', - __typeValue: this.m_uiState - }, - m_strDescription: { - __typeName: 'String', - __typeValue: this.m_strDescription - } - }; - } -} -NEXTypes.AnyDataHolder.addType('Gathering', Gathering); - -class PersistentGathering extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(Gathering); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_CommunityType = stream.readUInt32LE(); - this.m_Password = stream.readNEXString(); - this.m_Attribs = stream.readNEXList(stream.readUInt32LE); - this.m_ApplicationBuffer = stream.readNEXBuffer(); - this.m_ParticipationStartDate = stream.readNEXDateTime(); - this.m_ParticipationEndDate = stream.readNEXDateTime(); - this.m_MatchmakeSessionCount = stream.readUInt32LE(); - this.m_ParticipationCount = stream.readUInt32LE(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_CommunityType: { - __typeName: 'uint32', - __typeValue: this.m_CommunityType - }, - m_Password: { - __typeName: 'String', - __typeValue: this.m_Password - }, - m_Attribs: { - __typeName: 'List', - __typeValue: this.m_Attribs - }, - m_ApplicationBuffer: { - __typeName: 'Buffer', - __typeValue: this.m_ApplicationBuffer - }, - m_ParticipationStartDate: { - __typeName: 'DateTime', - __typeValue: this.m_ParticipationStartDate - }, - m_ParticipationEndDate: { - __typeName: 'DateTime', - __typeValue: this.m_ParticipationEndDate - }, - m_MatchmakeSessionCount: { - __typeName: 'uint32', - __typeValue: this.m_MatchmakeSessionCount - }, - m_ParticipationCount: { - __typeName: 'uint32', - __typeValue: this.m_ParticipationCount - } - }; - } -} - -class MatchmakeSession extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(Gathering); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - const nexVersion = stream.connection.title.nex_match_making_version || stream.connection.title.nex_version; - - this.m_GameMode = stream.readUInt32LE(); - this.m_Attribs = stream.readNEXList(stream.readUInt32LE); - this.m_OpenParticipation = stream.readBoolean(); - this.m_MatchmakeSystemType = stream.readUInt32LE(); - this.m_ApplicationBuffer = stream.readNEXBuffer(); - this.m_ParticipationCount = stream.readUInt32LE(); - - if (semver.gte(nexVersion, '3.4.0')) { - this.m_ProgressScore = stream.readUInt8(); - } - - if (semver.gte(nexVersion, '3.0.0')) { - this.m_SessionKey = stream.readNEXBuffer(); - } - - if (semver.gte(nexVersion, '3.5.0')) { - this.m_Option0 = stream.readUInt32LE(); - } - - if (semver.gte(nexVersion, '3.6.0')) { - this.m_MatchmakeParam = stream.readNEXStructure(MatchmakeParam); - this.m_StartedTime = stream.readNEXDateTime(); - } - - if (semver.gte(nexVersion, '3.7.0')) { - this.m_UserPassword = stream.readNEXString(); - } - - if (semver.gte(nexVersion, '3.8.0')) { - this.m_ReferGid = stream.readUInt32LE(); - this.m_UserPasswordEnabled = stream.readBoolean(); - this.m_SystemPasswordEnabled = stream.readBoolean(); - } - - if (semver.gte(nexVersion, '4.0.0')) { - this.m_Codeword = stream.readNEXString(); - } - } - - toJSON() { - const data = { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_GameMode: { - __typeName: 'uint32', - __typeValue: this.m_GameMode - }, - m_Attribs: { - __typeName: 'List', - __typeValue: this.m_Attribs - }, - m_OpenParticipation: { - __typeName: 'boolean', - __typeValue: this.m_OpenParticipation - }, - m_MatchmakeSystemType: { - __typeName: 'uint32', - __typeValue: this.m_MatchmakeSystemType - }, - m_ApplicationBuffer: { - __typeName: 'Buffer', - __typeValue: this.m_ApplicationBuffer - }, - m_ParticipationCount: { - __typeName: 'uint32', - __typeValue: this.m_ParticipationCount - } - }; - - if (this.m_ProgressScore !== undefined) { - data.m_ProgressScore = { - __typeName: 'uint8', - __typeValue: this.m_ProgressScore - }; // If prudpv1 - } - - if (this.m_SessionKey !== undefined) { - data.m_SessionKey = { - __typeName: 'Buffer', - __typeValue: this.m_SessionKey - }; // If prudpv1 - } - - if (this.m_Option0 !== undefined) { - data.m_Option0 = { - __typeName: 'uint32', - __typeValue: this.m_Option0 - }; // If prudpv1 - } - - if (this.m_MatchmakeParam !== undefined) { - data.m_MatchmakeParam = { - __typeName: 'MatchmakeParam', - __typeValue: this.m_MatchmakeParam - }; // If prudpv1 - } - - if (this.m_StartedTime !== undefined) { - data.m_StartedTime = { - __typeName: 'DateTime', - __typeValue: this.m_StartedTime - }; // If prudpv1 - } - - if (this.m_UserPassword !== undefined) { - data.m_UserPassword = { - __typeName: 'String', - __typeValue: this.m_UserPassword - }; // If prudpv1 - } - - if (this.m_ReferGid !== undefined) { - data.m_ReferGid = { - __typeName: 'uint32', - __typeValue: this.m_ReferGid - }; // If prudpv1 - } - - if (this.m_UserPasswordEnabled !== undefined) { - data.m_UserPasswordEnabled = { - __typeName: 'boolean', - __typeValue: this.m_UserPasswordEnabled - }; // If prudpv1 - } - - if (this.m_SystemPasswordEnabled !== undefined) { - data.m_SystemPasswordEnabled = { - __typeName: 'boolean', - __typeValue: this.m_SystemPasswordEnabled - }; // If prudpv1 - } - - if (this.m_Codeword !== undefined) { - data.m_Codeword = { - __typeName: 'String', - __typeValue: this.m_Codeword - }; // If prudpv1 - } - - return data; - } -} -NEXTypes.AnyDataHolder.addType('MatchmakeSession', MatchmakeSession); - -class MatchmakeSessionSearchCriteria extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - const nexVersion = stream.connection.title.nex_match_making_version || stream.connection.title.nex_version; - - this.m_Attribs = stream.readNEXList(stream.readNEXString); - this.m_GameMode = stream.readNEXString(); - this.m_MinParticipants = stream.readNEXString(); - this.m_MaxParticipants = stream.readNEXString(); - this.m_MatchmakeSystemType = stream.readNEXString(); - this.m_VacantOnly = stream.readBoolean(); - this.m_ExcludeLocked = stream.readBoolean(); - this.m_ExcludeNonHostPid = stream.readBoolean(); - - if (semver.gte(nexVersion, '3.0.0')) { - this.m_SelectionMethod = stream.readUInt32LE(); - } - - if (semver.gte(nexVersion, '3.4.0')) { - this.m_VacantParticipants = stream.readUInt16LE(); - } - - if (semver.gte(nexVersion, '3.6.0')) { - this.m_MatchmakeParam = stream.readNEXStructure(MatchmakeParam); - } - - if (semver.gte(nexVersion, '3.7.0')) { - this.m_ExcludeUserPasswordSet = stream.readBoolean(); - this.m_ExcludeSystemPasswordSet = stream.readBoolean(); - } - - if (semver.gte(nexVersion, '3.8.0')) { - this.m_ReferGid = stream.readUInt32LE(); - } - - if (semver.gte(nexVersion, '4.0.0')) { - this.m_Codeword = stream.readNEXString(); - this.m_ResultRange = stream.readNEXStructure(NEXTypes.ResultRange); - } - } - - toJSON() { - const data = { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_Attribs: { - __typeName: 'List', - __typeValue: this.m_Attribs - }, - m_GameMode: { - __typeName: 'String', - __typeValue: this.m_GameMode - }, - m_MinParticipants: { - __typeName: 'String', - __typeValue: this.m_MinParticipants - }, - m_MaxParticipants: { - __typeName: 'String', - __typeValue: this.m_MaxParticipants - }, - m_MatchmakeSystemType: { - __typeName: 'String', - __typeValue: this.m_MatchmakeSystemType - }, - m_VacantOnly: { - __typeName: 'boolean', - __typeValue: this.m_VacantOnly - }, - m_ExcludeLocked: { - __typeName: 'boolean', - __typeValue: this.m_ExcludeLocked - }, - m_ExcludeNonHostPid: { - __typeName: 'boolean', - __typeValue: this.m_ExcludeNonHostPid - } - }; - - if (this.m_SelectionMethod !== undefined) { - data.m_SelectionMethod = { - __typeName: 'uint32', - __typeValue: this.m_SelectionMethod - }; - } - - if (this.m_VacantParticipants !== undefined) { - data.m_VacantParticipants = { - __typeName: 'uint16', - __typeValue: this.m_VacantParticipants - }; // If prudpv1 - } - - if (this.m_MatchmakeParam !== undefined) { - data.m_MatchmakeParam = { - __typeName: 'MatchmakeParam', - __typeValue: this.m_MatchmakeParam - }; // If prudpv1 - } - - if (this.m_ExcludeUserPasswordSet !== undefined) { - data.m_ExcludeUserPasswordSet = { - __typeName: 'boolean', - __typeValue: this.m_ExcludeUserPasswordSet - }; // If prudpv1 - } - - if (this.m_ExcludeSystemPasswordSet !== undefined) { - data.m_ExcludeSystemPasswordSet = { - __typeName: 'boolean', - __typeValue: this.m_ExcludeSystemPasswordSet - }; // If prudpv1 - } - - if (this.m_ReferGid !== undefined) { - data.m_ReferGid = { - __typeName: 'uint32', - __typeValue: this.m_ReferGid - }; // If prudpv1 - } - - if (this.m_Codeword !== undefined) { - data.m_Codeword = { - __typeName: 'String', - __typeValue: this.m_Codeword - }; // If prudpv1 - } - - if (this.m_ResultRange !== undefined) { - data.m_ResultRange = { - __typeName: 'ResultRange', - __typeValue: this.m_ResultRange - }; // If prudpv1 - } - - return data; - } -} - -class CreateMatchmakeSessionParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.sourceMatchmakeSession = stream.readNEXStructure(MatchmakeSession); - this.additionalParticipants = stream.readNEXList(stream.readPID); - this.gidForParticipationCheck = stream.readUInt32LE(); - this.createMatchmakeSessionOption = stream.readUInt32LE(); - this.joinMessage = stream.readNEXString(); - this.participationCount = stream.readUInt16LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - sourceMatchmakeSession: { - __typeName: 'MatchmakeSession', - __typeValue: this.sourceMatchmakeSession - }, - additionalParticipants: { - __typeName: 'List', - __typeValue: this.additionalParticipants - }, - gidForParticipationCheck: { - __typeName: 'uint32', - __typeValue: this.gidForParticipationCheck - }, - createMatchmakeSessionOption: { - __typeName: 'uint32', - __typeValue: this.createMatchmakeSessionOption - }, - joinMessage: { - __typeName: 'String', - __typeValue: this.joinMessage - }, - participationCount: { - __typeName: 'uint16', - __typeValue: this.participationCount - } - }; - } -} - -class JoinMatchmakeSessionParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - const nexVersion = stream.connection.title.nex_match_making_version || stream.connection.title.nex_version; - - this.gid = stream.readUInt32LE(); - this.additionalParticipants = stream.readNEXList(stream.readPID); - this.gidForParticipationCheck = stream.readUInt32LE(); - this.joinMatchmakeSessionOption = stream.readUInt32LE(); - this.joinMatchmakeSessionBehavior = stream.readUInt8(); - this.strUserPassword = stream.readNEXString(); - this.strSystemPassword = stream.readNEXString(); - this.joinMessage = stream.readNEXString(); - this.participationCount = stream.readUInt16LE(); - - // * From Dani: - // * - "Just for future reference, Minecraft has structure version 1 on JoinMatchmakeSessionParam" - // * These fields COULD be different structure versions, not related to NEX updates. - // * Need to do more research - - // * Assuming this to be 3.10.0 - // * Not seen in Terraria, which is 3.8.3 - if (semver.gte(nexVersion, '3.10.0')) { - this.extraParticipants = stream.readUInt16LE(); - } - - // * Assuming this to be 4.0.0 - // * Not seen in Minecraft, which is 3.10.0 - if (semver.gte(nexVersion, '4.0.0')) { - this.blockListParam = stream.readNEXStructure(MatchmakeBlockListParam); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - additionalParticipants: { - __typeName: 'List', - __typeValue: this.additionalParticipants - }, - gidForParticipationCheck: { - __typeName: 'uint32', - __typeValue: this.gidForParticipationCheck - }, - joinMatchmakeSessionOption: { - __typeName: 'uint32', - __typeValue: this.joinMatchmakeSessionOption - }, - joinMatchmakeSessionBehavior: { - __typeName: 'uint8', - __typeValue: this.joinMatchmakeSessionBehavior - }, - strUserPassword: { - __typeName: 'String', - __typeValue: this.strUserPassword - }, - strSystemPassword: { - __typeName: 'String', - __typeValue: this.strSystemPassword - }, - joinMessage: { - __typeName: 'String', - __typeValue: this.joinMessage - }, - participationCount: { - __typeName: 'uint16', - __typeValue: this.participationCount - } - }; - - if (this.extraParticipants !== undefined) { - data.extraParticipants = { - __typeName: 'uint16', - __typeValue: this.extraParticipants - }; - } - - if (this.blockListParam !== undefined) { - data.blockListParam = { - __typeName: 'MatchmakeBlockListParam', - __typeValue: this.blockListParam - }; - } - - return data; - } -} - -class UpdateMatchmakeSessionParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.gid = stream.readUInt32LE(); - this.modificationFlag = stream.readUInt32LE(); - this.attributes = stream.readNEXList(stream.readUInt32LE); - this.openParticipation = stream.readBoolean(); - this.applicationBuffer = stream.readNEXBuffer(); - this.progressScore = stream.readUInt8(); - this.matchmakeParam = stream.readNEXStructure(MatchmakeParam); - this.startedTime = stream.readNEXDateTime(); - this.userPassword = stream.readNEXString(); - this.gameMode = stream.readUInt32LE(); - this.description = stream.readNEXString(); - this.minParticipants = stream.readUInt16LE(); - this.maxParticipants = stream.readUInt16LE(); - this.matchmakeSystemType = stream.readUInt32LE(); - this.participationPolicy = stream.readUInt32LE(); - this.policyArgument = stream.readUInt32LE(); - this.codeword = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - gid: { - __typeName: 'uint32', - __typeValue: this.gid - }, - modificationFlag: { - __typeName: 'uint32', - __typeValue: this.modificationFlag - }, - attributes: { - __typeName: 'List', - __typeValue: this.attributes - }, - openParticipation: { - __typeName: 'boolean', - __typeValue: this.openParticipation - }, - applicationBuffer: { - __typeName: 'Buffer', - __typeValue: this.applicationBuffer - }, - progressScore: { - __typeName: 'uint8', - __typeValue: this.progressScore - }, - matchmakeParam: { - __typeName: 'MatchmakeParam', - __typeValue: this.matchmakeParam - }, - startedTime: { - __typeName: 'DateTime', - __typeValue: this.startedTime - }, - userPassword: { - __typeName: 'String', - __typeValue: this.userPassword - }, - gameMode: { - __typeName: 'uint132', - __typeValue: this.gameMode - }, - description: { - __typeName: 'String', - __typeValue: this.description - }, - minParticipants: { - __typeName: 'uint16', - __typeValue: this.minParticipants - }, - maxParticipants: { - __typeName: 'uint16', - __typeValue: this.maxParticipants - }, - matchmakeSystemType: { - __typeName: 'Stri32', - __typeValue: this.matchmakeSystemType - }, - participationPolicy: { - __typeName: 'uint32', - __typeValue: this.participationPolicy - }, - policyArgument: { - __typeName: 'uint32', - __typeValue: this.policyArgument - }, - codeword: { - __typeName: 'String', - __typeValue: this.codeword - } - }; - } -} - -class MatchmakeBlockListParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.optionFlag = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - optionFlag: { - __typeName: 'uint32', - __typeValue: this.optionFlag - } - }; - } -} - -class MatchmakeParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_Params = stream.readNEXMap(stream.readNEXString, stream.readNEXVariant); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_Params: { - __typeName: 'Map', - __typeValue: this.m_Params - } - }; - } -} - -class AutoMatchmakeParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - const nexVersion = stream.connection.title.nex_match_making_version || stream.connection.title.nex_version; - - this.sourceMatchmakeSession = stream.readNEXStructure(MatchmakeSession); - this.additionalParticipants = stream.readNEXList(stream.readPID); - this.gidForParticipationCheck = stream.readUInt32LE(); - this.autoMatchmakeOption = stream.readUInt32LE(); - this.joinMessage = stream.readNEXString(); - this.participationCount = stream.readUInt16LE(); - this.lstSearchCriteria = stream.readNEXList(MatchmakeSessionSearchCriteria); - this.targetGids = stream.readNEXList(stream.readUInt32LE); - - if (semver.gte(nexVersion, '4.0.0')) { - this.blockListParam = stream.readNEXStructure(MatchmakeBlockListParam); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - sourceMatchmakeSession: { - __typeName: 'MatchmakeSession', - __typeValue: this.sourceMatchmakeSession - }, - additionalParticipants: { - __typeName: 'List', - __typeValue: this.additionalParticipants - }, - gidForParticipationCheck: { - __typeName: 'uint32', - __typeValue: this.gidForParticipationCheck - }, - autoMatchmakeOption: { - __typeName: 'uint32', - __typeValue: this.autoMatchmakeOption - }, - joinMessage: { - __typeName: 'String', - __typeValue: this.joinMessage - }, - participationCount: { - __typeName: 'uint16', - __typeValue: this.participationCount - }, - lstSearchCriteria: { - __typeName: 'List', - __typeValue: this.lstSearchCriteria - }, - targetGids: { - __typeName: 'List', - __typeValue: this.targetGids - } - }; - - if (this.blockListParam !== undefined) { - data.blockListParam = { - __typeName: 'MatchmakeBlockListParam', - __typeValue: this.blockListParam - }; // If prudpv1 - } - - return data; - } -} - -class FindMatchmakeSessionByParticipantParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_principalIdList = stream.readNEXList(stream.readPID); - this.m_resultOptions = stream.readUInt32LE(); - this.m_blockListParam = stream.readNEXStructure(MatchmakeBlockListParam); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_principalIdList: { - __typeName: 'List', - __typeValue: this.m_principalIdList - }, - m_resultOptions: { - __typeName: 'uint32', - __typeValue: this.m_resultOptions - }, - m_blockListParam: { - __typeName: 'MatchmakeBlockListParam', - __typeValue: this.m_blockListParam - } - }; - } -} - -class FindMatchmakeSessionByParticipantResult extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_principalId = stream.readPID(); - this.m_session = stream.readNEXStructure(MatchmakeSession); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_principalId: { - __typeName: 'PID', - __typeValue: this.m_principalId - }, - m_session: { - __typeName: 'MatchmakeSession', - __typeValue: this.m_session - } - }; - } -} - -class GatheringURLs extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_gid = stream.readUInt32LE(); - this.m_lstStationURLs = stream.readNEXStructure(stream.readNEXStationURL); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_gid: { - __typeName: 'uint32', - __typeValue: this.m_gid - }, - m_lstStationURLs: { - __typeName: 'List', - __typeValue: this.m_lstStationURLs - } - }; - } -} - -class GatheringStats extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_pidParticipant = stream.readPID(); - this.m_uiFlags = stream.readUInt32LE(); - this.m_lstValues = stream.readNEXList(stream.readFloatLE); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_pidParticipant: { - __typeName: 'PID', - __typeValue: this.m_pidParticipant - }, - m_uiFlags: { - __typeName: 'uint32', - __typeValue: this.m_uiFlags - }, - m_lstValues: { - __typeName: 'List', - __typeValue: this.m_lstValues - } - }; - } -} - -class Invitation extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_idGathering = stream.readUInt32LE(); - this.m_idGuest = stream.readUInt32LE(); - this.m_strMessage = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_idGathering: { - __typeName: 'uint32', - __typeValue: this.m_idGathering - }, - m_idGuest: { - __typeName: 'uint32', - __typeValue: this.m_idGuest - }, - m_strMessage: { - __typeName: 'String', - __typeValue: this.m_strMessage - } - }; - } -} - -class ParticipantDetails extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_idParticipant = stream.readPID(); - this.m_strName = stream.readNEXString(); - this.m_strMessage = stream.readNEXString(); - this.m_uiParticipants = stream.readUInt16LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_idParticipant: { - __typeName: 'PID', - __typeValue: this.m_idParticipant - }, - m_strName: { - __typeName: 'String', - __typeValue: this.m_strName - }, - m_strMessage: { - __typeName: 'String', - __typeValue: this.m_strMessage - }, - m_uiParticipants: { - __typeName: 'uint16', - __typeValue: this.m_uiParticipants - } - }; - } -} - -class DeletionEntry extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_idGathering = stream.readUInt32LE(); - this.m_pid = stream.readPID(); - this.m_uiReason = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_idGathering: { - __typeName: 'uint32', - __typeValue: this.m_idGathering - }, - m_pid: { - __typeName: 'PID', - __typeValue: this.m_pid - }, - m_uiReason: { - __typeName: 'uint32', - __typeValue: this.m_uiReason - } - }; - } -} - -class PlayingSession extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_PrincipalId = stream.readPID(); - this.m_Gathering = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_PrincipalId: { - __typeName: 'PID', - __typeValue: this.m_PrincipalId - }, - m_Gathering: { - __typeName: 'AnyDataHolder', - __typeValue: this.m_Gathering - } - }; - } -} - -class SimplePlayingSession extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_PrincipalID = stream.readPID(); - this.m_GatheringID = stream.readUInt32LE(); - this.m_GameMode = stream.readUInt32LE(); - this.m_Attribute_0 = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_PrincipalID: { - __typeName: 'PID', - __typeValue: this.m_PrincipalID - }, - m_GatheringID: { - __typeName: 'uint32', - __typeValue: this.m_GatheringID - }, - m_GameMode: { - __typeName: 'uint32', - __typeValue: this.m_GameMode - }, - m_Attribute_0: { - __typeName: 'uint32', - __typeValue: this.m_Attribute_0 - } - }; - } -} - -class SimpleCommunity extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_GatheringID = stream.readUInt32LE(); - this.m_MatchmakeSessionCount = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_GatheringID: { - __typeName: 'uint32', - __typeValue: this.m_GatheringID - }, - m_MatchmakeSessionCount: { - __typeName: 'uint32', - __typeValue: this.m_MatchmakeSessionCount - } - }; - } -} - -module.exports = { - Gathering, - PersistentGathering, - MatchmakeSession, - MatchmakeSessionSearchCriteria, - CreateMatchmakeSessionParam, - JoinMatchmakeSessionParam, - UpdateMatchmakeSessionParam, - MatchmakeBlockListParam, - MatchmakeParam, - AutoMatchmakeParam, - FindMatchmakeSessionByParticipantParam, - FindMatchmakeSessionByParticipantResult, - GatheringURLs, - GatheringStats, - Invitation, - ParticipantDetails, - DeletionEntry, - PlayingSession, - SimplePlayingSession, - SimpleCommunity -}; diff --git a/src/protocols/types/message_delivery.js b/src/protocols/types/message_delivery.js deleted file mode 100644 index 1694c72..0000000 --- a/src/protocols/types/message_delivery.js +++ /dev/null @@ -1,181 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class MessageRecipient extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_uiRecipientType = stream.readUInt32LE(); - this.m_principalId = stream.readPID(); - this.m_gatheringId = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_uiRecipientType: { - __typeName: 'uint32', - __typeValue: this.m_uiRecipientType - }, - m_principalId: { - __typeName: 'PID', - __typeValue: this.m_principalId - }, - m_gatheringId: { - __typeName: 'uint32', - __typeValue: this.m_gatheringId - } - }; - } -} - -class UserMessage extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - // TODO - Support NEX 4.0+ messages - - this.m_uiID = stream.readUInt32LE(); - this.m_idRecipient = stream.readUInt32LE(); - this.m_uiRecipientType = stream.readUInt32LE(); - this.m_uiParentID = stream.readUInt32LE(); - this.m_pidSender = stream.readPID(); - this.m_receptiontime = stream.readNEXDateTime(); - this.m_uiLifeTime = stream.readUInt32LE(); - this.m_uiFlags = stream.readUInt32LE(); - this.m_strSubject = stream.readNEXString(); - this.m_strSender = stream.readNEXString(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_uiID: { - __typeName: 'uint32', - __typeValue: this.m_uiID - }, - m_idRecipient: { - __typeName: 'uint32', - __typeValue: this.m_idRecipient - }, - m_uiRecipientType: { - __typeName: 'uint32', - __typeValue: this.m_uiRecipientType - }, - m_uiParentID: { - __typeName: 'uint32', - __typeValue: this.m_uiParentID - }, - m_pidSender: { - __typeName: 'PID', - __typeValue: this.m_pidSender - }, - m_receptiontime: { - __typeName: 'DateTime', - __typeValue: this.m_receptiontime - }, - m_uiLifeTime: { - __typeName: 'uint32', - __typeValue: this.m_uiLifeTime - }, - m_uiFlags: { - __typeName: 'uint32', - __typeValue: this.m_uiFlags - }, - m_strSubject: { - __typeName: 'String', - __typeValue: this.m_strSubject - }, - m_strSender: { - __typeName: 'String', - __typeValue: this.m_strSender - } - }; - } -} - -class TextMessage extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(UserMessage); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_strTextBody = stream.readNEXString(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_strTextBody: { - __typeName: 'String', - __typeValue: this.m_strTextBody - } - }; - } -} - -class BinaryMessage extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(UserMessage); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_binaryBody = stream.readNEXQBuffer(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_binaryBody: { - __typeName: 'qBuffer', - __typeValue: this.m_binaryBody - } - }; - } -} - -NEXTypes.AnyDataHolder.addType('TextMessage', TextMessage); -NEXTypes.AnyDataHolder.addType('BinaryMessage', BinaryMessage); - -module.exports = { - UserMessage, - MessageRecipient, - TextMessage, - BinaryMessage -}; diff --git a/src/protocols/types/nintendo_notifications.js b/src/protocols/types/nintendo_notifications.js deleted file mode 100644 index 4235d9b..0000000 --- a/src/protocols/types/nintendo_notifications.js +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class NintendoNotificationEvent extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_uiType = stream.readUInt32LE(); - this.m_pidSender = stream.readPID(); - this.m_dataholder = stream.readNEXAnyDataHolder(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_uiType: { - __typeName: 'uint32', - __typeValue: this.m_uiType - }, - m_pidSender: { - __typeName: 'PID', - __typeValue: this.m_pidSender - }, - m_dataholder: { - __typeName: 'AnyDataHolder', - __typeValue: this.m_dataholder - } - }; - } -} - -class NintendoNotificationEventGeneral extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_u32Param = stream.readUInt32LE(); - this.m_u64Param1 = stream.readUInt64LE(); - this.m_u64Param2 = stream.readUInt64LE(); - this.m_strParam = stream.readNEXString(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_u32Param: { - __typeName: 'uint32', - __typeValue: this.m_u32Param - }, - m_u64Param1: { - __typeName: 'uint64', - __typeValue: this.m_u64Param1 - }, - m_u64Param2: { - __typeName: 'uint64', - __typeValue: this.m_u64Param2 - }, - m_strParam: { - __typeName: 'String', - __typeValue: this.m_strParam - } - }; - } -} -NEXTypes.AnyDataHolder.addType('NintendoNotificationEventGeneral', NintendoNotificationEventGeneral); - -class NintendoNotificationEventProfile extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(NEXTypes.Data); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_region = stream.readUInt8(); - this.m_country = stream.readUInt8(); - this.m_area = stream.readUInt8(); - this.m_language = stream.readUInt8(); - this.m_platform = stream.readUInt8(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - m_region: { - __typeName: 'uint8', - __typeValue: this.m_region - }, - m_country: { - __typeName: 'uint8', - __typeValue: this.m_country - }, - m_area: { - __typeName: 'uint8', - __typeValue: this.m_area - }, - m_language: { - __typeName: 'uint8', - __typeValue: this.m_language - }, - m_platform: { - __typeName: 'uint8', - __typeValue: this.m_platform - } - }; - } -} - -module.exports = { - NintendoNotificationEvent, - NintendoNotificationEventGeneral, - NintendoNotificationEventProfile -}; \ No newline at end of file diff --git a/src/protocols/types/notifications.js b/src/protocols/types/notifications.js deleted file mode 100644 index 5872351..0000000 --- a/src/protocols/types/notifications.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const semver = require('semver'); -const NEXTypes = require('../../types'); - -class NotificationEvent extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - // * This has a different structure on the Switch - // * On the Switch m_pidSource, m_uiParam1, m_uiParam2 and m_uiParam3 are uint64 - // * In revision 1 of the protocol on Switch, an additional m_mapParam Map is added - - const nexVersion = stream.connection.title.nex_version; - - this.m_pidSource = stream.readPID(); - this.m_uiType = stream.readUInt32LE(); - this.m_uiParam1 = stream.readUInt32LE(); - this.m_uiParam2 = stream.readUInt32LE(); - this.m_strParam = stream.readNEXString(); - - if (semver.gte(nexVersion, '3.4.0')) { - this.m_uiParam3 = stream.readUInt32LE(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - m_pidSource: { - __typeName: 'PID', - __typeValue: this.m_pidSource - }, - m_uiType: { - __typeName: 'uint32', - __typeValue: this.m_uiType - }, - m_uiParam1: { - __typeName: 'uint32', - __typeValue: this.m_uiParam1 - }, - m_uiParam2: { - __typeName: 'uint32', - __typeValue: this.m_uiParam2 - }, - m_strParam: { - __typeName: 'String', - __typeValue: this.m_strParam - } - }; - - if (this.m_uiParam3 !== undefined) { - data.m_uiParam3 = { - __typeName: 'uint32', - __typeValue: this.m_uiParam3 - }; - } - - return data; - } -} - -module.exports = { - NotificationEvent -}; diff --git a/src/protocols/types/ranking.js b/src/protocols/types/ranking.js deleted file mode 100644 index d3f56b2..0000000 --- a/src/protocols/types/ranking.js +++ /dev/null @@ -1,296 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ - -const semver = require('semver'); -const NEXTypes = require('../../types'); - -class RankingOrderParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.orderCalculation = stream.readUInt8(); - this.groupIndex = stream.readUInt8(); - this.groupNum = stream.readUInt8(); - this.timeScope = stream.readUInt8(); - this.offset = stream.readUInt32LE(); - this.length = stream.readUInt8(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - orderCalculation: { - __typeName: 'uint8', - __typeValue: this.orderCalculation - }, - groupIndex: { - __typeName: 'uint8', - __typeValue: this.groupIndex - }, - groupNum: { - __typeName: 'uint8', - __typeValue: this.groupNum - }, - timeScope: { - __typeName: 'uint8', - __typeValue: this.timeScope - }, - offset: { - __typeName: 'uint32', - __typeValue: this.offset - }, - length: { - __typeName: 'uint8', - __typeValue: this.length - } - }; - } -} - -class RankingRankData extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - const nexVersion = stream.connection.title.nex_ranking_version || stream.connection.title.nex_version; - - this.principalId = stream.readPID(); - this.uniqueId = stream.readUInt64LE(); - this.order = stream.readUInt32LE(); - this.category = stream.readUInt32LE(); - this.score = stream.readUInt32LE(); - this.groups = stream.readNEXBuffer(); // * Appears on some games as List - this.param = stream.readUInt64LE(); - this.commonData = stream.readNEXBuffer(); - - if (semver.gte(nexVersion, '3.6.0')) { - this.updateTime = stream.readNEXDateTime(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - principalId: { - __typeName: 'PID', - __typeValue: this.principalId - }, - uniqueId: { - __typeName: 'uint64', - __typeValue: this.uniqueId - }, - order: { - __typeName: 'uint32', - __typeValue: this.order - }, - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - score: { - __typeName: 'uint32', - __typeValue: this.score - }, - groups: { - __typeName: 'Buffer', - __typeValue: this.groups - }, - param: { - __typeName: 'uint64', - __typeValue: this.param - }, - commonData: { - __typeName: 'Buffer', - __typeValue: this.commonData - } - }; - - if (this.updateTime !== undefined) { - data.updateTime = { - __typeName: 'DateTime', - __typeValue: this.updateTime - }; - } - - return data; - } -} - -class RankingResult extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.rankDataList = stream.readNEXList(RankingRankData); - this.totalCount = stream.readUInt32LE(); - this.sinceTime = stream.readNEXDateTime(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - rankDataList: { - __typeName: 'List', - __typeValue: this.rankDataList - }, - totalCount: { - __typeName: 'uint32', - __typeValue: this.totalCount - }, - sinceTime: { - __typeName: 'DateTime', - __typeValue: this.sinceTime - } - }; - } -} - -class RankingCachedResult extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(RankingResult); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.createdTime = stream.readNEXDateTime(); - this.expiredTime = stream.readNEXDateTime(); - this.maxLength = stream.readUInt8(); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - createdTime: { - __typeName: 'DateTime', - __typeValue: this.createdTime - }, - expiredTime: { - __typeName: 'DateTime', - __typeValue: this.expiredTime - }, - maxLength: { - __typeName: 'uint8', - __typeValue: this.maxLength - } - }; - } -} - -class RankingStats extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.statsList = stream.readNEXList(stream.readDoubleLE); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - statsList: { - __typeName: 'List', - __typeValue: this.statsList - } - }; - } -} - -class RankingScoreData extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.category = stream.readUInt32LE(); - this.score = stream.readUInt32LE(); - this.orderBy = stream.readUInt8(); - this.updateMode = stream.readUInt8(); - this.groups = stream.readNEXList(stream.readUInt8); - this.param = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - score: { - __typeName: 'uint32', - __typeValue: this.score - }, - orderBy: { - __typeName: 'uint8', - __typeValue: this.orderBy - }, - updateMode: { - __typeName: 'uint8', - __typeValue: this.updateMode - }, - groups: { - __typeName: 'List', - __typeValue: this.groups - }, - param: { - __typeName: 'uint64', - __typeValue: this.param - }, - }; - } -} - -class RankingChangeAttributesParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.modificationFlag = stream.readUInt8(); - this.groups = stream.readNEXList(stream.readUInt8); - this.param = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - modificationFlag: { - __typeName: 'uint8', - __typeValue: this.modificationFlag - }, - groups: { - __typeName: 'List', - __typeValue: this.groups - }, - param: { - __typeName: 'uint64', - __typeValue: this.param - }, - }; - } -} - -module.exports = { - RankingOrderParam, - RankingRankData, - RankingResult, - RankingCachedResult, - RankingStats, - RankingScoreData, - RankingChangeAttributesParam -}; diff --git a/src/protocols/types/ranking_legacy.js b/src/protocols/types/ranking_legacy.js deleted file mode 100644 index af9ace0..0000000 --- a/src/protocols/types/ranking_legacy.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class RankingData extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.uniqueId = stream.readUInt32LE(); - this.pid = stream.readPID(); - this.order = stream.readUInt32LE(); - this.category = stream.readUInt32LE(); - this.scores = stream.readNEXList(stream.readUInt32LE); - this.unknown1 = stream.readUInt8(); - this.unknown2 = stream.readUInt32LE(); - this.commonData = stream.readNEXBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - }, - pid: { - __typeName: 'PID', - __typeValue: this.pid - }, - order: { - __typeName: 'uint32', - __typeValue: this.order - }, - category: { - __typeName: 'uint32', - __typeValue: this.category - }, - scores: { - __typeName: 'List', - __typeValue: this.scores - }, - unknown1: { - __typeName: 'uint8', - __typeValue: this.unknown1 - }, - unknown2: { - __typeName: 'uint32', - __typeValue: this.unknown2 - }, - commonData: { - __typeName: 'Buffer', - __typeValue: this.commonData - } - }; - } -} - -module.exports = { - RankingData -}; diff --git a/src/protocols/types/secure_connection.js b/src/protocols/types/secure_connection.js deleted file mode 100644 index 64c69fb..0000000 --- a/src/protocols/types/secure_connection.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class AccountExtraInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.token = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - token: { - __typeName: 'String', - __typeValue: this.token - } - }; - } -} -NEXTypes.AnyDataHolder.addType('AccountExtraInfo', AccountExtraInfo); - -class NintendoLoginData extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.token = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - token: { - __typeName: 'String', - __typeValue: this.token - } - }; - } -} -NEXTypes.AnyDataHolder.addType('NintendoLoginData', NintendoLoginData); - -class ConnectionData extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_StationUrl = stream.readNEXStructure(NEXTypes.StationURL); - this.m_ConnectionID = stream.readUInt32LE(); - } - - toJSON() { - return { - m_StationUrl: { - __typeName: 'StationURL', - __typeValue: this.m_StationUrl - }, - m_ConnectionID: { - __typeName: 'uint32', - __typeValue: this.m_ConnectionID - }, - }; - } -} - -module.exports = { - AccountExtraInfo, - NintendoLoginData, - ConnectionData -}; diff --git a/src/protocols/types/service_item_tkcd.js b/src/protocols/types/service_item_tkcd.js deleted file mode 100644 index b637cdf..0000000 --- a/src/protocols/types/service_item_tkcd.js +++ /dev/null @@ -1,1773 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class ServiceItemHttpGetParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.url = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - url: { - __typeName: 'String', - __typeValue: this.url - } - }; - } -} - -class ServiceItemHttpGetResponse extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.response = stream.readNEXQBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - response: { - __typeName: 'qBuffer', - __typeValue: this.response - } - }; - } -} - -class ServiceItemEShopResponse extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.httpStatus = stream.readUInt32LE(); - this.errorCode = stream.readUInt32LE(); - this.correlationId = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - httpStatus: { - __typeName: 'uint32', - __typeValue: this.httpStatus - }, - errorCode: { - __typeName: 'uint32', - __typeValue: this.errorCode - }, - correlationId: { - __typeName: 'String', - __typeValue: this.correlationId - } - }; - } -} - -class ServiceItemAmount extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.formattedAmount = stream.readNEXString(); - this.currency = stream.readNEXString(); - this.rawValue = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - formattedAmount: { - __typeName: 'String', - __typeValue: this.formattedAmount - }, - currency: { - __typeName: 'String', - __typeValue: this.currency - }, - rawValue: { - __typeName: 'String', - __typeValue: this.rawValue - } - }; - } -} - -class ServiceItemPurchaseServiceItemParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.itemCode = stream.readNEXString(); - this.priceId = stream.readNEXString(); - this.referenceId = stream.readNEXString(); - this.balance = stream.readNEXString(); - this.itemName = stream.readNEXString(); - this.ecServiceToken = stream.readNEXString(); - this.language = stream.readNEXString(); - this.uniqueId = stream.readUInt32LE(); - - if (this._structureHeader.version >= 1) { - this.platform = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - priceId: { - __typeName: 'String', - __typeValue: this.priceId - }, - referenceId: { - __typeName: 'String', - __typeValue: this.referenceId - }, - balance: { - __typeName: 'String', - __typeValue: this.balance - }, - itemName: { - __typeName: 'String', - __typeValue: this.itemName - }, - ecServiceToken: { - __typeName: 'String', - __typeValue: this.ecServiceToken - }, - language: { - __typeName: 'String', - __typeValue: this.language - }, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - } - }; - - if (this.platform !== undefined) { - data.platform = { - __typeName: 'uint8', - __typeValue: this.platform - }; - } - - return data; - } -} - -class ServiceItemPurchaseInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.transactionId = stream.readNEXString(); - this.extTransactionId = stream.readNEXString(); - this.itemCode = stream.readNEXString(); - this.postBalance = stream.readNEXStructure(ServiceItemAmount); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - transactionId: { - __typeName: 'String', - __typeValue: this.transactionId - }, - extTransactionId: { - __typeName: 'String', - __typeValue: this.extTransactionId - }, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - postBalance: { - __typeName: 'ServiceItemAmount', - __typeValue: this.postBalance - } - }; - } -} - -class ServiceItemPurchaseServiceItemResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullablePurchaseInfo = stream.readNEXList(ServiceItemPurchaseInfo); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - nullablePurchaseInfo: { - __typeName: 'List', - __typeValue: this.nullablePurchaseInfo - } - }; - } -} - -class ServiceItemListServiceItemParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.language = stream.readNEXString(); - this.offset = stream.readUInt32LE(); - this.size = stream.readUInt32LE(); - this.isBalanceAvailable = stream.readBoolean(); - this.uniqueId = stream.readUInt32LE(); - - if (this._structureHeader.version >= 1) { - this.platform = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - language: { - __typeName: 'String', - __typeValue: this.language - }, - offset: { - __typeName: 'uint32', - __typeValue: this.offset - }, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - isBalanceAvailable: { - __typeName: 'boolean', - __typeValue: this.isBalanceAvailable - }, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - } - }; - - if (this.platform !== undefined) { - data.platform = { - __typeName: 'uint8', - __typeValue: this.platform - }; - } - - return data; - } -} - -class ServiceItemLimitation extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.limitationType = stream.readUInt32LE(); - this.limitationValue = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - limitationType: { - __typeName: 'uint32', - __typeValue: this.limitationType - }, - limitationValue: { - __typeName: 'uint32', - __typeValue: this.limitationValue - } - }; - } -} - -class ServiceItemAttribute extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.name = stream.readNEXString(); - this.value = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - name: { - __typeName: 'String', - __typeValue: this.name - }, - value: { - __typeName: 'String', - __typeValue: this.value - } - }; - } -} - -class ServiceItemListItem extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.itemCode = stream.readNEXString(); - this.regularPrice = stream.readNEXStructure(ServiceItemAmount); - this.taxExcluded = stream.readBoolean(); - this.initialPurchaseOnly = stream.readBoolean(); - this.limitation = stream.readNEXStructure(ServiceItemLimitation); - this.attributes = stream.readNEXList(ServiceItemAttribute); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - regularPrice: { - __typeName: 'ServiceItemAmount', - __typeValue: this.regularPrice - }, - taxExcluded: { - __typeName: 'boolean', - __typeValue: this.taxExcluded - }, - initialPurchaseOnly: { - __typeName: 'boolean', - __typeValue: this.initialPurchaseOnly - }, - limitation: { - __typeName: 'ServiceItemLimitation', - __typeValue: this.limitation - }, - attributes: { - __typeName: 'List', - __typeValue: this.attributes - } - }; - } -} - -class ServiceItemCatalog extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.totalSize = stream.readUInt32LE(); - this.offset = stream.readUInt32LE(); - this.listItems = stream.readNEXList(ServiceItemListItem); - this.isBalanceAvailable = stream.readBoolean(); - this.balance = stream.readNEXStructure(ServiceItemAmount); - - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - totalSize: { - __typeName: 'uint32', - __typeValue: this.totalSize - }, - offset: { - __typeName: 'uint32', - __typeValue: this.offset - }, - listItems: { - __typeName: 'List', - __typeValue: this.listItems - }, - isBalanceAvailable: { - __typeName: 'boolean', - __typeValue: this.isBalanceAvailable - }, - balance: { - __typeName: 'ServiceItemAmount', - __typeValue: this.balance - } - }; - } -} - -class ServiceItemListServiceItemResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullableCatalog = stream.readNEXList(ServiceItemCatalog); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - nullableCatalog: { - __typeName: 'List', - __typeValue: this.nullableCatalog - } - }; - } -} - -class ServiceItemGetBalanceParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.language = stream.readNEXString(); - this.uniqueId = stream.readUInt32LE(); - - if (this._structureHeader.version >= 1) { - this.platform = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - language: { - __typeName: 'String', - __typeValue: this.language - }, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - } - }; - - if (this.platform !== undefined) { - data.platform = { - __typeName: 'uint8', - __typeValue: this.platform - }; - } - - return data; - } -} - -class ServiceItemGetBalanceResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullableBalance = stream.readNEXList(ServiceItemAmount); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - nullableBalance: { - __typeName: 'List', - __typeValue: this.nullableBalance - } - }; - } -} - -class ServiceItemGetPrepurchaseInfoParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.itemCode = stream.readNEXString(); - this.referenceId = stream.readNEXString(); - this.limitation = stream.readNEXStructure(ServiceItemLimitation); - this.language = stream.readNEXString(); - this.uniqueId = stream.readUInt32LE(); - - if (this._structureHeader.version >= 1) { - this.platform = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - referenceId: { - __typeName: 'String', - __typeValue: this.referenceId - }, - limitation: { - __typeName: 'ServiceItemLimitation', - __typeValue: this.limitation - }, - language: { - __typeName: 'String', - __typeValue: this.language - }, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - } - }; - - if (this.platform !== undefined) { - data.platform = { - __typeName: 'uint8', - __typeValue: this.platform - }; - } - - return data; - } -} - -class ServiceItemPrepurchaseRightInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.limitationType = stream.readUInt32LE(); - this.acquiredCount = stream.readUInt32LE(); - this.usedCount = stream.readUInt32LE(); - this.expiryDate = stream.readUInt32LE(); - this.expiredCount = stream.readUInt32LE(); - this.expiryCounts = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - limitationType: { - __typeName: 'uint32', - __typeValue: this.limitationType - }, - acquiredCount: { - __typeName: 'uint32', - __typeValue: this.acquiredCount - }, - usedCount: { - __typeName: 'uint32', - __typeValue: this.usedCount - }, - expiryDate: { - __typeName: 'uint32', - __typeValue: this.expiryDate - }, - expiredCount: { - __typeName: 'uint32', - __typeValue: this.expiredCount - }, - expiryCounts: { - __typeName: 'List', - __typeValue: this.expiryCounts - } - }; - } -} - -class ServiceItemPrepurchaseInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.itemCode = stream.readNEXString(); - this.priceId = stream.readNEXString(); - this.regularPrice = stream.readNEXStructure(ServiceItemAmount); - this.isTaxAvailable = stream.readBoolean(); - this.taxAmount = stream.readNEXStructure(ServiceItemAmount); - this.totalAmount = stream.readNEXStructure(ServiceItemAmount); - this.currentBalance = stream.readNEXStructure(ServiceItemAmount); - this.postBalance = stream.readNEXStructure(ServiceItemAmount); - this.currentRightInfo = stream.readNEXStructure(ServiceItemPrepurchaseRightInfo); - this.postRightInfo = stream.readNEXStructure(ServiceItemPrepurchaseRightInfo); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - priceId: { - __typeName: 'String', - __typeValue: this.priceId - }, - regularPrice: { - __typeName: 'ServiceItemAmount', - __typeValue: this.regularPrice - }, - isTaxAvailable: { - __typeName: 'boolean', - __typeValue: this.isTaxAvailable - }, - taxAmount: { - __typeName: 'ServiceItemAmount', - __typeValue: this.taxAmount - }, - totalAmount: { - __typeName: 'ServiceItemAmount', - __typeValue: this.totalAmount - }, - currentBalance: { - __typeName: 'ServiceItemAmount', - __typeValue: this.currentBalance - }, - postBalance: { - __typeName: 'ServiceItemAmount', - __typeValue: this.postBalance - }, - currentRightInfo: { - __typeName: 'ServiceItemPrepurchaseRightInfo', - __typeValue: this.currentRightInfo - }, - postRightInfo: { - __typeName: 'ServiceItemPrepurchaseRightInfo', - __typeValue: this.postRightInfo - } - }; - } -} - -class ServiceItemGetPrepurchaseInfoResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullablePrepurchaseInfo = stream.readNEXList(ServiceItemPrepurchaseInfo); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - nullablePrepurchaseInfo: { - __typeName: 'List', - __typeValue: this.nullablePrepurchaseInfo - } - }; - } -} - -class ServiceItemGetServiceItemRightParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.referenceId = stream.readNEXString(); - this.deviceId = stream.readNEXString(); - this.uniqueId = stream.readUInt32LE(); - this.itemGroup = stream.readUInt8(); - - if (this._structureHeader.version >= 1) { - this.platform = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - referenceId: { - __typeName: 'String', - __typeValue: this.referenceId - }, - deviceId: { - __typeName: 'String', - __typeValue: this.deviceId - }, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - }, - itemGroup: { - __typeName: 'uint8', - __typeValue: this.itemGroup - } - }; - - if (this.platform !== undefined) { - data.platform = { - __typeName: 'uint8', - __typeValue: this.platform - }; - } - - return data; - } -} - -class ServiceItemRightBinary extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.useType = stream.readUInt8(); - this.rightBinary = stream.readNEXQBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - useType: { - __typeName: 'uint8', - __typeValue: this.useType - }, - rightBinary: { - __typeName: 'qBuffer', - __typeValue: this.rightBinary - } - }; - } -} - -class ServiceItemAccountRight extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.pid = stream.readPID(); - this.limitation = stream.readNEXStructure(ServiceItemLimitation); - this.rightBinaries = stream.readNEXList(ServiceItemRightBinary); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - pid: { - __typeName: 'PID', - __typeValue: this.pid - }, - limitation: { - __typeName: 'ServiceItemLimitation', - __typeValue: this.limitation - }, - rightBinaries: { - __typeName: 'List', - __typeValue: this.rightBinaries - } - }; - } -} - -class ServiceItemAccountRightTime extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemAccountRight); - } - - // * This type contains nothing - parse() { } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })) - }; - } -} - -class ServiceItemAccountRightConsumption extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemAccountRight); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.usedCount = stream.readUInt32LE(); - this.expiredCount = stream.readUInt32LE(); - this.expiryCounts = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - usedCount: { - __typeName: 'uint32', - __typeValue: this.usedCount - }, - expiredCount: { - __typeName: 'uint32', - __typeValue: this.expiredCount - }, - expiryCounts: { - __typeName: 'List', - __typeValue: this.expiryCounts - } - }; - } -} - -class ServiceItemRightInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.referenceId = stream.readNEXString(); - this.referenceIdType = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - referenceId: { - __typeName: 'String', - __typeValue: this.referenceId - }, - referenceIdType: { - __typeName: 'uint32', - __typeValue: this.referenceIdType - } - }; - } -} - -class ServiceItemRightTimeInfo extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemRightInfo); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.accountRights = stream.readNEXList(ServiceItemAccountRightTime); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - accountRights: { - __typeName: 'List', - __typeValue: this.accountRights - } - }; - } -} - -class ServiceItemRightConsumptionInfo extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemRightInfo); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.accountRights = stream.readNEXList(ServiceItemAccountRightConsumption); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - accountRights: { - __typeName: 'List', - __typeValue: this.accountRights - } - }; - } -} - -class ServiceItemRightInfos extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.supportId = stream.readNEXString(); - this.consumptionRightInfos = stream.readNEXList(ServiceItemRightConsumptionInfo); - this.additionalTimeRightInfos = stream.readNEXList(ServiceItemRightTimeInfo); - this.permanentRightInfos = stream.readNEXList(ServiceItemRightTimeInfo); - this.alreadyPurchasedInitialOnlyItem = stream.readBoolean(); - - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - supportId: { - __typeName: 'String', - __typeValue: this.supportId - }, - consumptionRightInfos: { - __typeName: 'List', - __typeValue: this.consumptionRightInfos - }, - additionalTimeRightInfos: { - __typeName: 'List', - __typeValue: this.additionalTimeRightInfos - }, - permanentRightInfos: { - __typeName: 'List', - __typeValue: this.permanentRightInfos - }, - alreadyPurchasedInitialOnlyItem: { - __typeName: 'boolean', - __typeValue: this.alreadyPurchasedInitialOnlyItem - } - }; - } -} - -class ServiceItemGetServiceItemRightResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullableRightInfos = stream.readNEXList(ServiceItemRightInfos); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - nullableRightInfos: { - __typeName: 'List', - __typeValue: this.nullableRightInfos - } - }; - } -} - -class ServiceItemGetPurchaseHistoryParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.language = stream.readNEXString(); - this.offset = stream.readUInt32LE(); - this.size = stream.readUInt32LE(); - this.uniqueId = stream.readUInt32LE(); - - if (this._structureHeader.version >= 1) { - this.platform = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - language: { - __typeName: 'String', - __typeValue: this.language - }, - offset: { - __typeName: 'uint32', - __typeValue: this.offset - }, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - } - }; - - if (this.platform !== undefined) { - data.platform = { - __typeName: 'uint8', - __typeValue: this.platform - }; - } - - return data; - } -} - -class ServiceItemTransaction extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.transactionId = stream.readNEXString(); - this.extTransactionId = stream.readNEXString(); - this.time = stream.readNEXDateTime(); - this.transactionType = stream.readUInt32LE(); - this.transactionDescription = stream.readNEXString(); - this.transactionAmount = stream.readNEXStructure(ServiceItemAmount); - this.itemCode = stream.readNEXString(); - this.referenceId = stream.readNEXString(); - this.limitation = stream.readNEXStructure(ServiceItemLimitation); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - transactionId: { - __typeName: 'String', - __typeValue: this.transactionId - }, - extTransactionId: { - __typeName: 'String', - __typeValue: this.extTransactionId - }, - time: { - __typeName: 'DateTime', - __typeValue: this.time - }, - transactionType: { - __typeName: 'uint32', - __typeValue: this.transactionType - }, - transactionDescription: { - __typeName: 'String', - __typeValue: this.transactionDescription - }, - transactionAmount: { - __typeName: 'ServiceItemAmount', - __typeValue: this.transactionAmount - }, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - referenceId: { - __typeName: 'String', - __typeValue: this.referenceId - }, - limitation: { - __typeName: 'ServiceItemLimitation', - __typeValue: this.limitation - } - }; - } -} - -class ServiceItemPurchaseHistory extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.totalSize = stream.readUInt32LE(); - this.offset = stream.readUInt32LE(); - this.transactions = stream.readNEXList(ServiceItemTransaction); - - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - supportId: { - __typeName: 'String', - __typeValue: this.supportId - }, - transactions: { - __typeName: 'List', - __typeValue: this.transactions - } - }; - } -} - -class ServiceItemGetPurchaseHistoryResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullablePurchaseHistory = stream.readNEXList(ServiceItemPurchaseHistory); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - nullablePurchaseHistory: { - __typeName: 'List', - __typeValue: this.nullablePurchaseHistory - } - }; - } -} - -class ServiceItemLawMessage extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.isMessageRequired = stream.readBoolean(); - this.lawMessage = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - isMessageRequired: { - __typeName: 'boolean', - __typeValue: this.isMessageRequired - }, - lawMessage: { - __typeName: 'String', - __typeValue: this.lawMessage - } - }; - } -} - -class ServiceItemGetLawMessageParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.language = stream.readNEXString(); - this.uniqueId = stream.readUInt32LE(); - - if (this._structureHeader.version >= 1) { - this.platform = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - language: { - __typeName: 'String', - __typeValue: this.language - }, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - } - }; - - if (this.platform !== undefined) { - data.platform = { - __typeName: 'uint8', - __typeValue: this.platform - }; - } - - return data; - } -} - -class ServiceItemGetLawMessageResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullableLawMessage = stream.readNEXList(ServiceItemLawMessage); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - nullableLawMessage: { - __typeName: 'List', - __typeValue: this.nullableLawMessage - } - }; - } -} - -class ServiceItemPostRightBinaryByAccountParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.referenceId = stream.readNEXString(); - this.useType = stream.readUInt8(); - this.rightBinary = stream.readNEXQBuffer(); - this.logMessage = stream.readNEXString(); - this.uniqueId = stream.readUInt32LE(); - - if (this._structureHeader.version >= 1) { - this.platform = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - referenceId: { - __typeName: 'String', - __typeValue: this.referenceId - }, - useType: { - __typeName: 'uint8', - __typeValue: this.useType - }, - rightBinary: { - __typeName: 'qBuffer', - __typeValue: this.rightBinary - }, - logMessage: { - __typeName: 'String', - __typeValue: this.logMessage - }, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - } - }; - - if (this.platform !== undefined) { - data.platform = { - __typeName: 'uint8', - __typeValue: this.platform - }; - } - - return data; - } -} - -class ServiceItemPostRightBinaryResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - // * This type contains nothing - parse() { } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })) - }; - } -} - -class ServiceItemUseServiceItemByAccountParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.referenceIdForUse = stream.readNEXString(); - this.referenceIdForRightBinary = stream.readNEXString(); - this.useType = stream.readUInt8(); - this.useNumber = stream.readUInt8(); - this.rightBinary = stream.readNEXQBuffer(); - this.logMessage = stream.readNEXString(); - this.uniqueId = stream.readUInt32LE(); - - if (this._structureHeader.version >= 1) { - this.platform = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - referenceIdForUse: { - __typeName: 'String', - __typeValue: this.referenceIdForUse - }, - referenceIdForRightBinary: { - __typeName: 'String', - __typeValue: this.referenceIdForRightBinary - }, - useType: { - __typeName: 'uint8', - __typeValue: this.useType - }, - useNumber: { - __typeName: 'uint8', - __typeValue: this.useNumber - }, - rightBinary: { - __typeName: 'qBuffer', - __typeValue: this.rightBinary - }, - logMessage: { - __typeName: 'String', - __typeValue: this.logMessage - }, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - } - }; - - if (this.platform !== undefined) { - data.platform = { - __typeName: 'uint8', - __typeValue: this.platform - }; - } - - return data; - } -} - -class ServiceItemUsedInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.acquiredCount = stream.readUInt32LE(); - this.usedCount = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - acquiredCount: { - __typeName: 'uint32', - __typeValue: this.acquiredCount - }, - usedCount: { - __typeName: 'uint32', - __typeValue: this.usedCount - } - }; - } -} - -class ServiceItemUseServiceItemResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullableUsedInfo = stream.readNEXList(ServiceItemUsedInfo); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - nullableUsedInfo: { - __typeName: 'List', - __typeValue: this.nullableUsedInfo - } - }; - } -} - -class ServiceItemAcquireServiceItemByAccountParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.referenceIdForAcquisition = stream.readNEXString(); - this.referenceIdForRightBinary = stream.readNEXString(); - this.useType = stream.readUInt8(); - this.limitationType = stream.readUInt32LE(); - this.limitationValue = stream.readUInt32LE(); - this.rightBinary = stream.readNEXQBuffer(); - this.logMessage = stream.readNEXString(); - this.uniqueId = stream.readUInt32LE(); - - if (this._structureHeader.version >= 1) { - this.platform = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - referenceIdForAcquisition: { - __typeName: 'String', - __typeValue: this.referenceIdForAcquisition - }, - referenceIdForRightBinary: { - __typeName: 'String', - __typeValue: this.referenceIdForRightBinary - }, - useType: { - __typeName: 'uint8', - __typeValue: this.useType - }, - limitationType: { - __typeName: 'uint32', - __typeValue: this.limitationType - }, - limitationValue: { - __typeName: 'uint32', - __typeValue: this.limitationValue - }, - rightBinary: { - __typeName: 'qBuffer', - __typeValue: this.rightBinary - }, - logMessage: { - __typeName: 'String', - __typeValue: this.logMessage - }, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - } - }; - - if (this.platform !== undefined) { - data.platform = { - __typeName: 'uint8', - __typeValue: this.platform - }; - } - - return data; - } -} - -class ServiceItemAcquireServiceItemResponse extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.limitationType = stream.readUInt32LE(); - this.acquiredCount = stream.readUInt32LE(); - this.usedCount = stream.readUInt32LE(); - this.expiryDate = stream.readUInt32LE(); - this.expiredCount = stream.readUInt32LE(); - this.expiryCounts = stream.readNEXList(stream.readUInt32LE); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - limitationType: { - __typeName: 'uint32', - __typeValue: this.limitationType - }, - acquiredCount: { - __typeName: 'uint32', - __typeValue: this.acquiredCount - }, - usedCount: { - __typeName: 'uint32', - __typeValue: this.usedCount - }, - expiryDate: { - __typeName: 'uint32', - __typeValue: this.expiryDate - }, - expiredCount: { - __typeName: 'uint32', - __typeValue: this.expiredCount - }, - expiryCounts: { - __typeName: 'List', - __typeValue: this.expiryCounts - } - }; - } -} - -class ServiceItemGetSupportIdParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.uniqueId = stream.readUInt32LE(); - - if (this._structureHeader.version >= 1) { - this.platform = stream.readUInt8(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - uniqueId: { - __typeName: 'uint32', - __typeValue: this.uniqueId - } - }; - - if (this.platform !== undefined) { - data.platform = { - __typeName: 'uint8', - __typeValue: this.platform - }; - } - - return data; - } -} - -class ServiceItemGetNoticeParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.scheduleType = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - scheduleType: { - __typeName: 'uint32', - __typeValue: this.scheduleType - } - }; - } -} - -class ServiceItemNotice extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.scheduleId = stream.readUInt64LE(); - this.scheduleType = stream.readUInt32LE(); - this.paramInt = stream.readInt32LE(); - this.paramString = stream.readNEXString(); - this.paramBinary = stream.readNEXQBuffer(); - this.timeBegin = stream.readNEXDateTime(); - this.timeEnd = stream.readNEXDateTime(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - scheduleId: { - __typeName: 'uint64', - __typeValue: this.scheduleId - }, - scheduleType: { - __typeName: 'uint32', - __typeValue: this.scheduleType - }, - paramInt: { - __typeName: 'sint32', - __typeValue: this.paramInt - }, - paramString: { - __typeName: 'String', - __typeValue: this.paramString - }, - paramBinary: { - __typeName: 'qBuffer', - __typeValue: this.paramBinary - }, - timeBegin: { - __typeName: 'DateTime', - __typeValue: this.timeBegin - }, - timeEnd: { - __typeName: 'DateTime', - __typeValue: this.timeEnd - } - }; - } -} - -class ServiceItemUserInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.applicationBuffer = stream.readNEXQBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - applicationBuffer: { - __typeName: 'qBuffer', - __typeValue: this.applicationBuffer - } - }; - } -} - -module.exports = { - ServiceItemHttpGetParam, - ServiceItemHttpGetResponse, - ServiceItemEShopResponse, - ServiceItemAmount, - ServiceItemPurchaseServiceItemParam, - ServiceItemPurchaseInfo, - ServiceItemPurchaseServiceItemResponse, - ServiceItemListServiceItemParam, - ServiceItemLimitation, - ServiceItemAttribute, - ServiceItemListItem, - ServiceItemCatalog, - ServiceItemListServiceItemResponse, - ServiceItemGetBalanceParam, - ServiceItemGetBalanceResponse, - ServiceItemGetPrepurchaseInfoParam, - ServiceItemPrepurchaseRightInfo, - ServiceItemPrepurchaseInfo, - ServiceItemGetPrepurchaseInfoResponse, - ServiceItemGetServiceItemRightParam, - ServiceItemRightBinary, - ServiceItemAccountRight, - ServiceItemAccountRightTime, - ServiceItemAccountRightConsumption, - ServiceItemRightInfo, - ServiceItemRightTimeInfo, - ServiceItemRightConsumptionInfo, - ServiceItemRightInfos, - ServiceItemGetServiceItemRightResponse, - ServiceItemGetPurchaseHistoryParam, - ServiceItemTransaction, - ServiceItemPurchaseHistory, - ServiceItemGetPurchaseHistoryResponse, - ServiceItemLawMessage, - ServiceItemGetLawMessageParam, - ServiceItemGetLawMessageResponse, - ServiceItemPostRightBinaryByAccountParam, - ServiceItemPostRightBinaryResponse, - ServiceItemUseServiceItemByAccountParam, - ServiceItemUsedInfo, - ServiceItemUseServiceItemResponse, - ServiceItemAcquireServiceItemByAccountParam, - ServiceItemAcquireServiceItemResponse, - ServiceItemGetSupportIdParam, - ServiceItemGetNoticeParam, - ServiceItemNotice, - ServiceItemUserInfo -}; diff --git a/src/protocols/types/service_item_wii_sports_club.js b/src/protocols/types/service_item_wii_sports_club.js deleted file mode 100644 index eef1113..0000000 --- a/src/protocols/types/service_item_wii_sports_club.js +++ /dev/null @@ -1,1155 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class ServiceItemHttpGetParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.url = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - url: { - __typeName: 'String', - __typeValue: this.url - } - }; - } -} - -class ServiceItemHttpGetResponse extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.response = stream.readNEXQBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - response: { - __typeName: 'qBuffer', - __typeValue: this.response - } - }; - } -} - -class ServiceItemEShopResponse extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.httpStatus = stream.readUInt32LE(); - this.errorCode = stream.readUInt32LE(); - this.correlationId = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - httpStatus: { - __typeName: 'uint32', - __typeValue: this.httpStatus - }, - errorCode: { - __typeName: 'uint32', - __typeValue: this.errorCode - }, - correlationId: { - __typeName: 'String', - __typeValue: this.correlationId - } - }; - } -} - -class ServiceItemAmount extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.formattedAmount = stream.readNEXString(); - this.currency = stream.readNEXString(); - this.rawValue = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - formattedAmount: { - __typeName: 'String', - __typeValue: this.formattedAmount - }, - currency: { - __typeName: 'String', - __typeValue: this.currency - }, - rawValue: { - __typeName: 'String', - __typeValue: this.rawValue - } - }; - } -} - -class ServiceItemPurchaseServiceItemParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.itemCode = stream.readNEXString(); - this.priceId = stream.readNEXString(); - this.referenceId = stream.readNEXString(); - this.balance = stream.readNEXString(); - this.itemName = stream.readNEXString(); - this.ecServiceToken = stream.readNEXString(); - this.language = stream.readNEXString(); - this.titleId = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - priceId: { - __typeName: 'String', - __typeValue: this.priceId - }, - referenceId: { - __typeName: 'String', - __typeValue: this.referenceId - }, - balance: { - __typeName: 'String', - __typeValue: this.balance - }, - itemName: { - __typeName: 'String', - __typeValue: this.itemName - }, - ecServiceToken: { - __typeName: 'String', - __typeValue: this.ecServiceToken - }, - language: { - __typeName: 'String', - __typeValue: this.language - }, - titleId: { - __typeName: 'String', - __typeValue: this.titleId - } - }; - } -} - -class ServiceItemPurchaseInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.transactionId = stream.readNEXString(); - this.extTransactionId = stream.readNEXString(); - this.itemCode = stream.readNEXString(); - this.postBalance = stream.readNEXStructure(ServiceItemAmount); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - transactionId: { - __typeName: 'String', - __typeValue: this.transactionId - }, - extTransactionId: { - __typeName: 'String', - __typeValue: this.extTransactionId - }, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - postBalance: { - __typeName: 'ServiceItemAmount', - __typeValue: this.postBalance - } - }; - } -} - -class ServiceItemPurchaseServiceItemResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullablePurchaseInfo = stream.readNEXList(ServiceItemPurchaseInfo); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - nullablePurchaseInfo: { - __typeName: 'List', - __typeValue: this.nullablePurchaseInfo - } - }; - } -} - -class ServiceItemListServiceItemParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.language = stream.readNEXString(); - this.offset = stream.readUInt32LE(); - this.size = stream.readUInt32LE(); - this.titleId = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - language: { - __typeName: 'String', - __typeValue: this.language - }, - offset: { - __typeName: 'uint32', - __typeValue: this.offset - }, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - titleId: { - __typeName: 'String', - __typeValue: this.titleId - } - }; - } -} - -class ServiceItemLimitation extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.limitationType = stream.readUInt32LE(); - this.limitationValue = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - limitationType: { - __typeName: 'uint32', - __typeValue: this.limitationType - }, - limitationValue: { - __typeName: 'uint32', - __typeValue: this.limitationValue - } - }; - } -} - -class ServiceItemAttribute extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.name = stream.readNEXString(); - this.value = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - name: { - __typeName: 'String', - __typeValue: this.name - }, - value: { - __typeName: 'String', - __typeValue: this.value - } - }; - } -} - -class ServiceItemListItem extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.itemCode = stream.readNEXString(); - this.regularPrice = stream.readNEXStructure(ServiceItemAmount); - this.taxExcluded = stream.readBoolean(); - this.initialPurchaseOnly = stream.readBoolean(); - this.limitation = stream.readNEXStructure(ServiceItemLimitation); - this.attributes = stream.readNEXList(ServiceItemAttribute); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - regularPrice: { - __typeName: 'ServiceItemAmount', - __typeValue: this.regularPrice - }, - taxExcluded: { - __typeName: 'boolean', - __typeValue: this.taxExcluded - }, - initialPurchaseOnly: { - __typeName: 'boolean', - __typeValue: this.initialPurchaseOnly - }, - limitation: { - __typeName: 'ServiceItemLimitation', - __typeValue: this.limitation - }, - attributes: { - __typeName: 'List', - __typeValue: this.attributes - } - }; - } -} - -class ServiceItemCatalog extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.totalSize = stream.readUInt32LE(); - this.offset = stream.readUInt32LE(); - this.listItems = stream.readNEXList(ServiceItemListItem); - - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - totalSize: { - __typeName: 'uint32', - __typeValue: this.totalSize - }, - offset: { - __typeName: 'uint32', - __typeValue: this.offset - }, - listItems: { - __typeName: 'List', - __typeValue: this.listItems - } - }; - } -} - -class ServiceItemListServiceItemResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullableCatalog = stream.readNEXList(ServiceItemCatalog); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - nullableCatalog: { - __typeName: 'List', - __typeValue: this.nullableCatalog - } - }; - } -} - -class ServiceItemGetBalanceParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.language = stream.readNEXString(); - this.titleId = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - language: { - __typeName: 'String', - __typeValue: this.language - }, - titleId: { - __typeName: 'String', - __typeValue: this.titleId - } - }; - } -} - -class ServiceItemGetBalanceResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullableBalance = stream.readNEXList(ServiceItemAmount); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - nullableBalance: { - __typeName: 'List', - __typeValue: this.nullableBalance - } - }; - } -} - -class ServiceItemGetPrepurchaseInfoParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.itemCode = stream.readNEXString(); - this.language = stream.readNEXString(); - this.titleId = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - language: { - __typeName: 'String', - __typeValue: this.language - }, - titleId: { - __typeName: 'String', - __typeValue: this.titleId - } - }; - } -} - -class ServiceItemPrepurchaseInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.itemCode = stream.readNEXString(); - this.priceId = stream.readNEXString(); - this.regularPrice = stream.readNEXStructure(ServiceItemAmount); - this.isTaxAvailable = stream.readBoolean(); - this.taxAmount = stream.readNEXStructure(ServiceItemAmount); - this.totalAmount = stream.readNEXStructure(ServiceItemAmount); - this.currentBalance = stream.readNEXStructure(ServiceItemAmount); - this.postBalance = stream.readNEXStructure(ServiceItemAmount); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - priceId: { - __typeName: 'String', - __typeValue: this.priceId - }, - regularPrice: { - __typeName: 'ServiceItemAmount', - __typeValue: this.regularPrice - }, - isTaxAvailable: { - __typeName: 'boolean', - __typeValue: this.isTaxAvailable - }, - taxAmount: { - __typeName: 'ServiceItemAmount', - __typeValue: this.taxAmount - }, - totalAmount: { - __typeName: 'ServiceItemAmount', - __typeValue: this.totalAmount - }, - currentBalance: { - __typeName: 'ServiceItemAmount', - __typeValue: this.currentBalance - }, - postBalance: { - __typeName: 'ServiceItemAmount', - __typeValue: this.postBalance - } - }; - } -} - -class ServiceItemGetPrepurchaseInfoResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullablePrepurchaseInfo = stream.readNEXList(ServiceItemPrepurchaseInfo); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - nullablePrepurchaseInfo: { - __typeName: 'List', - __typeValue: this.nullablePrepurchaseInfo - } - }; - } -} - -class ServiceItemGetServiceItemRightParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.referenceId = stream.readNEXString(); - this.titleId = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - referenceId: { - __typeName: 'String', - __typeValue: this.referenceId - }, - titleId: { - __typeName: 'String', - __typeValue: this.titleId - } - }; - } -} - -class ServiceItemAccountRight extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.pid = stream.readPID(); - this.limitation = stream.readNEXStructure(ServiceItemLimitation); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - pid: { - __typeName: 'PID', - __typeValue: this.pid - }, - limitation: { - __typeName: 'ServiceItemLimitation', - __typeValue: this.limitation - } - }; - } -} - -class ServiceItemRightInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.referenceId = stream.readNEXString(); - this.accountRights = stream.readNEXList(ServiceItemAccountRight); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - referenceId: { - __typeName: 'String', - __typeValue: this.referenceId - }, - accountRights: { - __typeName: 'List', - __typeValue: this.accountRights - } - }; - } -} - -class ServiceItemRightInfos extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.rightInfos = stream.readNEXList(ServiceItemRightInfo); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - rightInfos: { - __typeName: 'List', - __typeValue: this.rightInfos - } - }; - } -} - -class ServiceItemGetServiceItemRightResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullableRightInfos = stream.readNEXList(ServiceItemRightInfos); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - nullableRightInfos: { - __typeName: 'List', - __typeValue: this.nullableRightInfos - } - }; - } -} - -class ServiceItemGetPurchaseHistoryParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.language = stream.readNEXString(); - this.offset = stream.readUInt32LE(); - this.size = stream.readUInt32LE(); - this.titleId = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - language: { - __typeName: 'String', - __typeValue: this.language - }, - offset: { - __typeName: 'uint32', - __typeValue: this.offset - }, - size: { - __typeName: 'uint32', - __typeValue: this.size - }, - titleId: { - __typeName: 'String', - __typeValue: this.titleId - } - }; - } -} - -class ServiceItemTransaction extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.transactionId = stream.readNEXString(); - this.extTransactionId = stream.readNEXString(); - this.time = stream.readNEXDateTime(); - this.transactionType = stream.readUInt32LE(); - this.transactionDescription = stream.readNEXString(); - this.transactionAmount = stream.readNEXStructure(ServiceItemAmount); - this.itemCode = stream.readNEXString(); - this.referenceId = stream.readNEXString(); - this.limitation = stream.readNEXStructure(ServiceItemLimitation); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - transactionId: { - __typeName: 'String', - __typeValue: this.transactionId - }, - extTransactionId: { - __typeName: 'String', - __typeValue: this.extTransactionId - }, - time: { - __typeName: 'DateTime', - __typeValue: this.time - }, - transactionType: { - __typeName: 'uint32', - __typeValue: this.transactionType - }, - transactionDescription: { - __typeName: 'String', - __typeValue: this.transactionDescription - }, - transactionAmount: { - __typeName: 'ServiceItemAmount', - __typeValue: this.transactionAmount - }, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - }, - referenceId: { - __typeName: 'String', - __typeValue: this.referenceId - }, - limitation: { - __typeName: 'ServiceItemLimitation', - __typeValue: this.limitation - } - }; - } -} - -class ServiceItemPurchaseHistory extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.totalSize = stream.readUInt32LE(); - this.offset = stream.readUInt32LE(); - this.transactions = stream.readNEXList(ServiceItemTransaction); - - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - supportId: { - __typeName: 'String', - __typeValue: this.supportId - }, - transactions: { - __typeName: 'List', - __typeValue: this.transactions - } - }; - } -} - -class ServiceItemGetPurchaseHistoryResponse extends NEXTypes.Structure { - constructor() { - super(); - - this._parentTypesClasses.push(ServiceItemEShopResponse); - } - - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nullablePurchaseHistory = stream.readNEXList(ServiceItemPurchaseHistory); - } - - toJSON() { - return { - __typeInherits: this._parentTypes.map(value => ({ - __typeName: value.constructor.name, - __typeValue: value - })), - __structureVersion: this._structureHeader.version, - nullablePurchaseHistory: { - __typeName: 'List', - __typeValue: this.nullablePurchaseHistory - } - }; - } -} - -class ServiceItemGetNoticeParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.noticeType = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - noticeType: { - __typeName: 'uint32', - __typeValue: this.noticeType - } - }; - } -} - -class ServiceItemNotice extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.scheduleId = stream.readUInt64LE(); - this.scheduleType = stream.readUInt32LE(); - this.paramInt = stream.readInt32LE(); - this.paramString = stream.readNEXString(); - this.paramBinary = stream.readNEXQBuffer(); - this.timeBegin = stream.readNEXDateTime(); - this.timeEnd = stream.readNEXDateTime(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - scheduleId: { - __typeName: 'uint64', - __typeValue: this.scheduleId - }, - scheduleType: { - __typeName: 'uint32', - __typeValue: this.scheduleType - }, - paramInt: { - __typeName: 'sint32', - __typeValue: this.paramInt - }, - paramString: { - __typeName: 'String', - __typeValue: this.paramString - }, - paramBinary: { - __typeName: 'qBuffer', - __typeValue: this.paramBinary - }, - timeBegin: { - __typeName: 'DateTime', - __typeValue: this.timeBegin - }, - timeEnd: { - __typeName: 'DateTime', - __typeValue: this.timeEnd - } - }; - } -} - -class ServiceItemEvent extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.eventId = stream.readUInt64LE(); - this.paramInt = stream.readInt32LE(); - this.paramString = stream.readNEXString(); - this.paramBinary = stream.readNEXQBuffer(); - this.presentTicketType = stream.readUInt32LE(); - this.presentTicketNum = stream.readUInt32LE(); - this.timeBegin = stream.readNEXDateTime(); - this.timeEnd = stream.readNEXDateTime(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - eventId: { - __typeName: 'uint64', - __typeValue: this.eventId - }, - paramInt: { - __typeName: 'sint32', - __typeValue: this.paramInt - }, - paramString: { - __typeName: 'String', - __typeValue: this.paramString - }, - paramBinary: { - __typeName: 'qBuffer', - __typeValue: this.paramBinary - }, - presentTicketType: { - __typeName: 'uint32', - __typeValue: this.presentTicketType - }, - presentTicketNum: { - __typeName: 'uint32', - __typeValue: this.presentTicketNum - }, - timeBegin: { - __typeName: 'DateTime', - __typeValue: this.timeBegin - }, - timeEnd: { - __typeName: 'DateTime', - __typeValue: this.timeEnd - } - }; - } -} - -class ServiceItemTicketInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.ticketType = stream.readUInt32LE(); - this.numTotal = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - ticketType: { - __typeName: 'uint32', - __typeValue: this.ticketType - }, - numTotal: { - __typeName: 'uint32', - __typeValue: this.numTotal - } - }; - } -} - -class ServiceItemUserInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.numTotalEntryTicket = stream.readUInt32LE(); - this.applicationBuffer = stream.readNEXQBuffer(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - numTotalEntryTicket: { - __typeName: 'uint32', - __typeValue: this.numTotalEntryTicket - }, - applicationBuffer: { - __typeName: 'qBuffer', - __typeValue: this.applicationBuffer - } - }; - } -} - -class ServiceItemStartChallengeParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.challengeScheduleId = stream.readUInt32LE(); - this.ticketType = stream.readUInt32LE(); - this.numTotal = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - challengeScheduleId: { - __typeName: 'uint32', - __typeValue: this.challengeScheduleId - }, - ticketType: { - __typeName: 'uint32', - __typeValue: this.ticketType - }, - numTotal: { - __typeName: 'uint32', - __typeValue: this.numTotal - } - }; - } -} - -class ServiceItemEndChallengeParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.challengeScheduleId = stream.readUInt32LE(); - this.userInfo = stream.readNEXStructure(ServiceItemUserInfo); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - challengeScheduleId: { - __typeName: 'uint32', - __typeValue: this.challengeScheduleId - }, - userInfo: { - __typeName: 'ServiceItemUserInfo', - __typeValue: this.userInfo - } - }; - } -} - -class ServiceItemRequestTicketRestorationParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.ticketType = stream.readUInt32LE(); - this.numTicket = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - ticketType: { - __typeName: 'uint32', - __typeValue: this.ticketType - }, - numTicket: { - __typeName: 'uint32', - __typeValue: this.numTicket - } - }; - } -} - -module.exports = { - ServiceItemHttpGetParam, - ServiceItemHttpGetResponse, - ServiceItemEShopResponse, - ServiceItemAmount, - ServiceItemPurchaseServiceItemParam, - ServiceItemPurchaseInfo, - ServiceItemPurchaseServiceItemResponse, - ServiceItemListServiceItemParam, - ServiceItemLimitation, - ServiceItemAttribute, - ServiceItemListItem, - ServiceItemCatalog, - ServiceItemListServiceItemResponse, - ServiceItemGetBalanceParam, - ServiceItemGetBalanceResponse, - ServiceItemGetPrepurchaseInfoParam, - ServiceItemPrepurchaseInfo, - ServiceItemGetPrepurchaseInfoResponse, - ServiceItemGetServiceItemRightParam, - ServiceItemAccountRight, - ServiceItemRightInfo, - ServiceItemRightInfos, - ServiceItemGetServiceItemRightResponse, - ServiceItemGetPurchaseHistoryParam, - ServiceItemTransaction, - ServiceItemPurchaseHistory, - ServiceItemGetPurchaseHistoryResponse, - ServiceItemGetNoticeParam, - ServiceItemNotice, - ServiceItemEvent, - ServiceItemTicketInfo, - ServiceItemUserInfo, - ServiceItemStartChallengeParam, - ServiceItemEndChallengeParam, - ServiceItemRequestTicketRestorationParam -}; diff --git a/src/protocols/types/shop_badge_arcade.js b/src/protocols/types/shop_badge_arcade.js deleted file mode 100644 index 6fc68ab..0000000 --- a/src/protocols/types/shop_badge_arcade.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class ShopPostPlayLogParam extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.unknown1 = stream.readNEXList(stream.readUInt32LE); - this.timestamp = stream.readNEXDateTime(); - this.unknown2 = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - unknown1: { - __typeName: 'List', - __typeValue: this.unknown1 - }, - timestamp: { - __typeName: 'DateTime', - __typeValue: this.timestamp - }, - unknown2: { - __typeName: 'String', - __typeValue: this.unknown2 - } - }; - } -} - -module.exports = { - ShopPostPlayLogParam -}; diff --git a/src/protocols/types/shop_pokemon_bank.js b/src/protocols/types/shop_pokemon_bank.js deleted file mode 100644 index 5b5aa1f..0000000 --- a/src/protocols/types/shop_pokemon_bank.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class ShopItem extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.itemId = stream.readUInt32LE(); - this.referenceId = stream.readNEXQBuffer(); - this.serviceName = stream.readNEXString(); - this.itemCode = stream.readNEXString(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - itemId: { - __typeName: 'uint32', - __typeValue: this.itemId - }, - referenceId: { - __typeName: 'qBuffer', - __typeValue: this.referenceId - }, - serviceName: { - __typeName: 'String', - __typeValue: this.serviceName - }, - itemCode: { - __typeName: 'String', - __typeValue: this.itemCode - } - }; - } -} - -class ShopItemRights extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.referenceId = stream.readNEXQBuffer(); - this.itemType = stream.readInt8(); - this.attribute = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - referenceId: { - __typeName: 'qBuffer', - __typeValue: this.referenceId - }, - itemType: { - __typeName: 'sint8', - __typeValue: this.itemType - }, - attribute: { - __typeName: 'uint32', - __typeValue: this.attribute - } - }; - } -} - -module.exports = { - ShopItem, - ShopItemRights -}; diff --git a/src/protocols/types/utility.js b/src/protocols/types/utility.js deleted file mode 100644 index 0858c9e..0000000 --- a/src/protocols/types/utility.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @typedef {import('../../stream')} Stream - */ -const NEXTypes = require('../../types'); - -class UniqueIdInfo extends NEXTypes.Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.nexUniqueId = stream.readUInt64LE(); - this.nexUniqueIdPassword = stream.readUInt64LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - nexUniqueId: { - __typeName: 'uint64', - __typeValue: this.nexUniqueId - }, - nexUniqueIdPassword: { - __typeName: 'uint64', - __typeValue: this.nexUniqueIdPassword - } - }; - } -} - -module.exports = { - UniqueIdInfo -}; diff --git a/src/protocols/utility.js b/src/protocols/utility.js deleted file mode 100644 index ed531a4..0000000 --- a/src/protocols/utility.js +++ /dev/null @@ -1,194 +0,0 @@ -/** - * @typedef {import('../packet')} Packet - * @typedef {import('../packetv0')} PacketV0 - * @typedef {import('../packetv1')} PacketV1 - * @typedef {import('../rmc')} RMCMessage - */ - -const semver = require('semver'); -const Stream = require('../stream'); - -const StorageManager = require('./storage_manager'); - -const Requests = require('./requests/utility'); -const Responses = require('./responses/utility'); - -class Utility { - static ProtocolID = 0x6e; - - static ProtocolName = 'Utility'; - - static Methods = { - AcquireNexUniqueId: 0x1, - AcquireNexUniqueIdWithPassword: 0x2, - AssociateNexUniqueIdWithMyPrincipalId: 0x3, - AssociateNexUniqueIdsWithMyPrincipalId: 0x4, - GetAssociatedNexUniqueIdWithMyPrincipalId: 0x5, - GetAssociatedNexUniqueIdsWithMyPrincipalId: 0x6, - GetIntegerSettings: 0x7, - GetStringSettings: 0x8 - }; - - static MethodNames = Object.entries(Utility.Methods).reduce((namesObject, entry) => { - const [key, value] = entry; - namesObject[value] = key; - return namesObject; - }, {}); - - static Handlers = { - 0x1: Utility.AcquireNexUniqueId, - 0x2: Utility.AcquireNexUniqueIdWithPassword, - 0x3: Utility.AssociateNexUniqueIdWithMyPrincipalId, - 0x4: Utility.AssociateNexUniqueIdsWithMyPrincipalId, - 0x5: Utility.GetAssociatedNexUniqueIdWithMyPrincipalId, - 0x6: Utility.GetAssociatedNexUniqueIdsWithMyPrincipalId, - 0x7: Utility.GetIntegerSettings, - 0x8: Utility.GetStringSettings - }; - - /** - * - * @param {(Packet|PacketV0|PacketV1)} packet PRUDP packet - */ - static handlePacket(packet) { - const methodId = packet.rmcMessage.methodId; - - const nexVersion = packet.connection.title.nex_utility_version || packet.connection.title.nex_version; - - // Check if game uses Storage Manager instead of Utility. Since there aren't many games that use it, - // assume games not listed on title list to use Utility - if (semver.lt(nexVersion, '3.0.0') && semver.gt(nexVersion, '0.0.0')) { - StorageManager.handlePacket(packet); - return; - } - - const handler = Utility.Handlers[methodId]; - - if (!handler) { - console.log(`Unknown Utility method ID ${methodId} (0x${methodId?.toString(16)}) (${Utility.MethodNames[methodId]})`); - return; - } - - const { rmcMessage } = packet; - const stream = new Stream(rmcMessage.body, packet.connection); - - packet.rmcData = { - body: handler(rmcMessage, stream) - }; - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AcquireNexUniqueId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AcquireNexUniqueIdRequest(stream); - } else { - return new Responses.AcquireNexUniqueIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AcquireNexUniqueIdWithPassword(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AcquireNexUniqueIdWithPasswordRequest(stream); - } else { - return new Responses.AcquireNexUniqueIdWithPasswordResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AssociateNexUniqueIdWithMyPrincipalId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AssociateNexUniqueIdWithMyPrincipalIdRequest(stream); - } else { - return new Responses.AssociateNexUniqueIdWithMyPrincipalIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static AssociateNexUniqueIdsWithMyPrincipalId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.AssociateNexUniqueIdsWithMyPrincipalIdRequest(stream); - } else { - return new Responses.AssociateNexUniqueIdsWithMyPrincipalIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetAssociatedNexUniqueIdWithMyPrincipalId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetAssociatedNexUniqueIdWithMyPrincipalIdRequest(stream); - } else { - return new Responses.GetAssociatedNexUniqueIdWithMyPrincipalIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetAssociatedNexUniqueIdsWithMyPrincipalId(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetAssociatedNexUniqueIdsWithMyPrincipalIdRequest(stream); - } else { - return new Responses.GetAssociatedNexUniqueIdsWithMyPrincipalIdResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetIntegerSettings(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetIntegerSettingsRequest(stream); - } else { - return new Responses.GetIntegerSettingsResponse(stream); - } - } - - /** - * - * @param {RMCMessage} rmcMessage NEX RMC message - * @param {Stream} stream NEX data stream - * @returns {object} Parsed RMC body - */ - static GetStringSettings(rmcMessage, stream) { - if (rmcMessage.isRequest()) { - return new Requests.GetStringSettingsRequest(stream); - } else { - return new Responses.GetStringSettingsResponse(stream); - } - } -} - - -module.exports = Utility; diff --git a/src/rc4.ts b/src/rc4.ts new file mode 100644 index 0000000..12fdc8f --- /dev/null +++ b/src/rc4.ts @@ -0,0 +1,48 @@ +// * NodeJS dropped support for RC4 natively + +export default class RC4Stream { + private key: Buffer; + private sbox: number[] = new Array(256); + private i = 0; + private j = 0; + + constructor(key: Buffer | string) { + this.key = Buffer.from(key); + + this.init(); + } + + private init(): void { + for (let i = 0; i < 256; i++) { + this.sbox[i] = i; + } + + let j = 0; + for (let i = 0; i < 256; i++) { + j = (j + this.sbox[i] + this.key[i % this.key.length]) % 256; + [this.sbox[i], this.sbox[j]] = [this.sbox[j], this.sbox[i]]; + } + + this.i = 0; + this.j = 0; + } + + private nextByte(): number { + this.i = (this.i + 1) % 256; + this.j = (this.j + this.sbox[this.i]) % 256; + + [this.sbox[this.i], this.sbox[this.j]] = [this.sbox[this.j], this.sbox[this.i]]; + + return this.sbox[(this.sbox[this.i] + this.sbox[this.j]) % 256]; + } + + public update(data: Buffer): Buffer { + const ciphered = Buffer.alloc(data.length); + + for (let k = 0; k < data.length; k++) { + ciphered[k] = data[k] ^ this.nextByte(); + } + + return ciphered; + } +} \ No newline at end of file diff --git a/src/renderers/main/index.html b/src/renderers/main/index.html new file mode 100644 index 0000000..8f8c652 --- /dev/null +++ b/src/renderers/main/index.html @@ -0,0 +1,12 @@ + + + + + + + + + + TODO + + \ No newline at end of file diff --git a/src/rmc.js b/src/rmc.js deleted file mode 100644 index 3b20799..0000000 --- a/src/rmc.js +++ /dev/null @@ -1,111 +0,0 @@ -const Stream = require('./stream'); - -class RMCMessage { - static REQUEST = 0; - static RESPONSE = 1; - - /** - * - * @param {Buffer} payload Decrypted packet payload - */ - constructor(payload) { - this.payload = payload; - this.mode; - - this.size; - this.protocolId; // * ORed with 0x80 on requests - this.customId; // * Only exists if protocol ID is 0x7F - this.callId; - this.methodId; // * ORed with 0x8000 on responses - this.body; - - this.responseStatus; // * Only on responses - this.errorCode; // * Only on responses - - this.parse(); - } - - parse() { - const stream = new Stream(this.payload); - - this.size = stream.readUInt32LE(); // * Size of RMC message after this field - this.protocolId = stream.readUInt8(); - - if (this.protocolId & 0x80) { - // * Message is a request - this.mode = RMCMessage.REQUEST; - - this.protocolId = this.protocolId & ~0x80; // * Get original protocol ID - } else { - // * Message is a response - this.mode = RMCMessage.RESPONSE; - } - - if (this.protocolId === 0x7F) { - this.customId = stream.readUInt16LE(); - } - - if (this.isRequest()) { - this.callId = stream.readUInt32LE(); - this.methodId = stream.readUInt32LE(); - this.body = stream.readRest(); - } - - if (this.isResponse()) { - this.responseStatus = stream.readUInt8(); // * 0 is error, 1 is success - - if (this.isSuccess()) { - this.callId = stream.readUInt32LE(); - this.methodId = stream.readUInt32LE() & ~0x8000; // * Get original method ID - this.body = stream.readRest(); - } - - if (this.isError()) { - this.errorCode = stream.readUInt32LE(); - this.callId = stream.readUInt32LE(); - } - } - } - - /** - * - * @returns {boolean} true if is request message - */ - isRequest() { - return this.mode === RMCMessage.REQUEST; - } - - /** - * - * @returns {boolean} true if is response message - */ - isResponse() { - return this.mode === RMCMessage.RESPONSE; - } - - /** - * - * @returns {boolean} true if uses an extended protocol ID - */ - isExtended() { - return this.protocolId === 0x7F; - } - - /** - * - * @returns {boolean} true if response is a success - */ - isSuccess() { - return this.responseStatus === 1; - } - - /** - * - * @returns {boolean} true if response is an error - */ - isError() { - return this.responseStatus === 0; - } -} - -module.exports = RMCMessage; diff --git a/src/stream.js b/src/stream.js deleted file mode 100644 index ada07e3..0000000 --- a/src/stream.js +++ /dev/null @@ -1,387 +0,0 @@ -/** - * @typedef {import('./connection')} Connection - */ - -const semver = require('semver'); -const NEXTypes = require('./types'); - -class Stream { - /** - * - * @param {Buffer} buffer Buffer object - * @param {Connection} connection NEX connection - */ - constructor(buffer, connection) { - this.connection = connection; // Used for NEX type settings - this._buffer = buffer; - this._offset = 0; - } - - /** - * - * @returns {number} Current offset into the data - */ - pos() { - return this._offset; - } - - /** - * - * @returns {boolean} True if has data left to read - */ - hasDataLeft() { - return this.pos() < this._buffer.length; - } - - /** - * - * @returns {number} Bytes left in the stream from current position - */ - remaining() { - return this._buffer.length - this.pos(); - } - - /** - * - * @param {number} value Bytes to skip - */ - skip(value) { - this._offset += value; - } - - /** - * - * @param {number} offset Manually set the streams buffer offset - */ - seek(offset) { - this._offset = offset; - } - - /** - * - * @param {number} len Bytes to read - * @returns {Buffer} Read bytes - */ - read(len) { - const read = this._buffer.subarray(this.pos(), this.pos() + len); - this._offset += len; - - return read; - } - - /** - * - * @param {number} len Bytes to read - * @returns {Buffer} Read bytes - */ - readBytes(len) { - return this.read(len); - } - - /** - * - * @returns {Buffer} Rest of the stream from current offset - */ - readRest() { - return this.readBytes(this.remaining()); - } - - /** - * - * @returns {number} Read number - */ - readUInt8() { - return this.readBytes(1).readUInt8(); - } - - /** - * - * @returns {number} Read number - */ - readInt8() { - return this.readBytes(1).readInt8(); - } - - /** - * - * @returns {number} Read number - */ - readUInt16BE() { - return this.readBytes(2).readUInt16BE(); - } - - /** - * - * @returns {number} Read number - */ - readUInt16LE() { - return this.readBytes(2).readUInt16LE(); - } - - /** - * - * @returns {number} Read number - */ - readInt16BE() { - return this.readBytes(2).readInt16BE(); - } - - /** - * - * @returns {number} Read number - */ - readInt16LE() { - return this.readBytes(2).readInt16LE(); - } - - /** - * - * @returns {number} Read number - */ - readUInt32BE() { - return this.readBytes(4).readUInt32BE(); - } - - /** - * - * @returns {number} Read number - */ - readUInt32LE() { - return this.readBytes(4).readUInt32LE(); - } - - /** - * - * @returns {number} Read number - */ - readInt32BE() { - return this.readBytes(4).readInt32BE(); - } - - /** - * - * @returns {number} Read number - */ - readInt32LE() { - return this.readBytes(4).readInt32LE(); - } - - /** - * - * @returns {number} Read number - */ - readUInt64BE() { - return this.readBytes(8).readBigUInt64BE(); - } - - /** - * - * @returns {number} Read number - */ - readUInt64LE() { - return this.readBytes(8).readBigUInt64LE(); - } - - /** - * - * @returns {number} Read number - */ - readInt64BE() { - return this.readBytes(8).readBigInt64BE(); - } - - /** - * - * @returns {number} Read number - */ - readInt64LE() { - return this.readBytes(8).readBigInt64LE(); - } - - /** - * - * @returns {number} Read double - */ - readDoubleBE() { - return this.readBytes(8).readDoubleBE(); - } - - /** - * - * @returns {number} Read double - */ - readDoubleLE() { - return this.readBytes(8).readDoubleLE(); - } - - /** - * - * @returns {number} Read float - */ - readFloatBE() { - return this.readBytes(4).readFloatBE(); - } - - /** - * - * @returns {number} Read float - */ - readFloatLE() { - return this.readBytes(4).readFloatLE(); - } - - /** - * - * @returns {boolean} Read boolean - */ - readBoolean() { - return Boolean(this.readUInt8()); - } - - /** - * - * @returns {number} User PID - */ - readPID() { - if (semver.gte(this.connection.title.nex_version, '4.0.0')) { - return this.readUInt64LE(); - } else { - return this.readUInt32LE(); - } - } - - /** - * @returns {string} NEX string - */ - readNEXString() { - const length = this.readUInt16LE(); - const string = this.readBytes(length); - - return string.toString().replace(/\0/g, ''); - } - - /** - * @returns {Buffer} NEX Buffer - */ - readNEXBuffer() { - const length = this.readUInt32LE(); - - return this.readBytes(length); - } - - /** - * @returns {Buffer} NEX qBuffer - */ - readNEXQBuffer() { - const length = this.readUInt16LE(); - - return this.readBytes(length); - } - - /** - * - * @param {(Function|NEXTypes.Structure)} input Function to be ran or Structure to be parsed x times. x=list length - * @returns {Array} NEX List - */ - readNEXList(input) { - const list = []; - - const length = this.readUInt32LE(); - - for (let i = 0; i < length; i++) { - if (input.prototype instanceof NEXTypes.Structure) { - list.push(this.readNEXStructure(input)); - } else { - list.push(input.call(this)); - } - } - - return list; - } - - /** - * @param {(Function|NEXTypes.Structure)} keyType Function or Structure used for the keys of the map - * @param {(Function|NEXTypes.Structure)} valueType Function or Structure used for the values of the map - * @returns {NEXTypes.Map} NEX Map - */ - readNEXMap(keyType, valueType) { - const map = new NEXTypes.Map(); - - const length = this.readUInt32LE(); - - for (let i = 0; i < length; i++) { - let key; - let value; - - if (keyType.prototype instanceof NEXTypes.Structure) { - key = this.readNEXStructure(keyType); - } else { - key = keyType.call(this); - } - - if (valueType.prototype instanceof NEXTypes.Structure) { - value = this.readNEXStructure(valueType); - } else { - value = valueType.call(this); - } - - map.add(key, value); - } - - return map; - } - - /** - * - * @returns {NEXTypes.StationURL} NEX StationURL - */ - readNEXStationURL() { - return new NEXTypes.StationURL(this.readNEXString()); - } - - /** - * - * @returns {number} NEX DateTime - */ - readNEXDateTime() { - return new NEXTypes.DateTime(this.readUInt64LE()); - } - - /** - * - * @returns {NEXTypes.Result} NEX Result - */ - readNEXResult() { - return new NEXTypes.Result(this.readUInt32LE()); - } - - /** - * - * @param {NEXTypes.Structure} cls NEX Structure definition - * @returns {NEXTypes.Structure} Extracted NEX Structure - */ - readNEXStructure(cls) { - const instance = new cls(); - instance.extract(this); - - return instance; - } - - /** - * - * @returns {NEXTypes.Structure} Extracted NEX Structure - */ - readNEXAnyDataHolder() { - return this.readNEXStructure(NEXTypes.AnyDataHolder); - } - - /** - * - * @returns {NEXTypes.Variant} Variant type - */ - readNEXVariant() { - return new NEXTypes.Variant(this); - } -} - -module.exports = Stream; diff --git a/src/titles.json b/src/titles.json deleted file mode 100644 index c176bd9..0000000 --- a/src/titles.json +++ /dev/null @@ -1,1125 +0,0 @@ -[ - { - "name": "Friends", - "access_key": "ridfebb9", - "nex_version": "1.0.0", - "title_ids": [ - "0004013000003202", - "000500301001500A", - "000500301001510A", - "000500301001520A" - ] - }, - { - "name": "Angry Birds Star Wars 3DS", - "access_key": "fbae7416", - "nex_version": "3.2.1", - "nex_ranking_version": "3.2.1", - "nex_datastore_version": "3.2.1", - "nex_match_making_version": "3.2.1", - "nex_messaging_version": "3.2.1", - "nex_utility_version": "3.2.1", - "title_ids": [ - "00040000000F2200", - "00040000000F7A00" - ] - }, - { - "name": "Angry Birds Trilogy 3DS", - "access_key": "ac4fbf0d", - "nex_version": "2.7.2", - "nex_ranking_version": "2.7.2", - "nex_datastore_version": "2.7.2", - "nex_match_making_version": "2.7.2", - "nex_messaging_version": "2.7.2", - "nex_utility_version": "2.7.2", - "title_ids": [ - "00040000000AE200", - "00040000000AF400" - ] - }, - { - "name": "Animal Crossing: New Leaf", - "access_key": "d6f08b40", - "nex_version": "3.10.1", - "nex_ranking_version": "3.10.1", - "nex_datastore_version": "3.10.1", - "nex_match_making_version": "3.10.1", - "nex_messaging_version": "3.10.1", - "nex_utility_version": "3.10.1", - "title_ids": [ - "0004000000086300", - "0004000000086400", - "0004000000198E00", - "0004000000198F00", - "0004000000199000" - ] - }, - { - "name": "Animal Crossing Plaza", - "access_key": "7b9b09cb", - "nex_version": "3.5.1", - "nex_ranking_version": "3.5.1", - "nex_datastore_version": "3.5.1", - "nex_match_making_version": "3.5.1", - "nex_messaging_version": "3.5.1", - "nex_utility_version": "3.5.1", - "title_ids": [ - "0005000010145600" - ] - }, - { - "name": "Axiom Verge", - "access_key": "24e0a63b", - "nex_version": "3.10.0", - "nex_ranking_version": "3.10.0", - "nex_datastore_version": "3.10.0", - "nex_match_making_version": "3.10.0", - "nex_messaging_version": "3.10.0", - "nex_utility_version": "3.10.0", - "title_ids": [ - "00050000101F7900", - "0005000010200800" - ] - }, - { - "name": "Badge Arcade", - "access_key": "82d5962d", - "nex_version": "3.7.3", - "nex_ranking_version": "3.7.3", - "nex_datastore_version": "3.7.3", - "nex_match_making_version": "3.7.3", - "nex_messaging_version": "3.7.3", - "nex_utility_version": "3.7.3", - "title_ids": [ - "0004000000153500", - "0004000000153600" - ] - }, - { - "name": "BIOHAZARD REVELATIONS UE", - "access_key": "59d539a9", - "nex_version": "3.2.1", - "nex_ranking_version": "3.2.1", - "nex_datastore_version": "3.2.1", - "nex_match_making_version": "3.2.1", - "nex_messaging_version": "3.2.1", - "nex_utility_version": "3.2.1", - "title_ids": [ - "0005000010113100" - ] - }, - { - "name": "Devil's Third", - "access_key": "", - "nex_version": "3.6.1", - "nex_ranking_version": "3.6.1", - "nex_datastore_version": "3.6.1", - "nex_match_making_version": "3.6.1", - "nex_messaging_version": "3.6.1", - "nex_utility_version": "3.6.1", - "title_ids": [ - "0005000010138F00", - "0005000010177600", - "0005000010177700", - "0005000010197D00" - ] - }, - { - "name": "Disney INFINITY", - "access_key": "", - "nex_version": "3.5.2", - "nex_ranking_version": "3.5.2", - "nex_datastore_version": "3.5.2", - "nex_match_making_version": "3.5.2", - "nex_messaging_version": "3.5.2", - "nex_utility_version": "3.5.2", - "title_ids": [ - "0005000010132900", - "0005000010136F00", - "0005000010137000", - "000500001015A300" - ] - }, - { - "name": "Disney Infinity [2.0]", - "access_key": "", - "nex_version": "3.5.2", - "nex_ranking_version": "3.5.2", - "nex_datastore_version": "3.5.2", - "nex_match_making_version": "3.5.2", - "nex_messaging_version": "3.5.2", - "nex_utility_version": "3.5.2", - "title_ids": [ - "000500001016DC00", - "0005000010188C00", - "0005000010188D00" - ] - }, - { - "name": "DISNEY INFINITY 3.0", - "access_key": "", - "nex_version": "3.9.1", - "nex_ranking_version": "3.9.1", - "nex_datastore_version": "3.9.1", - "nex_match_making_version": "3.9.1", - "nex_messaging_version": "3.9.1", - "nex_utility_version": "3.9.1", - "title_ids": [ - "00050000101AC900", - "00050000101B3D00", - "00050000101B3E00", - "00050000101DDC00" - ] - }, - { - "name": "DKC: Tropical Freeze", - "access_key": "7fcf384a", - "nex_version": "3.4.0", - "nex_ranking_version": "3.4.0", - "nex_datastore_version": "3.4.0", - "nex_match_making_version": "3.4.0", - "nex_messaging_version": "3.4.0", - "nex_utility_version": "3.4.0", - "title_ids": [ - "0005000010137F00", - "0005000010138300", - "0005000010144800" - ] - }, - { - "name": "DuckTales: Remastered", - "access_key": "1294a96c", - "nex_version": "3.3.0", - "nex_ranking_version": "3.3.0", - "nex_datastore_version": "3.3.0", - "nex_match_making_version": "3.3.0", - "nex_messaging_version": "3.3.0", - "nex_utility_version": "3.3.0", - "title_ids": [ - "0005000010129000", - "0005000010129200" - ] - }, - { - "name": "FAST Racing NEO", - "access_key": "811aa39f", - "nex_version": "3.9.1", - "nex_ranking_version": "3.9.1", - "nex_datastore_version": "3.9.1", - "nex_match_making_version": "3.9.1", - "nex_messaging_version": "3.9.1", - "nex_utility_version": "3.9.1", - "title_ids": [ - "000500001012F000", - "00050000101D6000", - "00050000101E4100", - "00050000101FED00" - ] - }, - { - "name": "FotNS: Ken's Rage 2", - "access_key": "9994e29c", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "0005000010116600", - "000500001012B800", - "000500001012B900" - ] - }, - { - "name": "Game Party", - "access_key": "", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "000500001010E400", - "000500001010FF00" - ] - }, - { - "name": "Hyrule Warriors", - "access_key": "7fcc1f7c", - "nex_version": "3.8.0", - "nex_ranking_version": "3.8.0", - "nex_datastore_version": "3.8.0", - "nex_match_making_version": "3.8.0", - "nex_messaging_version": "3.8.0", - "nex_utility_version": "3.8.0", - "title_ids": [ - "000500001017CD00", - "000500001017D800", - "000500001017D900" - ] - }, - { - "name": "Injustice: Gods Among Us", - "access_key": "65e9f4d6", - "nex_version": "3.2.1", - "nex_ranking_version": "3.2.1", - "nex_datastore_version": "3.2.1", - "nex_match_making_version": "3.2.1", - "nex_messaging_version": "3.2.1", - "nex_utility_version": "3.2.1", - "title_ids": [ - "0005000010111700", - "0005000010111A00", - "0005000010140700" - ] - }, - { - "name": "IRONFALL Invasion", - "access_key": "feb81c7c", - "nex_version": "3.7.1", - "nex_ranking_version": "3.7.1", - "nex_datastore_version": "3.7.1", - "nex_match_making_version": "3.7.1", - "nex_messaging_version": "3.7.1", - "nex_utility_version": "3.7.1", - "title_ids": [ - "000400000015B100", - "000400000015D800", - "000400000017BF00", - "000400000017D000" - ] - }, - { - "name": "Legend of Kay", - "access_key": "478232f3", - "nex_version": "3.8.3", - "nex_ranking_version": "3.8.3", - "nex_datastore_version": "3.8.3", - "nex_match_making_version": "3.8.3", - "nex_messaging_version": "3.8.3", - "nex_utility_version": "3.8.3", - "title_ids": [ - "0005000010193300", - "0005000010193400" - ] - }, - { - "name": "LOST REAVERS", - "access_key": "", - "nex_version": "3.10.0", - "nex_ranking_version": "3.10.0", - "nex_datastore_version": "3.10.0", - "nex_match_making_version": "3.10.0", - "nex_messaging_version": "3.10.0", - "nex_utility_version": "3.10.0", - "title_ids": [ - "000500001018D900", - "00050000101A4800", - "00050000101B9900" - ] - }, - { - "name": "Mario & Sonic Rio 2016 3DS", - "access_key": "a2dbfa39", - "nex_version": "3.9.1", - "nex_ranking_version": "3.9.1", - "nex_datastore_version": "3.9.1", - "nex_match_making_version": "3.9.1", - "nex_messaging_version": "3.9.1", - "nex_utility_version": "3.9.1", - "title_ids": [ - "000400000014A400", - "000400000017E200", - "000400000017E300", - "0004000000191C00", - "0004000000191D00", - "0004000000192400" - ] - }, - { - "name": "Mario & Sonic Rio 2016 Wii U", - "access_key": "63fecb0f", - "nex_version": "3.9.1", - "nex_ranking_version": "3.9.1", - "nex_datastore_version": "3.9.1", - "nex_match_making_version": "3.9.1", - "nex_messaging_version": "3.9.1", - "nex_utility_version": "3.9.1", - "title_ids": [ - "0005000010190300", - "00050000101E5300", - "00050000101E5400" - ] - }, - { - "name": "MARIO & SONIC SOCHI 2014", - "access_key": "585214a5", - "nex_version": "3.4.0", - "nex_ranking_version": "3.4.0", - "nex_datastore_version": "3.4.0", - "nex_match_making_version": "3.4.0", - "nex_messaging_version": "3.4.0", - "nex_utility_version": "3.4.0", - "title_ids": [ - "0005000010106900", - "000500001010C700", - "000500001010C800" - ] - }, - { - "name": "MARIO KART 7", - "access_key": "6181dff1", - "nex_version": "2.4.3", - "nex_ranking_version": "2.4.3", - "nex_datastore_version": "2.4.3", - "nex_match_making_version": "2.4.3", - "nex_messaging_version": "2.4.3", - "nex_utility_version": "2.4.3", - "title_ids": [ - "0004000000030600", - "0004000000030700", - "0004000000030800", - "0004000000030A00", - "000400000008B400" - ] - }, - { - "name": "MARIO KART 8", - "access_key": "25dbf96a", - "nex_version": "3.5.4", - "nex_ranking_version": "3.5.4", - "nex_datastore_version": "3.5.4", - "nex_match_making_version": "3.5.4", - "nex_messaging_version": "3.5.4", - "nex_utility_version": "3.5.4", - "title_ids": [ - "000500001010EB00", - "000500001010EC00", - "000500001010ED00" - ] - }, - { - "name": "Mario Tennis Open", - "access_key": "0fabeff2", - "nex_version": "2.6.1", - "nex_ranking_version": "2.6.1", - "nex_datastore_version": "2.6.1", - "nex_match_making_version": "2.6.1", - "nex_messaging_version": "2.6.1", - "nex_utility_version": "2.6.1", - "title_ids": [ - "0004000000064D00", - "000400000007C700", - "000400000007C800", - "00040000000B8800", - "00040000000B9100" - ] - }, - { - "name": "Mario Tennis: Ultra Smash", - "access_key": "c69b92a0", - "nex_version": "3.9.1", - "nex_ranking_version": "3.9.1", - "nex_datastore_version": "3.9.1", - "nex_match_making_version": "3.9.1", - "nex_messaging_version": "3.9.1", - "nex_utility_version": "3.9.1", - "title_ids": [ - "0005000010199000", - "00050000101A3500", - "00050000101A3600" - ] - }, - { - "name": "Mario vs. DK: Tipping Stars", - "access_key": "d8927c3f", - "nex_version": "3.7.1", - "nex_ranking_version": "3.7.1", - "nex_datastore_version": "3.7.1", - "nex_match_making_version": "3.7.1", - "nex_messaging_version": "3.7.1", - "nex_utility_version": "3.7.1", - "title_ids": [ - "000400000012C800", - "000400000012CA00", - "0005000010149300", - "0005000010178E00", - "0005000010179200" - ] - }, - { - "name": "Metroid Prime: FF", - "access_key": "f79fb3c5", - "nex_version": "3.9.1", - "nex_ranking_version": "3.9.1", - "nex_datastore_version": "3.9.1", - "nex_match_making_version": "3.9.1", - "nex_messaging_version": "3.9.1", - "nex_utility_version": "3.9.1", - "title_ids": [ - "000400000016CE00", - "000400000016E300", - "0004000000175200" - ] - }, - { - "name": "MH3G HD Ver.", - "access_key": "", - "nex_version": "3.0.5", - "nex_ranking_version": "3.0.5", - "nex_datastore_version": "3.0.5", - "nex_match_making_version": "3.0.5", - "nex_messaging_version": "3.0.5", - "nex_utility_version": "3.0.5", - "title_ids": [ - "0004000000048100", - "0005000010104D00" - ] - }, - { - "name": "MH3U", - "access_key": "", - "nex_version": "3.0.5", - "nex_ranking_version": "3.0.5", - "nex_datastore_version": "3.0.5", - "nex_match_making_version": "3.0.5", - "nex_messaging_version": "3.0.5", - "nex_utility_version": "3.0.5", - "title_ids": [ - "00040000000AE400", - "00040000000B1D00", - "00040000000D2E00", - "0005000010117200", - "0005000010118300" - ] - }, - { - "name": "Mighty No. 9", - "access_key": "bb980c2e", - "nex_version": "3.9.1", - "nex_ranking_version": "3.9.1", - "nex_datastore_version": "3.9.1", - "nex_match_making_version": "3.9.1", - "nex_messaging_version": "3.9.1", - "nex_utility_version": "3.9.1", - "title_ids": [ - "00050000101C5A00", - "00050000101C9600", - "00050000101DD900" - ] - }, - { - "name": "Minecraft: Wii U Edition", - "access_key": "f1b61c8e", - "nex_version": "3.10.0", - "nex_ranking_version": "3.10.0", - "nex_datastore_version": "3.10.0", - "nex_match_making_version": "3.10.0", - "nex_messaging_version": "3.10.0", - "nex_utility_version": "3.10.0", - "title_ids": [ - "00050000101D7500", - "00050000101D9D00", - "00050000101DBE00" - ] - }, - { - "name": "Nano Assault Neo", - "access_key": "7e484a8e", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "0005000010110100", - "0005000010110600", - "0005000010136400" - ] - }, - { - "name": "NINJA GAIDEN 3: Razor's Edge", - "access_key": "f857b4bd", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "0005000010110900", - "0005000010110A00", - "0005000010110B00", - "0005000010139B00" - ] - }, - { - "name": "Nova-111", - "access_key": "bafe9856", - "nex_version": "3.8.3", - "nex_ranking_version": "3.8.3", - "nex_datastore_version": "3.8.3", - "nex_match_making_version": "3.8.3", - "nex_messaging_version": "3.8.3", - "nex_utility_version": "3.8.3", - "title_ids": [ - "00050000101C0700", - "00050000101C0A00" - ] - }, - { - "name": "OlliOlli", - "access_key": "60e5df12", - "nex_version": "3.6.1", - "nex_ranking_version": "3.6.1", - "nex_datastore_version": "3.6.1", - "nex_match_making_version": "3.6.1", - "nex_messaging_version": "3.6.1", - "nex_utility_version": "3.6.1", - "title_ids": [ - "000400000015A200", - "000400000015A400", - "00050000101A5E00", - "00050000101A6900" - ] - }, - { - "name": "PIKMIN 3", - "access_key": "f6accfc1", - "nex_version": "3.3.0", - "nex_ranking_version": "3.3.0", - "nex_datastore_version": "3.3.0", - "nex_match_making_version": "3.3.0", - "nex_messaging_version": "3.3.0", - "nex_utility_version": "3.3.0", - "title_ids": [ - "000500001012BC00", - "000500001012BD00", - "000500001012BE00", - "0005000010185300" - ] - }, - { - "name": "Pokémon Bank", - "access_key": "9a2961d8", - "nex_version": "3.4.12", - "nex_ranking_version": "3.4.12", - "nex_datastore_version": "3.4.12", - "nex_match_making_version": "3.4.12", - "nex_messaging_version": "3.4.12", - "nex_utility_version": "3.4.12", - "title_ids": [ - "00040000000C9B00" - ] - }, - { - "name": "Pokémon Rumble World", - "access_key": "844f1d0c", - "nex_version": "3.8.2", - "nex_ranking_version": "3.8.2", - "nex_datastore_version": "3.8.2", - "nex_match_making_version": "3.8.2", - "nex_messaging_version": "3.8.2", - "nex_utility_version": "3.8.2", - "title_ids": [ - "0004000000164600", - "0004000000185A00" - ] - }, - { - "name": "POKKÉN TOURNAMENT", - "access_key": "6ef3adf1", - "nex_version": "3.10.0", - "nex_ranking_version": "3.10.0", - "nex_datastore_version": "3.10.0", - "nex_match_making_version": "3.10.0", - "nex_messaging_version": "3.10.0", - "nex_utility_version": "3.10.0", - "title_ids": [ - "00050000101C5800", - "00050000101DF400", - "00050000101DF500" - ] - }, - { - "name": "Puddle", - "access_key": "afcffb5c", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "000500001010FB00", - "0005000010110500", - "00050000101A2700" - ] - }, - { - "name": "PUYOPUYOTETRIS", - "access_key": "4eb0ca36", - "nex_version": "3.5.2", - "nex_ranking_version": "3.5.2", - "nex_datastore_version": "3.5.2", - "nex_match_making_version": "3.5.2", - "nex_messaging_version": "3.5.2", - "nex_utility_version": "3.5.2", - "title_ids": [ - "0004000000101200", - "000500001014D900" - ] - }, - { - "name": "RESIDENT EVIL REVELATIONS", - "access_key": "", - "nex_version": "3.2.1", - "nex_ranking_version": "3.2.1", - "nex_datastore_version": "3.2.1", - "nex_match_making_version": "3.2.1", - "nex_messaging_version": "3.2.1", - "nex_utility_version": "3.2.1", - "title_ids": [ - "0004000000053B00", - "000400000005EE00", - "000500001012B400", - "000500001012CF00" - ] - }, - { - "name": "RTK 12", - "access_key": "bfede098", - "nex_version": "3.4.0", - "nex_ranking_version": "3.4.0", - "nex_datastore_version": "3.4.0", - "nex_match_making_version": "3.4.0", - "nex_messaging_version": "3.4.0", - "nex_utility_version": "3.4.0", - "title_ids": [ - "0005000010111C00", - "0005000010149000" - ] - }, - { - "name": "Runner2", - "access_key": "1084452a", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "000500001011AF00", - "0005000010136300", - "00050000101DD600" - ] - }, - { - "name": "SI2", - "access_key": "44adeb87", - "nex_version": "3.6.1", - "nex_ranking_version": "3.6.1", - "nex_datastore_version": "3.6.1", - "nex_match_making_version": "3.6.1", - "nex_messaging_version": "3.6.1", - "nex_utility_version": "3.6.1", - "title_ids": [ - "0005000010173300", - "0005000010176500" - ] - }, - { - "name": "SONIC LOST WORLD", - "access_key": "69a9fc95", - "nex_version": "3.3.0", - "nex_ranking_version": "3.3.0", - "nex_datastore_version": "3.3.0", - "nex_match_making_version": "3.3.0", - "nex_messaging_version": "3.3.0", - "nex_utility_version": "3.3.0", - "title_ids": [ - "00040000000C5400", - "00040000000C8C00", - "00040000000CB400", - "000400000010CF00", - "0005000010128F00", - "000500001012B100", - "0005000010135700" - ] - }, - { - "name": "Sonic Transformed", - "access_key": "b26a3421", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "000400000008FC00", - "00040000000B3500", - "000500001010B300", - "0005000010111F00", - "000500001015B400" - ] - }, - { - "name": "Splatoon", - "access_key": "6f599f81", - "nex_version": "3.8.3", - "nex_ranking_version": "3.8.3", - "nex_datastore_version": "3.8.3", - "nex_match_making_version": "3.8.3", - "nex_messaging_version": "3.8.3", - "nex_utility_version": "3.8.3", - "title_ids": [ - "0005000010162B00", - "0005000010176900", - "0005000010176A00", - "000500001017E300", - "00050000101CDB00", - "00050000101CDC00", - "00050000101CDD00", - "00050000101CDE00", - "00050000101D6A00", - "00050000101D6B00", - "00050000101D6C00" - ] - }, - { - "name": "Star Fox Guard", - "access_key": "", - "nex_version": "3.8.2", - "nex_ranking_version": "3.8.2", - "nex_datastore_version": "3.8.2", - "nex_match_making_version": "3.8.2", - "nex_messaging_version": "3.8.2", - "nex_utility_version": "3.8.2", - "title_ids": [ - "00050000101BEB00", - "00050000101BEC00", - "00050000101BED00" - ] - }, - { - "name": "Star Fox Guard (Demo)", - "access_key": "", - "nex_version": "3.8.2", - "nex_ranking_version": "3.8.2", - "nex_datastore_version": "3.8.2", - "nex_match_making_version": "3.8.2", - "nex_messaging_version": "3.8.2", - "nex_utility_version": "3.8.2", - "title_ids": [ - "00050000101DCC00", - "00050000101DCD00", - "00050000101DCE00" - ] - }, - { - "name": "Star Wars Pinball", - "access_key": "ecd0e530", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "00040000000D4A00", - "00040000000E6800", - "0005000010132A00", - "0005000010135200" - ] - }, - { - "name": "Steel Diver: Sub Wars", - "access_key": "fb9537fe", - "nex_version": "3.7.0", - "nex_ranking_version": "3.7.0", - "nex_datastore_version": "3.7.0", - "nex_match_making_version": "3.7.0", - "nex_messaging_version": "3.7.0", - "nex_utility_version": "3.7.0", - "title_ids": [ - "00040000000D7D00", - "00040000000D7E00" - ] - }, - { - "name": "Super Mario Maker", - "access_key": "9f2b4678", - "nex_version": "3.8.12", - "nex_ranking_version": "3.8.12", - "nex_datastore_version": "3.8.12", - "nex_match_making_version": "3.8.12", - "nex_messaging_version": "3.8.12", - "nex_utility_version": "3.8.12", - "title_ids": [ - "00040000001A0300", - "00040000001A0400", - "00040000001A0500", - "00040000001BB800", - "000500001018DB00", - "000500001018DC00", - "000500001018DD00" - ] - }, - { - "name": "Super Smash Bros.", - "access_key": "2869ba38", - "nex_version": "3.6.27", - "nex_ranking_version": "3.6.27", - "nex_datastore_version": "3.6.27", - "nex_match_making_version": "3.6.27", - "nex_messaging_version": "3.6.27", - "nex_utility_version": "3.6.27", - "title_ids": [ - "00040000000B8B00", - "00040000000EDF00", - "00040000000EE000", - "0004000000167C00", - "0005000010110E00", - "0005000010144F00", - "0005000010145000" - ] - }, - { - "name": "Team Kirby Clash Deluxe", - "access_key": "e0c85605", - "nex_version": "3.10.1", - "nex_ranking_version": "3.10.1", - "nex_datastore_version": "3.10.1", - "nex_match_making_version": "3.10.1", - "nex_messaging_version": "3.10.1", - "nex_utility_version": "3.10.1", - "title_ids": [ - "00040000001A8B00", - "00040000001AB800", - "00040000001AB900", - "00040000001C2200", - "00040000001CAA00", - "00040000001CAD00" - ] - }, - { - "name": "TEKKEN TAG 2 Wii U EDITION", - "access_key": "0f037f64", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "0005000010100600", - "000500001010F800", - "0005000010110000" - ] - }, - { - "name": "Terraria", - "access_key": "3d37fbdb", - "nex_version": "3.8.3", - "nex_ranking_version": "3.8.3", - "nex_datastore_version": "3.8.3", - "nex_match_making_version": "3.8.3", - "nex_messaging_version": "3.8.3", - "nex_utility_version": "3.8.3", - "title_ids": [ - "000400000016A600", - "000400000016A900", - "00040000001B3200", - "0005000010198F00", - "000500001019C300", - "00050000101F3A00" - ] - }, - { - "name": "Trine 2", - "access_key": "f9c35adc", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "0005000010112200", - "0005000010128A00", - "000500001014D600" - ] - }, - { - "name": "WARRIORS OROCHI 3 Hyper", - "access_key": "d74bb27d", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "000500001010EA00", - "0005000010110200", - "0005000010112B00" - ] - }, - { - "name": "Wii Karaoke U", - "access_key": "dfc5a4ac", - "nex_version": "3.4.0", - "nex_ranking_version": "3.4.0", - "nex_datastore_version": "3.4.0", - "nex_match_making_version": "3.4.0", - "nex_messaging_version": "3.4.0", - "nex_utility_version": "3.4.0", - "title_ids": [ - "0005000010100D00", - "0005000010102500", - "0005000010149600" - ] - }, - { - "name": "Wii Party U", - "access_key": "a5b77314", - "nex_version": "3.3.0", - "nex_ranking_version": "3.3.0", - "nex_datastore_version": "3.3.0", - "nex_match_making_version": "3.3.0", - "nex_messaging_version": "3.3.0", - "nex_utility_version": "3.3.0", - "title_ids": [ - "000500001011A800", - "0005000010137D00", - "0005000010137E00" - ] - }, - { - "name": "Wii Sports Club", - "access_key": "4d324052", - "nex_version": "3.4.7", - "nex_ranking_version": "3.4.7", - "nex_datastore_version": "3.4.7", - "nex_match_making_version": "3.4.7", - "nex_messaging_version": "3.4.7", - "nex_utility_version": "3.4.7", - "title_ids": [ - "000500001012F100", - "0005000010144D00", - "0005000010144E00", - "0005000010171E00" - ] - }, - { - "name": "Xenoblade Chronicles X", - "access_key": "59d7be84", - "nex_version": "3.5.5", - "nex_ranking_version": "3.5.5", - "nex_datastore_version": "3.5.5", - "nex_match_making_version": "3.5.5", - "nex_messaging_version": "3.5.5", - "nex_utility_version": "3.5.5", - "title_ids": [ - "0005000010116100", - "00050000101C4C00", - "00050000101C4D00" - ] - }, - { - "name": "Yo-kai Watch 2", - "access_key": "7ab183bb", - "nex_version": "3.6.1", - "nex_ranking_version": "3.6.1", - "nex_datastore_version": "3.6.1", - "nex_match_making_version": "3.6.1", - "nex_messaging_version": "3.6.1", - "nex_utility_version": "3.6.1", - "title_ids": [ - "000400000012F800", - "000400000012F900", - "0004000000155100", - "000400000019A900", - "000400000019AA00", - "000400000019AE00", - "000400000019AF00", - "00040000001B2700", - "00040000001B2A00", - "00040000001B7100", - "00040000001BB500" - ] - }, - { - "name": "Zen Pinball 2", - "access_key": "2ff15f7e", - "nex_version": "3.0.1", - "nex_ranking_version": "3.0.1", - "nex_datastore_version": "3.0.1", - "nex_match_making_version": "3.0.1", - "nex_messaging_version": "3.0.1", - "nex_utility_version": "3.0.1", - "title_ids": [ - "0005000010113800", - "0005000010115F00" - ] - }, - { - "name": "役満 鳳凰", - "access_key": "23aab2d3", - "nex_version": "3.6.14", - "nex_ranking_version": "3.6.14", - "nex_datastore_version": "3.6.14", - "nex_match_making_version": "3.6.14", - "nex_messaging_version": "3.6.14", - "nex_utility_version": "3.6.14", - "title_ids": [ - "0005000010149700" - ] - }, - { - "name": "Kid Icarus Uprising", - "access_key": "58a7e494", - "nex_version": "0.0.0", - "title_ids": [ - "0004000000030000", - "0004000000030100", - "0004000000030200" - ] - }, - { - "name": "Luigi's Mansion 2", - "access_key": "3861a9f8", - "nex_version": "0.0.0", - "title_ids": [ - "0004000000055F00", - "0004000000076400", - "0004000000076500" - ] - }, - { - "name": "Pokémon X/Y", - "access_key": "876138df", - "nex_version": "0.0.0", - "title_ids": [ - "0004000000055D00" - ] - }, - { - "name": "TLoZ: Tri Force Heroes", - "access_key": "c1621b84", - "nex_version": "0.0.0", - "title_ids": [ - "0004000000176E00", - "0004000000176F00", - "0004000000177000", - "0004000000182200", - "0004000000182300" - ] - } -] \ No newline at end of file diff --git a/src/types.js b/src/types.js deleted file mode 100644 index efcc149..0000000 --- a/src/types.js +++ /dev/null @@ -1,445 +0,0 @@ -/** - * @typedef {import('./stream')} Stream - */ - -const semver = require('semver'); - -class Structure { - constructor() { - this._parentTypesClasses = []; - this._parentTypes = []; - this._structureHeader = { - version: 0, - contentLength: 0 - }; - } - - toJSON() { - const json = { - __structureTypeName: this.constructor.name, - __structureVersion: this._structureHeader.version - }; - - for (const key in this) { - if (Object.hasOwnProperty.call(this, key)) { - json[key] = this[key]; - } - } - - return json; - } - - /** - * - * @param {Stream} stream NEX data stream NEX data stream - */ - extract(stream) { - const parentTypesClasses = this._parentTypesClasses; - - for (const parentTypeClass of parentTypesClasses) { - this._parentTypes.push(stream.readNEXStructure(parentTypeClass)); - } - - if (semver.gte(stream.connection.title.nex_version, '3.5.0')) { - this._structureHeader = { - version: stream.readUInt8(), - contentLength: stream.readUInt32LE() - }; - } - - this.parse(stream); - } -} - -// This is empty -class Data extends Structure { - // * This type contains nothing - parse() { } - - toJSON() { - return { - __structureVersion: this._structureHeader.version - }; - } -} - -class AnyDataHolder { - static typesHandlers = {}; - - /** - * - * @param {string} name NEX type name - * @param {*} cls NEX type definition - */ - static addType(name, cls) { - this.typesHandlers[name] = cls; - } - - constructor() { - this.typeName; - this.length1; - this.length2; - this.data; - } - - /** - * - * @param {Stream} stream NEX data stream - */ - extract(stream) { - this.typeName = stream.readNEXString(); - this.length1 = stream.readUInt32LE(); - this.length2 = stream.readUInt32LE(); - - const structure = AnyDataHolder.typesHandlers[this.typeName]; - - if (structure) { - this.data = stream.readNEXStructure(structure); - } else { - console.log(`Unknown AnyDataHolder type ${this.typeName}`); - this.data = stream.readBytes(this.length2); - } - } - - toJSON() { - const data = { - typeName: { - __typeName: 'String', - __typeValue: this.typeName - }, - length1: { - __typeName: 'uint32', - __typeValue: this.length1 - }, - length2: { - __typeName: 'uint32', - __typeValue: this.length2 - }, - objectData: { - __typeName: this.typeName, // * The type of the data changes and is stored in the typeName - __typeValue: this.data - } - }; - - if (data.objectData.__typeValue instanceof Buffer) { - data.objectData.__typeValue = data.objectData.__typeValue.toString('hex'); - } - - return data; - } -} - -class RVConnectionData extends Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.stationUrl = stream.readNEXStationURL(); - this.specialProtocols = stream.readNEXList(stream.readUInt8); - this.stationUrlSpecial = stream.readNEXStationURL(); - - if (this._structureHeader.version >= 1) { - this.currentUTCTime = stream.readNEXDateTime(); - } - } - - toJSON() { - const data = { - __structureVersion: this._structureHeader.version, - m_urlRegularProtocols: { - __typeName: 'StationURL', - __typeValue: this.stationUrl - }, - m_lstSpecialProtocols: { - __typeName: 'List', - __typeValue: this.specialProtocols - }, - m_urlSpecialProtocols: { - __typeName: 'StationURL', - __typeValue: this.stationUrlSpecial - } - }; - - if (this.currentUTCTime !== undefined) { - data.m_currentUTCTime = { - __typeName: 'DateTime', - __typeValue: this.currentUTCTime - }; - } - - return data; - } -} - -class StationURL { - /** - * - * @param {string} string StationURL string - */ - constructor(string) { - this._string = string; - this.address; - this.port; - this.stream; - this.sid; - this.CID; - this.PID; - this.type; - this.RVCID; - this.natm; - this.natf; - this.upnp; - this.pmp; - this.probeinit; - this.PRID; - this.fastproberesponse; - this.NodeID; - - // min length is "udp:/" - if (string.length < 5) { - return; - } - - const data = string.split(':/'); - - const scheme = data[0]; - let parameters = data[1]; - - parameters = Object.fromEntries(parameters.split(';').map(parameter => parameter.split('='))); - - this.scheme = scheme; - Object.assign(this, parameters); - } - - toJSON() { - return { - url: { - __typeName: 'String', - __typeValue: this._string - } - }; - } -} - -class DateTime { - /** - * - * @param {bigint} value DateTime value - */ - constructor(value) { - this.value = value; - - } - - getSeconds() { - return Number(this.value & 63n); - } - - getMinutes() { - return Number((this.value >> 6n) & 63n); - } - - getHours() { - return Number((this.value >> 12n) & 31n); - } - - getDay() { - return Number((this.value >> 17n) & 31n); - } - - getMonth() { - return Number((this.value >> 22n) & 15n) - 1; - } - - getYear() { - return Number(this.value >> 26n); - } - - standard() { - return new Date(Date.UTC( - this.getYear(), - this.getMonth(), - this.getDay(), - this.getHours(), - this.getMinutes(), - this.getSeconds() - )); - } - - toJSON() { - return { - date: { - __typeName: 'Date', - __typeValue: this.standard() - } - }; - } -} - -class ResultRange extends Structure { - /** - * - * @param {Stream} stream NEX data stream - */ - parse(stream) { - this.m_uiOffset = stream.readUInt32LE(); - this.m_uiSize = stream.readUInt32LE(); - } - - toJSON() { - return { - __structureVersion: this._structureHeader.version, - m_uiOffset: { - __typeName: 'uint32', - __typeValue: this.m_uiOffset - }, - m_uiSize: { - __typeName: 'uint32', - __typeValue: this.m_uiSize - } - }; - } -} - -class Result { - /** - * - * @param {number} resultCode Result code - */ - constructor(resultCode) { - this.resultCode = resultCode; - } - - isSuccess() { - return (this.resultCode & (1 << 31)) === 0; - } - - isError() { - return (this.resultCode & (1 << 31)) !== 0; - } - - toJSON() { - return { - resultCode: { - __typeName: 'uint32', - __typeValue: this.resultCode - } - }; - } -} - -class Variant { - /** - * - *@param {Stream} stream NEX data stream - */ - constructor(stream) { - this.type = stream.readUInt8(); - this.value = null; // * if type = 0, then value = null. Let null be default - - switch (this.type) { - case 1: - this.value = stream.readInt64LE(); - break; - case 2: - this.value = stream.readDoubleLE(); - break; - case 3: - this.value = stream.readBoolean(); - break; - case 4: - this.value = stream.readNEXString(); - break; - case 5: - this.value = stream.readNEXDateTime(); - break; - case 6: - this.value = stream.readUInt64LE(); - break; - } - } - - toJSON() { - const data = { - type: { - __typeName: 'uint8', - __typeValue: this.type - }, - value: { - __typeValue: this.value - } - }; - - switch (this.type) { - case 0: - data.value.__typeName = 'No value'; - break; - case 1: - data.value.__typeName = 'sint64'; - break; - case 2: - data.value.__typeName = 'double'; - break; - case 3: - data.value.__typeName = 'boolean'; - break; - case 4: - data.value.__typeName = 'String'; - break; - case 5: - data.value.__typeName = 'DateTime'; - break; - case 6: - data.value.__typeName = 'uint64'; - break; - } - - return data; - } -} - -class Map { - constructor() { - this.__realMap = {}; - } - - add(key, value) { - this.__realMap[key] = value; - } - - toJSON() { - const list = []; - - for (const key in this.__realMap) { - if (Object.hasOwnProperty.call(this.__realMap, key)) { - const value = this.__realMap[key]; - - // * __typeName is populated in the frontend - list.push({ - key: { - __typeValue: key, - }, - value: { - __typeValue: value, - } - }); - } - } - - return list; - } -} - -module.exports = { - Structure, - Data, - AnyDataHolder, - RVConnectionData, - StationURL, - DateTime, - ResultRange, - Result, - Variant, - Map -}; diff --git a/src/types/frame.ts b/src/types/frame.ts new file mode 100644 index 0000000..fd6ca1f --- /dev/null +++ b/src/types/frame.ts @@ -0,0 +1,15 @@ +import type { EnhancedPacketBlock } from '@/types/pcapng-parser'; + +type SimpleFrame = { + timestamp: { + seconds: number; + microseconds: number; + }; + storedLength: number; + realLength: number; + data: Buffer; +}; + +type Frame = SimpleFrame | EnhancedPacketBlock; + +export default Frame; \ No newline at end of file diff --git a/src/types/nex/byte-stream-settings.ts b/src/types/nex/byte-stream-settings.ts new file mode 100644 index 0000000..7410170 --- /dev/null +++ b/src/types/nex/byte-stream-settings.ts @@ -0,0 +1,12 @@ +type NEXByteStreamSettings = { + pid_size: number; + string_length_size: number; + use_structure_header: boolean; + session_key_size: number; + kerberos_key_version: number; + kerberos_ticket_version: number; + checksum_size: number; + flags_and_type_size: number; +}; + +export default NEXByteStreamSettings; \ No newline at end of file diff --git a/src/types/nex/packet.ts b/src/types/nex/packet.ts new file mode 100644 index 0000000..c4883f8 --- /dev/null +++ b/src/types/nex/packet.ts @@ -0,0 +1,7 @@ +import PRUDPPacketV0 from '@/nex/prudp-packetv0'; +import PRUDPPacketV1 from '@/nex/prudp-packetv1'; +import RawRMCPacket from '@/nex/raw-rmc-packet'; + +type Packet = PRUDPPacketV0 | PRUDPPacketV1 | RawRMCPacket; + +export default Packet; \ No newline at end of file diff --git a/src/types/nex/service-protocol.ts b/src/types/nex/service-protocol.ts new file mode 100644 index 0000000..4989b08 --- /dev/null +++ b/src/types/nex/service-protocol.ts @@ -0,0 +1,10 @@ +import type Packet from '@/types/nex/packet'; + +type ServiceProtocol = { + ID: number; + Name: string; + + handlePacket(packet: Packet): void +} + +export default ServiceProtocol; \ No newline at end of file diff --git a/src/types/nex/udp-packet.ts b/src/types/nex/udp-packet.ts new file mode 100644 index 0000000..6c9cbb9 --- /dev/null +++ b/src/types/nex/udp-packet.ts @@ -0,0 +1,9 @@ +type UDPPacket = { + source: string; + destination: string; + sourcePort: number; + destinationPort: number; + payload: Buffer; +}; + +export default UDPPacket; \ No newline at end of file diff --git a/src/types/pcap-parser.ts b/src/types/pcap-parser.ts new file mode 100644 index 0000000..4470055 --- /dev/null +++ b/src/types/pcap-parser.ts @@ -0,0 +1,9 @@ +export type Packet = { + timestamp: { + seconds: number; + microseconds: number; + }; + storedLength: number; + realLength: number; + data: Buffer; +} \ No newline at end of file diff --git a/src/types/pcapng-parser.ts b/src/types/pcapng-parser.ts new file mode 100644 index 0000000..ba02d00 --- /dev/null +++ b/src/types/pcapng-parser.ts @@ -0,0 +1,51 @@ +export type OptionalData = Map; + +export type SectionHeaderBlock = { + be: boolean; + interfaces: InterfaceDescriptionBlock[]; + versionMajor: number; + versionMinor: number; + options: OptionalData; +}; + +export type InterfaceDescriptionBlock = { + linkLayerType: number; + reserved: number; + maxPacketLength: number; + options: OptionalData; +}; + +export type EnhancedPacketBlock = { + interfaceID: number; + timestamp: { + high: number; + low: number; + sectonds: number; + }, + storedLength: number; + realLength: number; + interface: NetworkInterface; + options: OptionalData; + data: Buffer; +}; + +export type SimplePacketBlock = { + realLength: number; + interface: NetworkInterface; + data: Buffer; +}; + +export type NameResolutionBlock = object; // * Unused +export type InterfaceStatisticsBlock = object; // * Unused +export type CustomBlock = object; // * Unused + +export type EthernetInterface = { + type: 1, + data: { + destinationMAC: string; + sourceMAC: string; + type: number; + } +}; + +export type NetworkInterface = EthernetInterface; \ No newline at end of file diff --git a/src/types/state.ts b/src/types/state.ts new file mode 100644 index 0000000..5b9e793 --- /dev/null +++ b/src/types/state.ts @@ -0,0 +1,8 @@ +type State = { + raw_rmc: boolean; + settings: { + recent_files: string[]; + }; +}; + +export default State; \ No newline at end of file diff --git a/src/util.js b/src/util.js deleted file mode 100644 index d9f90a4..0000000 --- a/src/util.js +++ /dev/null @@ -1,14 +0,0 @@ -const crypto = require('crypto'); - -/** - * - * @param {(string|Buffer)} input Input - * @returns {Buffer} MD5 hashed buffer - */ -function md5(input) { - return crypto.createHash('md5').update(input).digest(); -} - -module.exports = { - md5 -}; \ No newline at end of file diff --git a/src/windows/main/index.ts b/src/windows/main/index.ts new file mode 100644 index 0000000..2b97556 --- /dev/null +++ b/src/windows/main/index.ts @@ -0,0 +1,71 @@ +import path from 'node:path'; +import { app, BrowserWindow, ipcMain, Menu } from 'electron'; +import fs from 'fs-extra'; +import createMenu from '@/windows/main/menu'; +import type State from '@/types/state'; + +global.Object.defineProperty(global.BigInt.prototype, 'toJSON', { + value: function() { return this.toString(); }, + configurable: true, + enumerable: false, + writable: true +}); + +app.setName('NEX Viewer'); + +const appUserDataPath = app.getPath('userData'); +const settingsRootPath = path.join(appUserDataPath, 'settings.json'); + +if (!fs.existsSync(settingsRootPath)) { + fs.writeFileSync(settingsRootPath, JSON.stringify({ + recent_files: [] + })); +} + +const state: State = { + raw_rmc: false, + settings: fs.readJSONSync(settingsRootPath) +}; + +for (const recentFile of state.settings.recent_files) { + // TODO - Actually store these + app.addRecentDocument(recentFile); +} + +function createWindow(): void { + const window = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { // TODO - Use Electron's contextBridge instead + nodeIntegration: true, + contextIsolation: false + } + }); + + window.webContents.openDevTools(); + + ipcMain.on('renderer-ready', () => { + Menu.setApplicationMenu(createMenu(state)); + }); + + window.maximize(); + window.loadFile('../../renderers/main/index.html'); +} + +app.whenReady().then(() => { + Menu.setApplicationMenu(Menu.buildFromTemplate([])); // * Clear menu before frontend loads + + createWindow(); + + app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow(); + } + }); +}); + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit(); + } +}); \ No newline at end of file diff --git a/src/windows/main/menu.ts b/src/windows/main/menu.ts new file mode 100644 index 0000000..2c4e9b7 --- /dev/null +++ b/src/windows/main/menu.ts @@ -0,0 +1,8 @@ +import { Menu } from 'electron'; +import type State from '@/types/state'; + +export default function createComponentBuilder(_state: State): Menu { + return Menu.buildFromTemplate([ + // TODO + ]); +} \ No newline at end of file diff --git a/test/smm1/parse-smm1.js b/test/smm1/parse-smm1.js deleted file mode 100644 index 3226e93..0000000 --- a/test/smm1/parse-smm1.js +++ /dev/null @@ -1,8 +0,0 @@ -const NEXParser = require('../..'); -const parser = new NEXParser(); - -parser.on('packet', packet => { - // * DO SOMETHING -}); - -parser.parse(__dirname + '/smm.pcapng'); \ No newline at end of file diff --git a/titleids.txt b/titleids.txt deleted file mode 100644 index 49200c1..0000000 --- a/titleids.txt +++ /dev/null @@ -1,73 +0,0 @@ -Angry Birds Star Wars 3DS | 00040000000F2200, 00040000000F7A00 -Angry Birds Trilogy 3DS | 00040000000AE200, 00040000000AF400 -Animal Crossing: New Leaf | 0004000000086300, 0004000000086400, 0004000000198E00, 0004000000198F00, 0004000000199000 -Animal Crossing Plaza | 0005000010145600 -Axiom Verge | 00050000101F7900, 0005000010200800 -Badge Arcade | 0004000000153500, 0004000000153600 -BIOHAZARD REVELATIONS UE | 0005000010113100 -Devil's Third | 0005000010138F00, 0005000010177600, 0005000010177700, 0005000010197D00 -Disney INFINITY | 0005000010132900, 0005000010136F00, 0005000010137000, 000500001015A300 -Disney Infinity [2.0] | 000500001016DC00, 0005000010188C00, 0005000010188D00 -DISNEY INFINITY 3.0 | 00050000101AC900, 00050000101B3D00, 00050000101B3E00, 00050000101DDC00 -DKC: Tropical Freeze | 0005000010137F00, 0005000010138300, 0005000010144800 -DuckTales: Remastered | 0005000010129000, 0005000010129200 -FAST Racing NEO | 000500001012F000, 00050000101D6000, 00050000101E4100, 00050000101FED00 -FotNS: Ken's Rage 2 | 0005000010116600, 000500001012B800, 000500001012B900 -Game Party | 000500001010E400, 000500001010FF00 -Hyrule Warriors | 000500001017CD00, 000500001017D800, 000500001017D900 -Injustice: Gods Among Us | 0005000010111700, 0005000010111A00, 0005000010140700 -IRONFALL Invasion | 000400000015B100, 000400000015D800, 000400000017BF00, 000400000017D000 -Kid Icarus Uprising | 0004000000030000, 0004000000030100, 0004000000030200 -Legend of Kay | 0005000010193300, 0005000010193400 -LOST REAVERS | 000500001018D900, 00050000101A4800, 00050000101B9900 -Luigi's Mansion 2 | 0004000000055F00, 0004000000076400, 0004000000076500 -Mario & Sonic Rio 2016 3DS | 000400000014A400, 000400000017E200, 000400000017E300, 0004000000191C00, 0004000000191D00, 0004000000192400 -Mario & Sonic Rio 2016 Wii U | 0005000010190300, 00050000101E5300, 00050000101E5400 -MARIO & SONIC SOCHI 2014 | 0005000010106900, 000500001010C700, 000500001010C800 -MARIO KART 7 | 0004000000030600, 0004000000030700, 0004000000030800, 0004000000030A00, 000400000008B400 -MARIO KART 8 | 000500001010EB00, 000500001010EC00, 000500001010ED00 -Mario Tennis Open | 0004000000064D00, 000400000007C700, 000400000007C800, 00040000000B8800, 00040000000B9100 -Mario Tennis: Ultra Smash | 0005000010199000, 00050000101A3500, 00050000101A3600 -Mario vs. DK: Tipping Stars | 000400000012C800, 000400000012CA00, 0005000010149300, 0005000010178E00, 0005000010179200 -Metroid Prime: FF | 000400000016CE00, 000400000016E300, 0004000000175200 -MH3G HD Ver. | 0004000000048100, 0005000010104D00 -MH3U | 00040000000AE400, 00040000000B1D00, 00040000000D2E00, 0005000010117200, 0005000010118300 -Mighty No. 9 | 00050000101C5A00, 00050000101C9600, 00050000101DD900 -Minecraft: Wii U Edition | 00050000101D7500, 00050000101D9D00, 00050000101DBE00 -Nano Assault Neo | 0005000010110100, 0005000010110600, 0005000010136400 -NINJA GAIDEN 3: Razor's Edge | 0005000010110900, 0005000010110A00, 0005000010110B00, 0005000010139B00 -Nova-111 | 00050000101C0700, 00050000101C0A00 -OlliOlli | 000400000015A200, 000400000015A400, 00050000101A5E00, 00050000101A6900 -PIKMIN 3 | 000500001012BC00, 000500001012BD00, 000500001012BE00, 0005000010185300 -Pokémon Bank | 00040000000C9B00 -Pokémon Rumble World | 0004000000164600, 0004000000185A00 -Pokémon X/Y | 0004000000055D00 -POKKÉN TOURNAMENT | 00050000101C5800, 00050000101DF400, 00050000101DF500 -Puddle | 000500001010FB00, 0005000010110500, 00050000101A2700 -PUYOPUYOTETRIS | 0004000000101200, 000500001014D900 -RESIDENT EVIL REVELATIONS | 0004000000053B00, 000400000005EE00, 000500001012B400, 000500001012CF00 -RTK 12 | 0005000010111C00, 0005000010149000 -Runner2 | 000500001011AF00, 0005000010136300, 00050000101DD600 -SI2 | 0005000010173300, 0005000010176500 -SONIC LOST WORLD | 00040000000C5400, 00040000000C8C00, 00040000000CB400, 000400000010CF00, 0005000010128F00, 000500001012B100, 0005000010135700 -Sonic Transformed | 000400000008FC00, 00040000000B3500, 000500001010B300, 0005000010111F00, 000500001015B400 -Splatoon | 0005000010162B00, 0005000010176900, 0005000010176A00, 000500001017E300, 00050000101CDB00, 00050000101CDC00, 00050000101CDD00, 00050000101CDE00, 00050000101D6A00, 00050000101D6B00, 00050000101D6C00 -Star Fox Guard | 00050000101BEB00, 00050000101BEC00, 00050000101BED00 -Star Fox Guard (Demo) | 00050000101DCC00, 00050000101DCD00, 00050000101DCE00 -Star Wars Pinball | 00040000000D4A00, 00040000000E6800, 0005000010132A00, 0005000010135200 -Steel Diver: Sub Wars | 00040000000D7D00, 00040000000D7E00 -Super Mario Maker | 00040000001A0300, 00040000001A0400, 00040000001A0500, 00040000001BB800, 000500001018DB00, 000500001018DC00, 000500001018DD00 -Super Smash Bros. | 00040000000B8B00, 00040000000EDF00, 00040000000EE000, 0004000000167C00, 0005000010110E00, 0005000010144F00, 0005000010145000 -Team Kirby Clash Deluxe | 00040000001A8B00, 00040000001AB800, 00040000001AB900, 00040000001C2200, 00040000001CAA00, 00040000001CAD00 -TEKKEN TAG 2 Wii U EDITION | 0005000010100600, 000500001010F800, 0005000010110000 -Terraria | 000400000016A600, 000400000016A900, 00040000001B3200, 0005000010198F00, 000500001019C300, 00050000101F3A00 -TLoZ: Tri Force Heroes | 0004000000176E00, 0004000000176F00, 0004000000177000, 0004000000182200, 0004000000182300 -Trine 2 | 0005000010112200, 0005000010128A00, 000500001014D600 -WARRIORS OROCHI 3 Hyper | 000500001010EA00, 0005000010110200, 0005000010112B00 -Wii Karaoke U | 0005000010100D00, 0005000010102500, 0005000010149600 -Wii Party U | 000500001011A800, 0005000010137D00, 0005000010137E00 -Wii Sports Club | 000500001012F100, 0005000010144D00, 0005000010144E00, 0005000010171E00 -Xenoblade Chronicles X | 0005000010116100, 00050000101C4C00, 00050000101C4D00 -Yo-kai Watch 2 | 000400000012F800, 000400000012F900, 0004000000155100, 000400000019A900, 000400000019AA00, 000400000019AE00, 000400000019AF00, 00040000001B2700, 00040000001B2A00, 00040000001B7100, 00040000001BB500 -Zen Pinball 2 | 0005000010113800, 0005000010115F00 -役満 鳳凰 | 0005000010149700 diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..063dcb0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "strict": true, + "strictPropertyInitialization": false, + "sourceMap": true, + "declaration": true, + "resolveJsonModule": true, + "module": "commonjs", + "esModuleInterop": true, + "moduleResolution": "node", + "baseUrl": "src", + "outDir": "dist", + "allowJs": true, + "target": "es2022", + "noEmitOnError": true, + "paths": { + "@/*": ["./*"] + } + }, + "include": ["src"], + "ts-node": { + "require": ["tsconfig-paths/register"] + } +} \ No newline at end of file From d23ca8ea3fb31bf82290066a49ff320fc0eef86b Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Fri, 7 Jun 2024 17:23:10 -0400 Subject: [PATCH 02/67] chore: add TODO comment about merging folders in windows folder --- src/windows/main/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/windows/main/index.ts b/src/windows/main/index.ts index 2b97556..002e910 100644 --- a/src/windows/main/index.ts +++ b/src/windows/main/index.ts @@ -1,3 +1,5 @@ +// TODO - Should we just merge the "renderers" and "windows" folders? + import path from 'node:path'; import { app, BrowserWindow, ipcMain, Menu } from 'electron'; import fs from 'fs-extra'; From e744130c0c7d5c680204af49b674119f1011d750 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 12:40:11 -0400 Subject: [PATCH 03/67] fix: emit PRUDP packets in session --- src/nex/session.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nex/session.ts b/src/nex/session.ts index fd019eb..a18319a 100644 --- a/src/nex/session.ts +++ b/src/nex/session.ts @@ -69,6 +69,7 @@ export default class Session extends EventEmitter { for (const packet of packets) { this.processPacket(packet); + this.emit('packet', packet); } } From b53a6cad1b0c7ca99caf819d4e90bf1d36b487c6 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 13:36:00 -0400 Subject: [PATCH 04/67] chore: add packet serializing and better type defs/checks --- src/nex/connection.ts | 28 ++-- src/nex/protocols/secure-connection/index.ts | 5 + src/nex/protocols/ticket-granting/index.ts | 5 + src/nex/prudp-packet.ts | 129 ++++++++++++++++++- src/nex/prudp-packetv0.ts | 8 ++ src/nex/prudp-packetv1.ts | 35 ++++- src/nex/raw-rmc-packet.ts | 4 + src/nex/substream.ts | 4 +- 8 files changed, 189 insertions(+), 29 deletions(-) diff --git a/src/nex/connection.ts b/src/nex/connection.ts index 97448f3..48fac60 100644 --- a/src/nex/connection.ts +++ b/src/nex/connection.ts @@ -149,11 +149,11 @@ export default class Connection { this.reset(); // * Assume a new connection has started } - if (packet.isTypeSyn() && packet.fromServerToClient) { + if (packet.isTypeSyn() && packet.fromServerToClient && packet.connectionSignature) { this.serverConnectionSignature = packet.connectionSignature; } - if (packet.isTypeConnect() && packet.fromClientToServer) { + if (packet.isTypeConnect() && packet.fromClientToServer && packet.connectionSignature) { this.clientConnectionSignature = packet.connectionSignature; } @@ -209,9 +209,10 @@ export default class Connection { } let packets: Packet[]; + const substreamID = packet.substreamID || 0; if (packet.version !== -1) { - const substream = packet.fromClientToServer ? this.clientSubstream(packet.substreamID) : this.serverSubstream(packet.substreamID); + const substream = packet.fromClientToServer ? this.clientSubstream(substreamID) : this.serverSubstream(substreamID); packets = substream.update(packet); } else { packets = [packet]; @@ -220,16 +221,16 @@ export default class Connection { for (const packet of packets) { if (packet.isTypeData()) { // TODO - This whole section needs to be reworked to support different encryption and compression settings. Currently assumes RC4 and no compression - let defragmentedPayload: Buffer; + let defragmentedPayload: Buffer | null = null; if (packet.version !== -1) { - const substream = this.clientSubstream(packet.substreamID); + const substream = this.clientSubstream(substreamID); defragmentedPayload = substream.addFragment(packet); - } else { + } else if (packet.payload) { defragmentedPayload = packet.payload; } - if (packet.fragmentID === 0) { + if (packet.fragmentID === 0 && defragmentedPayload) { packet.defragmentedPayload = defragmentedPayload; this.processPacketMessage(packet); } @@ -240,7 +241,7 @@ export default class Connection { } private processPacketMessage(packet: Packet): void { - packet.message = new RMCMessage(packet.defragmentedPayload); + packet.message = new RMCMessage(packet.defragmentedPayload!); packet.message.connection = this; const protocol = getProtocol(packet.message); @@ -251,19 +252,20 @@ export default class Connection { if (!packet.message.error) { protocol.handlePacket(packet); } else { - const substream = packet.fromClientToServer ? this.clientSubstream(packet.substreamID) : this.serverSubstream(packet.substreamID); + const substreamID = packet.substreamID || 0; + const substream = packet.fromClientToServer ? this.clientSubstream(substreamID) : this.serverSubstream(substreamID); const seenPackets = packet.fromClientToServer ? substream.servertoClientSeenPackets : substream.clientToServerSeenPackets; // * Search packets from the other end const requestPacket = seenPackets.find(p => { if ( - p.message.type === RMCMessage.REQUEST && - p.message.protocolID === packet.message.protocolID && - p.message.callID === packet.message.callID + p.message?.type === RMCMessage.REQUEST && + p.message?.protocolID === packet.message?.protocolID && + p.message?.callID === packet.message?.callID ) { return true; } }); - if (requestPacket) { + if (requestPacket && requestPacket.message?.methodName) { packet.message.methodName = requestPacket.message.methodName; } else { packet.message.methodName = 'UnknownMethod'; diff --git a/src/nex/protocols/secure-connection/index.ts b/src/nex/protocols/secure-connection/index.ts index 736482e..5ef7ac2 100644 --- a/src/nex/protocols/secure-connection/index.ts +++ b/src/nex/protocols/secure-connection/index.ts @@ -24,6 +24,11 @@ export default class SecureConnectionProtocol { }; static handlePacket(packet: Packet): void { + if (!packet.message) { + // * This will never happen. Only checked to make TypeScript happy + return; + } + const methodID = packet.message.methodID; // TODO - Use Switch names when parsing Switch packets diff --git a/src/nex/protocols/ticket-granting/index.ts b/src/nex/protocols/ticket-granting/index.ts index ae53e33..33adda4 100644 --- a/src/nex/protocols/ticket-granting/index.ts +++ b/src/nex/protocols/ticket-granting/index.ts @@ -32,6 +32,11 @@ export default class TicketGrantingProtocol { }; static handlePacket(packet: Packet): void { + if (!packet.message) { + // * This will never happen. Only checked to make TypeScript happy + return; + } + const methodID = packet.message.methodID; // TODO - Use Switch names when parsing Switch packets diff --git a/src/nex/prudp-packet.ts b/src/nex/prudp-packet.ts index ad2d9a4..1ceb182 100644 --- a/src/nex/prudp-packet.ts +++ b/src/nex/prudp-packet.ts @@ -22,14 +22,14 @@ export default class PRUDPPacket { public sessionID: number; public signature: Buffer; public sequenceID: number; - public connectionSignature: Buffer; - public fragmentID: number; - public substreamID: number; - public payload: Buffer; - public decryptedPayload: Buffer; - public defragmentedPayload: Buffer; + public connectionSignature?: Buffer; + public fragmentID?: number; + public substreamID?: number; + public payload?: Buffer; + public decryptedPayload?: Buffer; + public defragmentedPayload?: Buffer; public connection: Connection; - public message: RMCMessage; + public message?: RMCMessage; protected stream: ByteStream; @@ -145,4 +145,119 @@ export default class PRUDPPacket { public hasFlagMultiAck(): boolean { return this.hasFlag(PRUDPPacket.FLAGS.MULTI_ACK); } + + public serialize(): Record { + const serialized: Record = { + version: this.version, + source_address: this.sourceAddress, + source_port: this.sourcePort, + destination_address: this.destinationAddress, + destination_port: this.destinationPort, + source_stream_id: this.sourceStreamID, + source_stream_type: this.serializeStreamType(this.sourceStreamType), + destination_stream_id: this.destinationStreamID, + destination_stream_type: this.serializeStreamType(this.destinationStreamType), + type: this.serializeType(), + flags: this.serializeFlags(), + session_id: this.sessionID, + signature: this.signature, + sequence_id: this.sequenceID + }; + + if (this.version === 1) { + serialized.substream_id = this.substreamID; + } + + if (this.connectionSignature) { + serialized.connection_signature = this.connectionSignature; + } + + serialized.payload = this.payload; + serialized.decrypted_payload = this.decryptedPayload; + + if (this.isTypeData()) { + serialized.fragment_id = this.fragmentID; + + if (this.fragmentID === 0) { + serialized.message = this.message; + serialized.defragmented_payload = this.defragmentedPayload; + } + } + + return serialized; + } + + private serializeStreamType(streamType: number): string { + switch(streamType) { + case 1: + return 'DO'; + case 2: + return 'RV'; + case 3: + return 'OldRVSec'; + case 4: + return 'SBMGMT'; + case 5: + return 'NAT'; + case 6: + return 'SessionDiscovery'; + case 7: + return 'NATEcho'; + case 8: + return 'Routing'; + case 9: + return 'Game'; + case 10: + return 'RVSecure'; + case 11: + return 'Relay'; + } + + throw new Error(`Unsupported stream type ${streamType}`); + } + + private serializeType(): string { + switch(this.type) { + case 0: + return 'SYN'; + case 1: + return 'CONNECT'; + case 2: + return 'DATA'; + case 3: + return 'DISCONNECT'; + case 4: + return 'PING'; + case 5: + return 'USER'; + } + + throw new Error(`Unsupported packet type ${this.type}`); + } + + private serializeFlags(): string[] { + const flags: string[] = []; + + if (this.hasFlagAck()) { + flags.push('ACK'); + } + + if (this.hasFlagReliable()) { + flags.push('RELIABLE'); + } + + if (this.hasFlagNeedAck()) { + flags.push('NEED_ACK'); + } + + if (this.hasFlagHasSize()) { + flags.push('HAS_SIZE'); + } + + if (this.hasFlagMultiAck()) { + flags.push('MULTI_ACK'); + } + + return flags; + } } \ No newline at end of file diff --git a/src/nex/prudp-packetv0.ts b/src/nex/prudp-packetv0.ts index bfb751e..5e73f51 100644 --- a/src/nex/prudp-packetv0.ts +++ b/src/nex/prudp-packetv0.ts @@ -93,4 +93,12 @@ export default class PRUDPPacketV0 extends PRUDPPacket { return checksum & 0xFF; } + + public toJSON(): Record { + const serialized = this.serialize(); + + serialized.checksum = this.checksum; + + return serialized; + } } \ No newline at end of file diff --git a/src/nex/prudp-packetv1.ts b/src/nex/prudp-packetv1.ts index 6cd91e3..67d7313 100644 --- a/src/nex/prudp-packetv1.ts +++ b/src/nex/prudp-packetv1.ts @@ -9,6 +9,9 @@ export default class PRUDPPacketV1 extends PRUDPPacket { private payloadLength: number; private headerBytes: Buffer; // * Used for the signature calculation private optionsBytes: Buffer; // * Used for the signature calculation + private supportedFunctions?: Buffer; + private initialUnreliableSequenceID?: number; + private maximumSubstreamID?: number; static Magic = Buffer.from([0xEA, 0xD0]); @@ -99,8 +102,7 @@ export default class PRUDPPacketV1 extends PRUDPPacket { throw new Error('Invalid PRUDPv1 option ID'); } - // * Supported functions. Not needed here - optionsStream.skip(optionSize); + this.supportedFunctions = optionsStream.readBytes(optionSize); } if (optionID === 1) { @@ -124,8 +126,7 @@ export default class PRUDPPacketV1 extends PRUDPPacket { throw new Error('Invalid PRUDPv1 option ID'); } - // * Initial sequence id for unreliable data packets. Not needed here - optionsStream.skip(optionSize); + this.initialUnreliableSequenceID = optionsStream.readUInt16LE(); } if (optionID === 4) { @@ -133,8 +134,7 @@ export default class PRUDPPacketV1 extends PRUDPPacket { throw new Error('Invalid PRUDPv1 option ID'); } - // * Maximum substream ID. Not needed here - optionsStream.skip(optionSize); + this.maximumSubstreamID = optionsStream.readUInt8(); } } } @@ -154,8 +154,29 @@ export default class PRUDPPacketV1 extends PRUDPPacket { mac.update(accessKeySumBytes); mac.update(connectionSignature); mac.update(this.optionsBytes); - mac.update(this.payload); + + if (this.payload) { + mac.update(this.payload); + } return mac.digest(); } + + public toJSON(): Record { + const serialized = this.serialize(); + + if (this.supportedFunctions) { + serialized.supported_functions = this.supportedFunctions; + } + + if (this.initialUnreliableSequenceID) { + serialized.initial_unreliable_sequence_id = this.initialUnreliableSequenceID; + } + + if (this.maximumSubstreamID) { + serialized.maximum_substream_id = this.maximumSubstreamID; + } + + return serialized; + } } \ No newline at end of file diff --git a/src/nex/raw-rmc-packet.ts b/src/nex/raw-rmc-packet.ts index cc0223f..d89a395 100644 --- a/src/nex/raw-rmc-packet.ts +++ b/src/nex/raw-rmc-packet.ts @@ -45,4 +45,8 @@ export default class RawRMCPacket extends PRUDPPacket { this.destinationStreamType = -1; this.destinationStreamID = -1; } + + public toJSON(): Record { + return this.serialize(); + } } \ No newline at end of file diff --git a/src/nex/substream.ts b/src/nex/substream.ts index 12864fd..a740931 100644 --- a/src/nex/substream.ts +++ b/src/nex/substream.ts @@ -57,7 +57,7 @@ export default class Substream { let payload = packet.payload; // * Raw RMC packets and PRUDP Lite do not encrypt payloads - if (packet.version === 0 || packet.version === 1) { + if ((packet.version === 0 || packet.version === 1) && payload) { payload = cipher.update(payload); } @@ -65,7 +65,7 @@ export default class Substream { payload = Buffer.concat([ fragmentedPayload, - payload, + payload || Buffer.alloc(0), ]); seenPackets.push(packet); From 2a189755962f0b0d266600438a14ad460bc4345a Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 13:49:44 -0400 Subject: [PATCH 05/67] chore(types): update type imports for Packet type def --- src/types/nex/packet.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/types/nex/packet.ts b/src/types/nex/packet.ts index c4883f8..f1537e7 100644 --- a/src/types/nex/packet.ts +++ b/src/types/nex/packet.ts @@ -1,6 +1,6 @@ -import PRUDPPacketV0 from '@/nex/prudp-packetv0'; -import PRUDPPacketV1 from '@/nex/prudp-packetv1'; -import RawRMCPacket from '@/nex/raw-rmc-packet'; +import type PRUDPPacketV0 from '@/nex/prudp-packetv0'; +import type PRUDPPacketV1 from '@/nex/prudp-packetv1'; +import type RawRMCPacket from '@/nex/raw-rmc-packet'; type Packet = PRUDPPacketV0 | PRUDPPacketV1 | RawRMCPacket; From 662e2178a1fe5d93e181dd17b9757e91f888e5cd Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 14:55:10 -0400 Subject: [PATCH 06/67] chore(lint): add browser globals to eslint config --- eslint.config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eslint.config.js b/eslint.config.js index 8e4260d..0ba95e2 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,3 +1,4 @@ +const globals = require('globals'); const eslint = require('@eslint/js'); const tseslint = require('typescript-eslint'); @@ -7,6 +8,7 @@ module.exports = [ { languageOptions: { globals: { + ...globals.browser, node: true, commonjs: true, es6: true, From c9a9b988e3898973040e86ccaa4efd6ac809c1cb Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 14:55:56 -0400 Subject: [PATCH 07/67] chore: add browserify command for building --- package-lock.json | 1595 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 7 +- 2 files changed, 1588 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 24dfa40..74821f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@eslint/js": "^9.1.1", "@types/fs-extra": "^11.0.4", "@types/semver": "^7.5.8", + "browserify": "^17.0.0", "electron": "^30.0.1", "eslint": "^8.57.0", "rimraf": "^5.0.5", @@ -625,6 +626,38 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dev": true, + "dependencies": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-node/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -693,12 +726,89 @@ "node": ">=8" } }, + "node_modules/asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/assert": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz", + "integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==", + "dev": true, + "dependencies": { + "object.assign": "^4.1.4", + "util": "^0.10.4" + } + }, + "node_modules/assert/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/assert/node_modules/util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -711,6 +821,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, "node_modules/boolean": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", @@ -740,6 +856,214 @@ "node": ">=8" } }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "node_modules/browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "dependencies": { + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "JSONStream": "^1.0.3", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + }, + "bin": { + "browser-pack": "bin/cmd.js" + } + }, + "node_modules/browser-resolve": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", + "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", + "dev": true, + "dependencies": { + "resolve": "^1.17.0" + } + }, + "node_modules/browserify": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-17.0.0.tgz", + "integrity": "sha512-SaHqzhku9v/j6XsQMRxPyBrSP3gnwmE27gLJYZgMT2GeK3J0+0toN+MnuNYDfHwVGQfLiMZ7KSNSIXHemy905w==", + "dev": true, + "dependencies": { + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^2.0.0", + "browserify-zlib": "~0.2.0", + "buffer": "~5.2.1", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.1", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^3.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.2.1", + "JSONStream": "^1.0.3", + "labeled-stream-splicer": "^2.0.0", + "mkdirp-classic": "^0.5.2", + "module-deps": "^6.2.3", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "^1.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum-object": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^3.0.0", + "stream-http": "^3.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.12.0", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + }, + "bin": { + "browserify": "bin/cmd.js" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", + "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.5", + "hash-base": "~3.0", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.7", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserify/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/browserify/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -749,6 +1073,24 @@ "node": "*" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, "node_modules/cacheable-lookup": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", @@ -776,6 +1118,31 @@ "node": ">=8" } }, + "node_modules/cached-path-relative": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", + "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==", + "dev": true + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -825,6 +1192,16 @@ "fsevents": "~2.3.2" } }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/clone-response": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", @@ -855,6 +1232,18 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", + "dev": true, + "dependencies": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, "node_modules/commander": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", @@ -870,6 +1259,88 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -884,6 +1355,34 @@ "node": ">= 8" } }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dash-ast": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", + "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", + "dev": true + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -948,7 +1447,6 @@ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, - "optional": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -966,7 +1464,6 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, - "optional": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -979,6 +1476,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deps-sort": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz", + "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==", + "dev": true, + "dependencies": { + "JSONStream": "^1.0.3", + "shasum-object": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + }, + "bin": { + "deps-sort": "bin/cmd.js" + } + }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -986,6 +1517,40 @@ "dev": true, "optional": true }, + "node_modules/detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dev": true, + "dependencies": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1010,6 +1575,25 @@ "node": ">=6.0.0" } }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true, + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -1034,6 +1618,27 @@ "node": ">= 12.20.55" } }, + "node_modules/elliptic": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", + "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -1063,7 +1668,6 @@ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, - "optional": true, "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -1076,7 +1680,6 @@ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, - "optional": true, "engines": { "node": ">= 0.4" } @@ -1263,6 +1866,25 @@ "node": ">=0.10.0" } }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -1317,6 +1939,12 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -1430,6 +2058,15 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/foreground-child": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", @@ -1484,17 +2121,21 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "optional": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, - "optional": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -1668,7 +2309,6 @@ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "optional": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -1712,6 +2352,15 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1726,7 +2375,6 @@ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, - "optional": true, "dependencies": { "es-define-property": "^1.0.0" }, @@ -1739,7 +2387,6 @@ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, - "optional": true, "engines": { "node": ">= 0.4" }, @@ -1752,7 +2399,6 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, - "optional": true, "engines": { "node": ">= 0.4" }, @@ -1760,12 +2406,49 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, - "optional": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -1773,6 +2456,26 @@ "node": ">= 0.4" } }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, "node_modules/http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", @@ -1792,6 +2495,32 @@ "node": ">=10.19.0" } }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -1842,6 +2571,52 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/inline-source-map": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.3.tgz", + "integrity": "sha512-1aVsPEsJWMJq/pdMU61CDlm1URcW702MTB4w9/zUjMus6H/Py8o7g68Pr9D4I6QluWGt/KdmswuRhaA05xVR1w==", + "dev": true, + "dependencies": { + "source-map": "~0.5.3" + } + }, + "node_modules/insert-module-globals": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz", + "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==", + "dev": true, + "dependencies": { + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "JSONStream": "^1.0.3", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.0.0" + }, + "bin": { + "insert-module-globals": "bin/cmd.js" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -1854,6 +2629,36 @@ "node": ">=8" } }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1872,6 +2677,21 @@ "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -1902,6 +2722,27 @@ "node": ">=8" } }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1986,6 +2827,31 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -1995,6 +2861,16 @@ "json-buffer": "3.0.1" } }, + "node_modules/labeled-stream-splicer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", + "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "stream-splicer": "^2.0.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -2023,6 +2899,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -2062,6 +2944,17 @@ "node": ">=10" } }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2084,6 +2977,25 @@ "node": ">=8.6" } }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", @@ -2093,6 +3005,18 @@ "node": ">=4" } }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2123,6 +3047,41 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/module-deps": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz", + "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==", + "dev": true, + "dependencies": { + "browser-resolve": "^2.0.0", + "cached-path-relative": "^1.0.2", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.2.0", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "JSONStream": "^1.0.3", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + }, + "bin": { + "module-deps": "bin/cmd.js" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2169,16 +3128,42 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, - "optional": true, "engines": { "node": ">= 0.4" } }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2205,6 +3190,12 @@ "node": ">= 0.8.0" } }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true + }, "node_modules/p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", @@ -2244,6 +3235,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2256,6 +3253,38 @@ "node": ">=6" } }, + "node_modules/parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==", + "dev": true, + "dependencies": { + "path-platform": "~0.11.15" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", + "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", + "dev": true, + "dependencies": { + "asn1.js": "^4.10.1", + "browserify-aes": "^1.2.0", + "evp_bytestokey": "^1.0.3", + "hash-base": "~3.0", + "pbkdf2": "^3.1.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2283,6 +3312,21 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/path-scurry": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", @@ -2317,6 +3361,22 @@ "node": ">=8" } }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -2347,6 +3407,15 @@ "node": ">=12" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -2356,6 +3425,21 @@ "node": ">= 0.8.0" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -2365,6 +3449,26 @@ "node": ">=0.4.0" } }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -2384,6 +3488,30 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/queue-lit": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/queue-lit/-/queue-lit-1.5.2.tgz", @@ -2425,6 +3553,64 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/read-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/readable-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -2437,6 +3623,23 @@ "node": ">=8.10.0" } }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-alpn": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", @@ -2492,6 +3695,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, "node_modules/roarr": { "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", @@ -2533,6 +3746,26 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", @@ -2570,6 +3803,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shasum-object": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz", + "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==", + "dev": true, + "dependencies": { + "fast-safe-stringify": "^2.0.7" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -2591,6 +3863,33 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -2603,6 +3902,26 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -2612,6 +3931,15 @@ "node": ">=8" } }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sprintf-js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", @@ -2619,6 +3947,85 @@ "dev": true, "optional": true }, + "node_modules/stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dev": true, + "dependencies": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "node_modules/stream-browserify/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", + "dev": true, + "dependencies": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-http": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "node_modules/stream-http/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", + "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -2730,6 +4137,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==", + "dev": true, + "dependencies": { + "minimist": "^1.1.0" + } + }, "node_modules/sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", @@ -2754,12 +4170,61 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "dependencies": { + "acorn-node": "^1.2.0" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==", + "dev": true, + "dependencies": { + "process": "~0.11.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2815,6 +4280,12 @@ "node": ">=6" } }, + "node_modules/tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -2840,6 +4311,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, "node_modules/typescript": { "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", @@ -2879,6 +4356,31 @@ } } }, + "node_modules/umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true, + "bin": { + "umd": "bin/cli.js" + } + }, + "node_modules/undeclared-identifiers": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", + "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", + "dev": true, + "dependencies": { + "acorn-node": "^1.3.0", + "dash-ast": "^1.0.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + }, + "bin": { + "undeclared-identifiers": "bin.js" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -2902,6 +4404,47 @@ "punycode": "^2.1.0" } }, + "node_modules/url": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", + "dev": true, + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.11.2" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2917,6 +4460,25 @@ "node": ">= 8" } }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", @@ -3017,6 +4579,15 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/package.json b/package.json index e7de045..56318cd 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,10 @@ "scripts": { "lint": "./node_modules/.bin/eslint ./src", "clean": "rimraf ./dist", - "copy-html": "mkdir -p ./dist/renderers/main && cp ./src/renderers/main/index.html ./dist/renderers/main/index.html", - "build": "npm run lint && npm run clean && npx tsc && npx tsc-alias && npm run copy-html", + "copy-html": "mkdir -p ./dist/renderers/main && cp ./src/renderers/main/index.html ./dist/renderers/main/index.html", + "build": "npm run lint && npm run clean && npm run compile && npm run browserify", + "compile": "npx tsc && npx tsc-alias && npm run copy-html", + "browserify": "browserify ./dist/renderers/main/assets/js/util.js ./dist/renderers/main/assets/js/renderer.js -o ./dist/renderers/main/assets/js/bundle.js", "start": "electron dist/windows/main/index.js" }, "keywords": [], @@ -17,6 +19,7 @@ "@eslint/js": "^9.1.1", "@types/fs-extra": "^11.0.4", "@types/semver": "^7.5.8", + "browserify": "^17.0.0", "electron": "^30.0.1", "eslint": "^8.57.0", "rimraf": "^5.0.5", From a5e43039f261d43babd20702de7329d49bf57388 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 14:59:30 -0400 Subject: [PATCH 08/67] refactor(rmc): update serialized RMC message data --- src/nex/rmc-message.ts | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/nex/rmc-message.ts b/src/nex/rmc-message.ts index 674aba7..820e389 100644 --- a/src/nex/rmc-message.ts +++ b/src/nex/rmc-message.ts @@ -12,7 +12,7 @@ export default class RMCMessage { private _methodID: number; private _callID: number; private _error?: QResult; - private _parametersData: Buffer; + private _parametersData?: Buffer; public parameters?: any; public methodName: string; @@ -43,7 +43,7 @@ export default class RMCMessage { return this._error; } - get parametersData(): Buffer { + get parametersData(): Buffer | undefined { return this._parametersData; } @@ -103,16 +103,23 @@ export default class RMCMessage { } public toJSON(): Record { - const json: Record = { + const serialized: Record = { type: this._type, - protocolID: this._protocolID, - protocolName: this.protocolName, - methodID: this._methodID, - methodName: this.methodName, - callID: this._callID, - parameters: this.parameters + protocol_id: this._protocolID, + protocol_name: this.protocolName, + method_id: this._methodID, + method_name: this.methodName, + call_id: this._callID }; - return json; + if (this.parameters) { + serialized.parameters = this.parameters; + } + + if (this._error) { + serialized._error = this._error; + } + + return serialized; } } \ No newline at end of file From 336c02d4cdad6547cbab990f6af74c747c43fffc Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 15:00:23 -0400 Subject: [PATCH 09/67] refactor(prudp): update serialized PRUDPPacket/PRUDPPacketV1 data --- src/nex/prudp-packet.ts | 18 +++++++++++------- src/nex/prudp-packetv1.ts | 2 ++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/nex/prudp-packet.ts b/src/nex/prudp-packet.ts index 1ceb182..98ac922 100644 --- a/src/nex/prudp-packet.ts +++ b/src/nex/prudp-packet.ts @@ -164,24 +164,28 @@ export default class PRUDPPacket { sequence_id: this.sequenceID }; - if (this.version === 1) { - serialized.substream_id = this.substreamID; - } - if (this.connectionSignature) { serialized.connection_signature = this.connectionSignature; } - serialized.payload = this.payload; - serialized.decrypted_payload = this.decryptedPayload; + if (this.payload) { + serialized.payload = this.payload; + } + + if (this.decryptedPayload) { + serialized.decrypted_payload = this.decryptedPayload; + } if (this.isTypeData()) { serialized.fragment_id = this.fragmentID; if (this.fragmentID === 0) { - serialized.message = this.message; serialized.defragmented_payload = this.defragmentedPayload; } + + if (this.message) { + serialized.message = this.message; + } } return serialized; diff --git a/src/nex/prudp-packetv1.ts b/src/nex/prudp-packetv1.ts index 67d7313..1fcdbd2 100644 --- a/src/nex/prudp-packetv1.ts +++ b/src/nex/prudp-packetv1.ts @@ -165,6 +165,8 @@ export default class PRUDPPacketV1 extends PRUDPPacket { public toJSON(): Record { const serialized = this.serialize(); + serialized.substream_id = this.substreamID; + if (this.supportedFunctions) { serialized.supported_functions = this.supportedFunctions; } From 68260344d87656cbc31526f9c440fbb468dc66b3 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 15:00:55 -0400 Subject: [PATCH 10/67] chore(types): add serialized packet type def --- src/types/nex/serialized-packet.ts | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/types/nex/serialized-packet.ts diff --git a/src/types/nex/serialized-packet.ts b/src/types/nex/serialized-packet.ts new file mode 100644 index 0000000..9475ec7 --- /dev/null +++ b/src/types/nex/serialized-packet.ts @@ -0,0 +1,41 @@ +import type RMCMessage from '@/nex/rmc-message'; + +type SerializedPRUDPPacket = { + version: number; + source_address: string; + source_port: number; + destination_address: string; + destination_port: number; + source_stream_id: number; + source_stream_type: string; + destination_stream_id: number; + destination_stream_type: string; + type: string + flags: string[] + session_id: number; + signature: Buffer; + sequence_id: number; + connection_signature?: Buffer; + fragment_id?: number; + payload?: Buffer; + decrypted_payload?: Buffer; + defragmented_payload?: Buffer; + message?: RMCMessage; +}; + +type SerializedPRUDPV0Packet = SerializedPRUDPPacket & { + version: 0; + checksum: number; +}; + +type SerializedPRUDPV1Packet = SerializedPRUDPPacket & { + version: 1; + substream_id: number; + supported_functions?: Buffer; + initial_unreliable_sequence_id?: number; + maximum_substream_id?: number; +}; + +type SerializedPacket = SerializedPRUDPPacket | SerializedPRUDPV0Packet | SerializedPRUDPV1Packet; + +export default SerializedPacket; \ No newline at end of file From 769b9d2ea0de274fa566493d3bc23b28961ed212 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 15:47:56 -0400 Subject: [PATCH 11/67] fix(rmc): rename _error to error on serialized RMC message data --- src/nex/rmc-message.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nex/rmc-message.ts b/src/nex/rmc-message.ts index 820e389..de246c0 100644 --- a/src/nex/rmc-message.ts +++ b/src/nex/rmc-message.ts @@ -117,7 +117,7 @@ export default class RMCMessage { } if (this._error) { - serialized._error = this._error; + serialized.error = this._error; } return serialized; From 8a4e758d5d3bec48c5af17eb2a896e47b31e17b6 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 15:48:50 -0400 Subject: [PATCH 12/67] fix(protocols): assert that RMC parameters exist in method handlers --- src/nex/protocols/secure-connection/requests/register-ex.ts | 2 +- src/nex/protocols/secure-connection/requests/register.ts | 2 +- src/nex/protocols/secure-connection/responses/register-ex.ts | 2 +- src/nex/protocols/secure-connection/responses/register.ts | 2 +- src/nex/protocols/ticket-granting/requests/login-ex.ts | 2 +- src/nex/protocols/ticket-granting/requests/login.ts | 2 +- src/nex/protocols/ticket-granting/requests/request-ticket.ts | 2 +- src/nex/protocols/ticket-granting/responses/login-ex.ts | 2 +- src/nex/protocols/ticket-granting/responses/login.ts | 2 +- src/nex/protocols/ticket-granting/responses/request-ticket.ts | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/nex/protocols/secure-connection/requests/register-ex.ts b/src/nex/protocols/secure-connection/requests/register-ex.ts index 509fbe6..3123d80 100644 --- a/src/nex/protocols/secure-connection/requests/register-ex.ts +++ b/src/nex/protocols/secure-connection/requests/register-ex.ts @@ -11,7 +11,7 @@ export default class RegisterExRequest { private hCustomData = new AnyDataHolder(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); this.vecMyURLs.extractFrom(stream); this.hCustomData.extractFrom(stream); diff --git a/src/nex/protocols/secure-connection/requests/register.ts b/src/nex/protocols/secure-connection/requests/register.ts index ae62485..19dba12 100644 --- a/src/nex/protocols/secure-connection/requests/register.ts +++ b/src/nex/protocols/secure-connection/requests/register.ts @@ -9,7 +9,7 @@ export default class RegisterRequest { private vecMyURLs = new List(new StationURL()); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); this.vecMyURLs.extractFrom(stream); } diff --git a/src/nex/protocols/secure-connection/responses/register-ex.ts b/src/nex/protocols/secure-connection/responses/register-ex.ts index 1587b6b..23f1b32 100644 --- a/src/nex/protocols/secure-connection/responses/register-ex.ts +++ b/src/nex/protocols/secure-connection/responses/register-ex.ts @@ -12,7 +12,7 @@ export default class RegisterExResponse { private urlPublic = new StationURL(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); this.retval.extractFrom(stream); diff --git a/src/nex/protocols/secure-connection/responses/register.ts b/src/nex/protocols/secure-connection/responses/register.ts index 9b38c0a..ccd5a49 100644 --- a/src/nex/protocols/secure-connection/responses/register.ts +++ b/src/nex/protocols/secure-connection/responses/register.ts @@ -12,7 +12,7 @@ export default class RegisterResponse { private urlPublic = new StationURL(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); this.retval.extractFrom(stream); diff --git a/src/nex/protocols/ticket-granting/requests/login-ex.ts b/src/nex/protocols/ticket-granting/requests/login-ex.ts index 6dd024d..1059818 100644 --- a/src/nex/protocols/ticket-granting/requests/login-ex.ts +++ b/src/nex/protocols/ticket-granting/requests/login-ex.ts @@ -10,7 +10,7 @@ export default class LoginExRequest { private oExtraData = new AnyDataHolder(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); this.strUserName.extractFrom(stream); this.oExtraData.extractFrom(stream); diff --git a/src/nex/protocols/ticket-granting/requests/login.ts b/src/nex/protocols/ticket-granting/requests/login.ts index 39eb9e1..9ca03a0 100644 --- a/src/nex/protocols/ticket-granting/requests/login.ts +++ b/src/nex/protocols/ticket-granting/requests/login.ts @@ -8,7 +8,7 @@ export default class LoginRequest { private strUserName = new RVString(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); this.strUserName.extractFrom(stream); } diff --git a/src/nex/protocols/ticket-granting/requests/request-ticket.ts b/src/nex/protocols/ticket-granting/requests/request-ticket.ts index 28edf9a..2a1716a 100644 --- a/src/nex/protocols/ticket-granting/requests/request-ticket.ts +++ b/src/nex/protocols/ticket-granting/requests/request-ticket.ts @@ -9,7 +9,7 @@ export default class RequestTicketRequest { private idTarget = new PID(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); this.idSource.extractFrom(stream); this.idTarget.extractFrom(stream); diff --git a/src/nex/protocols/ticket-granting/responses/login-ex.ts b/src/nex/protocols/ticket-granting/responses/login-ex.ts index 2e6d8e6..661cb59 100644 --- a/src/nex/protocols/ticket-granting/responses/login-ex.ts +++ b/src/nex/protocols/ticket-granting/responses/login-ex.ts @@ -16,7 +16,7 @@ export default class LoginExResponse { private strReturnMsg = new RVString(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); this.retval.extractFrom(stream); diff --git a/src/nex/protocols/ticket-granting/responses/login.ts b/src/nex/protocols/ticket-granting/responses/login.ts index 0e487cf..edaae96 100644 --- a/src/nex/protocols/ticket-granting/responses/login.ts +++ b/src/nex/protocols/ticket-granting/responses/login.ts @@ -16,7 +16,7 @@ export default class LoginResponse { private strReturnMsg = new RVString(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); this.retval.extractFrom(stream); diff --git a/src/nex/protocols/ticket-granting/responses/request-ticket.ts b/src/nex/protocols/ticket-granting/responses/request-ticket.ts index ec3190e..4770233 100644 --- a/src/nex/protocols/ticket-granting/responses/request-ticket.ts +++ b/src/nex/protocols/ticket-granting/responses/request-ticket.ts @@ -12,7 +12,7 @@ export default class RequestTicketResponse { private pSourceKey = new RVString(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); this.retval.extractFrom(stream); From 4b8b597b107667e0d9e31f093a028f14f0e6ac3c Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 15:58:10 -0400 Subject: [PATCH 13/67] chore(rmc): add serialized RMC message type def --- src/nex/rmc-message.ts | 5 ++++- src/types/nex/serialized-packet.ts | 4 ++-- src/types/nex/serialized-rmc-message.ts | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 src/types/nex/serialized-rmc-message.ts diff --git a/src/nex/rmc-message.ts b/src/nex/rmc-message.ts index de246c0..097e7b6 100644 --- a/src/nex/rmc-message.ts +++ b/src/nex/rmc-message.ts @@ -117,7 +117,10 @@ export default class RMCMessage { } if (this._error) { - serialized.error = this._error; + serialized.error = { + code: this._error.code, + name: this._error.name() + }; } return serialized; diff --git a/src/types/nex/serialized-packet.ts b/src/types/nex/serialized-packet.ts index 9475ec7..72e7d5e 100644 --- a/src/types/nex/serialized-packet.ts +++ b/src/types/nex/serialized-packet.ts @@ -1,4 +1,4 @@ -import type RMCMessage from '@/nex/rmc-message'; +import type SerializedRMCMessage from '@/types/nex/serialized-rmc-message'; type SerializedPRUDPPacket = { version: number; @@ -20,7 +20,7 @@ type SerializedPRUDPPacket = { payload?: Buffer; decrypted_payload?: Buffer; defragmented_payload?: Buffer; - message?: RMCMessage; + message?: SerializedRMCMessage; }; type SerializedPRUDPV0Packet = SerializedPRUDPPacket & { diff --git a/src/types/nex/serialized-rmc-message.ts b/src/types/nex/serialized-rmc-message.ts new file mode 100644 index 0000000..663784b --- /dev/null +++ b/src/types/nex/serialized-rmc-message.ts @@ -0,0 +1,15 @@ +type SerializedRMCMessage = { + type: 0 | 1; + protocol_id: number; + protocol_name: string; + method_id: number; + method_name: string; + call_id: number; + parameters?: any; + error?: { + code: number; + name: string; + }; +}; + +export default SerializedRMCMessage; \ No newline at end of file From 694bc1656a5a730fd8911a8dc86ea0ca6e29f190 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sat, 8 Jun 2024 16:04:23 -0400 Subject: [PATCH 14/67] refactor: make toJSON methods return serialized types --- src/nex/prudp-packet.ts | 7 ++++--- src/nex/prudp-packetv0.ts | 5 +++-- src/nex/prudp-packetv1.ts | 7 ++++--- src/nex/raw-rmc-packet.ts | 3 ++- src/nex/rmc-message.ts | 5 +++-- src/types/nex/serialized-packet.ts | 6 +++--- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/nex/prudp-packet.ts b/src/nex/prudp-packet.ts index 98ac922..04ce1f4 100644 --- a/src/nex/prudp-packet.ts +++ b/src/nex/prudp-packet.ts @@ -1,6 +1,7 @@ import ByteStream from '@/byte-stream'; import RMCMessage from '@/nex/rmc-message'; import Connection from '@/nex/connection'; +import type { SerializedPRUDPPacket } from '@/types/nex/serialized-packet'; export default class PRUDPPacket { public readonly version: number; @@ -146,8 +147,8 @@ export default class PRUDPPacket { return this.hasFlag(PRUDPPacket.FLAGS.MULTI_ACK); } - public serialize(): Record { - const serialized: Record = { + public serialize(): SerializedPRUDPPacket { + const serialized: SerializedPRUDPPacket = { version: this.version, source_address: this.sourceAddress, source_port: this.sourcePort, @@ -184,7 +185,7 @@ export default class PRUDPPacket { } if (this.message) { - serialized.message = this.message; + serialized.message = this.message.toJSON(); } } diff --git a/src/nex/prudp-packetv0.ts b/src/nex/prudp-packetv0.ts index 5e73f51..2965f0b 100644 --- a/src/nex/prudp-packetv0.ts +++ b/src/nex/prudp-packetv0.ts @@ -1,5 +1,6 @@ import ByteStream from '@/byte-stream'; import PRUDPPacket from '@/nex/prudp-packet'; +import type { SerializedPRUDPV0Packet } from '@/types/nex/serialized-packet'; export default class PRUDPPacketV0 extends PRUDPPacket { public readonly version = 0; @@ -94,8 +95,8 @@ export default class PRUDPPacketV0 extends PRUDPPacket { return checksum & 0xFF; } - public toJSON(): Record { - const serialized = this.serialize(); + public toJSON(): SerializedPRUDPV0Packet { + const serialized = this.serialize() as SerializedPRUDPV0Packet; serialized.checksum = this.checksum; diff --git a/src/nex/prudp-packetv1.ts b/src/nex/prudp-packetv1.ts index 1fcdbd2..e28ec22 100644 --- a/src/nex/prudp-packetv1.ts +++ b/src/nex/prudp-packetv1.ts @@ -1,6 +1,7 @@ import crypto from 'node:crypto'; import ByteStream from '@/byte-stream'; import PRUDPPacket from '@/nex/prudp-packet'; +import type { SerializedPRUDPV1Packet } from '@/types/nex/serialized-packet'; export default class PRUDPPacketV1 extends PRUDPPacket { public readonly version = 1; @@ -162,10 +163,10 @@ export default class PRUDPPacketV1 extends PRUDPPacket { return mac.digest(); } - public toJSON(): Record { - const serialized = this.serialize(); + public toJSON(): SerializedPRUDPV1Packet { + const serialized = this.serialize() as SerializedPRUDPV1Packet; - serialized.substream_id = this.substreamID; + serialized.substream_id = this.substreamID!; if (this.supportedFunctions) { serialized.supported_functions = this.supportedFunctions; diff --git a/src/nex/raw-rmc-packet.ts b/src/nex/raw-rmc-packet.ts index d89a395..b0c4aa2 100644 --- a/src/nex/raw-rmc-packet.ts +++ b/src/nex/raw-rmc-packet.ts @@ -1,5 +1,6 @@ import ByteStream from '@/byte-stream'; import PRUDPPacket from '@/nex/prudp-packet'; +import type SerializedPacket from '@/types/nex/serialized-packet'; export default class RawRMCPacket extends PRUDPPacket { public readonly version = -1; @@ -46,7 +47,7 @@ export default class RawRMCPacket extends PRUDPPacket { this.destinationStreamID = -1; } - public toJSON(): Record { + public toJSON(): SerializedPacket { return this.serialize(); } } \ No newline at end of file diff --git a/src/nex/rmc-message.ts b/src/nex/rmc-message.ts index 097e7b6..4f8d792 100644 --- a/src/nex/rmc-message.ts +++ b/src/nex/rmc-message.ts @@ -1,6 +1,7 @@ import ByteStream from '@/byte-stream'; import QResult from '@/nex/types/qresult'; import type Connection from '@/nex/connection'; +import type SerializedRMCMessage from '@/types/nex/serialized-rmc-message'; export default class RMCMessage { static readonly REQUEST = 0; @@ -102,8 +103,8 @@ export default class RMCMessage { } } - public toJSON(): Record { - const serialized: Record = { + public toJSON(): SerializedRMCMessage { + const serialized: SerializedRMCMessage = { type: this._type, protocol_id: this._protocolID, protocol_name: this.protocolName, diff --git a/src/types/nex/serialized-packet.ts b/src/types/nex/serialized-packet.ts index 72e7d5e..f3a5288 100644 --- a/src/types/nex/serialized-packet.ts +++ b/src/types/nex/serialized-packet.ts @@ -1,6 +1,6 @@ import type SerializedRMCMessage from '@/types/nex/serialized-rmc-message'; -type SerializedPRUDPPacket = { +export type SerializedPRUDPPacket = { version: number; source_address: string; source_port: number; @@ -23,12 +23,12 @@ type SerializedPRUDPPacket = { message?: SerializedRMCMessage; }; -type SerializedPRUDPV0Packet = SerializedPRUDPPacket & { +export type SerializedPRUDPV0Packet = SerializedPRUDPPacket & { version: 0; checksum: number; }; -type SerializedPRUDPV1Packet = SerializedPRUDPPacket & { +export type SerializedPRUDPV1Packet = SerializedPRUDPPacket & { version: 1; substream_id: number; supported_functions?: Buffer; From 6f6ca4a51f7cc270e2911c2fc4a09a82bca3bf79 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 9 Jun 2024 12:49:48 -0400 Subject: [PATCH 15/67] fix(nex): fix PCAPNGParser import in session.ts --- src/nex/session.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nex/session.ts b/src/nex/session.ts index a18319a..81bc3d8 100644 --- a/src/nex/session.ts +++ b/src/nex/session.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import fs from 'fs-extra'; import ByteStream from '@/byte-stream'; import PCAPParser from '@/pcap-parser'; -import PCAPNGParser from '@/pcap-parser'; +import PCAPNGParser from '@/pcapng-parser'; import Connection from '@/nex/connection'; import PRUDPPacketV1 from '@/nex/prudp-packetv1'; import PRUDPPacketV0 from '@/nex/prudp-packetv0'; From ccfebcf35d32abd26972653a364a0e0833013ee7 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 9 Jun 2024 14:46:20 -0400 Subject: [PATCH 16/67] refactor: add global settings --- src/settings.ts | 35 +++++++++++++++++++++++++++++++++++ src/types/frame.ts | 4 ++-- src/types/settings.ts | 12 ++++++++++++ src/types/state.ts | 6 +++--- 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 src/settings.ts create mode 100644 src/types/settings.ts diff --git a/src/settings.ts b/src/settings.ts new file mode 100644 index 0000000..3209a29 --- /dev/null +++ b/src/settings.ts @@ -0,0 +1,35 @@ +import path from 'node:path'; +import { app } from 'electron'; +import fs from 'fs-extra'; + +const appUserDataPath = app.getPath('userData'); +const settingsRootPath = path.join(appUserDataPath, 'settings.json'); + +console.log(settingsRootPath); + +let settings = { + recent_files: [], + accounts: [] +}; + +if (fs.existsSync(settingsRootPath)) { + settings = fs.readJSONSync(settingsRootPath); +} else { + saveSettings(); +} + +if (!settings.recent_files) { + settings.recent_files = []; +} + +if (!settings.accounts) { + settings.accounts = []; +} + +export function saveSettings(): void { + fs.writeJSONSync(settingsRootPath, settings, { + spaces: '\t' + }); +} + +export default settings; \ No newline at end of file diff --git a/src/types/frame.ts b/src/types/frame.ts index fd6ca1f..3038ca6 100644 --- a/src/types/frame.ts +++ b/src/types/frame.ts @@ -1,4 +1,4 @@ -import type { EnhancedPacketBlock } from '@/types/pcapng-parser'; +import type { EnhancedPacketBlock, SimplePacketBlock } from '@/types/pcapng-parser'; type SimpleFrame = { timestamp: { @@ -10,6 +10,6 @@ type SimpleFrame = { data: Buffer; }; -type Frame = SimpleFrame | EnhancedPacketBlock; +type Frame = EnhancedPacketBlock | SimplePacketBlock | SimpleFrame; export default Frame; \ No newline at end of file diff --git a/src/types/settings.ts b/src/types/settings.ts new file mode 100644 index 0000000..604b665 --- /dev/null +++ b/src/types/settings.ts @@ -0,0 +1,12 @@ +export type Account = { + username?: string; + pid: number; + password?: string; + password_hash_old?: string; + password_hash_new?: string; +} + +export type Settings = { + recent_files: string[]; + accounts: Account[]; +} \ No newline at end of file diff --git a/src/types/state.ts b/src/types/state.ts index 5b9e793..28cf96e 100644 --- a/src/types/state.ts +++ b/src/types/state.ts @@ -1,8 +1,8 @@ +import type { Settings } from '@/types/settings'; + type State = { raw_rmc: boolean; - settings: { - recent_files: string[]; - }; + settings: Settings; }; export default State; \ No newline at end of file From 70ae4bc61144fc06e81aff3a301aa56fdfeb4096 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 9 Jun 2024 15:19:57 -0400 Subject: [PATCH 17/67] chore: remove console log in settings.ts --- src/settings.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/settings.ts b/src/settings.ts index 3209a29..2ae0de5 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -5,8 +5,6 @@ import fs from 'fs-extra'; const appUserDataPath = app.getPath('userData'); const settingsRootPath = path.join(appUserDataPath, 'settings.json'); -console.log(settingsRootPath); - let settings = { recent_files: [], accounts: [] From 65ddd7e49858cd9d6cba932be5d88e997e3df8d4 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 9 Jun 2024 15:41:46 -0400 Subject: [PATCH 18/67] chore: update settings types --- src/settings.ts | 3 ++- src/types/settings.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/settings.ts b/src/settings.ts index 2ae0de5..b90fdbb 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,11 +1,12 @@ import path from 'node:path'; import { app } from 'electron'; import fs from 'fs-extra'; +import type { Settings } from '@/types/settings'; const appUserDataPath = app.getPath('userData'); const settingsRootPath = path.join(appUserDataPath, 'settings.json'); -let settings = { +let settings: Settings = { recent_files: [], accounts: [] }; diff --git a/src/types/settings.ts b/src/types/settings.ts index 604b665..9c6b27d 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -1,6 +1,6 @@ export type Account = { username?: string; - pid: number; + pid: bigint; password?: string; password_hash_old?: string; password_hash_new?: string; From a68f1bbf51d8bd1906bd547c81b0c8d7de9d301e Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 9 Jun 2024 16:01:33 -0400 Subject: [PATCH 19/67] refactor(nex): use new account settings to lookup NEX accounts --- src/nex/connection.ts | 87 ++++++++++++------------------------------- 1 file changed, 23 insertions(+), 64 deletions(-) diff --git a/src/nex/connection.ts b/src/nex/connection.ts index 48fac60..1705980 100644 --- a/src/nex/connection.ts +++ b/src/nex/connection.ts @@ -1,5 +1,4 @@ -import os from 'node:os'; -import fs from 'fs-extra'; +import settings, { saveSettings } from '@/settings'; import Substream from '@/nex/substream'; import RMCMessage from '@/nex/rmc-message'; import { keyDerivationOld, keyDerivationNew, Ticket } from '@/nex/kerberos'; @@ -12,62 +11,6 @@ import type StationURL from '@/nex/types/station-url'; // TODO - Maybe this should be broken out into .ts files for each game? That way a game can define it's own signature calculation functions and such? import titles from '@/nex/titles.json'; -// TODO - TypeScript does not allow bigint (the type of PIDs here) to be used as an index type. Update this when TypeScript allows this -const GAME_SERVER_PASSWORDS: Record = {}; - -export function populateGameServerPasswords(): void { - const paths: string[] = []; - const home = os.homedir(); - - // TODO - Support more paths? Old viewer supported more local paths, was this useful? - if (process.platform === 'win32') { - fs.ensureDirSync(`${process.env.APPDATA}/NEXViewer`); - - paths.push(`${process.env.APPDATA}/NEXViewer/game-server-passwords.txt`); - } else { - fs.ensureDirSync(`${home}/.config/nex-viewer`); - - paths.push(`${home}/.config/nex-viewer/game-server-passwords.txt`); - } - - for (const path of paths) { - if (fs.existsSync(path)) { - const credentials = fs.readFileSync(path, { - encoding: 'utf8' - }).split('\n').filter(line => line).map(line => { - const parts = line.split(':'); - const pid = parts.shift(); - const password = parts.join(':'); // * Passwords may contain ":". Need to rejoin just in case - - return { - pid, - password - }; - }); - - for (const credential of credentials) { - const pid = Number(credential.pid); - - GAME_SERVER_PASSWORDS[pid] = credential.password; - } - } - } - - if (Object.keys(GAME_SERVER_PASSWORDS).length === 0) { - // TODO - Better explain the file format? - let error = `Failed to load game server passwords. Populate "${home}/.config/nex-viewer/game-server-passwords.txt"`; - - if (process.platform === 'win32') { - error = `Failed to load game server passwords. Populate "${process.env.APPDATA}/NEXViewer/game-server-passwords.txt"`; - } - - throw new Error(error); - } -} - -// TODO - This should be moved to the main window process, so that the error thrown can be shown as a popup -populateGameServerPasswords(); - // * Represents an individual connection to a specific game server export default class Connection { public clientAddress: string; @@ -320,18 +263,34 @@ export default class Connection { let key = Buffer.from(sourceKey, 'hex'); if (key.length === 0) { - // TODO - Remove "as any" when TypeScript updates to allow bigint as an index type - const sourcePassword = GAME_SERVER_PASSWORDS[sourcePID as any]; + const account = settings.accounts.find(({ pid }) => BigInt(pid) === sourcePID); - if (!sourcePassword) { - throw new Error(`No password set for PID ${sourcePID}`); + if (!account) { + console.log(settings.accounts); + throw new Error(`No account found for PID ${sourcePID}`); } if (this.title.settings.kerberos_key_version === 0) { - key = keyDerivationOld(sourcePID, sourcePassword); + if (account.password_hash_old) { + key = Buffer.from(account.password_hash_old, 'hex'); + } else if (account.password) { + key = keyDerivationOld(sourcePID, account.password); + account.password_hash_old = key.toString('hex').toUpperCase(); + } else { + throw new Error(`Title ${this.title.name} uses old Kerberos key derivation and no password is set for PID ${sourcePID}`); + } } else { - key = keyDerivationNew(sourcePID, sourcePassword); + if (account.password_hash_new) { + key = Buffer.from(account.password_hash_new, 'hex'); + } else if (account.password) { + key = keyDerivationNew(sourcePID, account.password); + account.password_hash_new = key.toString('hex').toUpperCase(); + } else { + throw new Error(`Title ${this.title.name} uses new Kerberos key derivation and no password is set for PID ${sourcePID}`); + } } + + saveSettings(); } const ticket = new Ticket(ticketData, key, this.title.settings); From 686d9d1b6bf575aeda261e877fe90ca4812be1c7 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 9 Jun 2024 16:02:06 -0400 Subject: [PATCH 20/67] chore(nex): remove debug print in connection.ts --- src/nex/connection.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/nex/connection.ts b/src/nex/connection.ts index 1705980..f2c4f92 100644 --- a/src/nex/connection.ts +++ b/src/nex/connection.ts @@ -266,7 +266,6 @@ export default class Connection { const account = settings.accounts.find(({ pid }) => BigInt(pid) === sourcePID); if (!account) { - console.log(settings.accounts); throw new Error(`No account found for PID ${sourcePID}`); } From af544f793e28840e603c3d21ccee46b10dcc0ef4 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 9 Jun 2024 16:29:36 -0400 Subject: [PATCH 21/67] fix(nex): QResult codes are uint32 not int32 --- src/nex/types/qresult.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nex/types/qresult.ts b/src/nex/types/qresult.ts index 9236eec..6fce463 100644 --- a/src/nex/types/qresult.ts +++ b/src/nex/types/qresult.ts @@ -301,7 +301,7 @@ export default class QResult { public code: number; public extractFrom(stream: ByteStream): void { - this.code = stream.readInt32LE(); + this.code = stream.readUInt32LE(); } public isSuccess(): boolean { From 8ecbbb14d1f3e29665bcc808e6bc77fda4c61baa Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 9 Jun 2024 16:31:26 -0400 Subject: [PATCH 22/67] fix(nex): fix how error responses find their request messages --- src/nex/connection.ts | 43 +++++++++++++++++++++++------------------- src/nex/rmc-message.ts | 12 ++++-------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/nex/connection.ts b/src/nex/connection.ts index f2c4f92..3b3be38 100644 --- a/src/nex/connection.ts +++ b/src/nex/connection.ts @@ -187,6 +187,30 @@ export default class Connection { packet.message = new RMCMessage(packet.defragmentedPayload!); packet.message.connection = this; + if (packet.message.error) { + const substreamID = packet.substreamID || 0; + const requestPacket = this.packets.find(p => { + if ( + p.substreamID === substreamID && + p.message?.type === RMCMessage.REQUEST && + p.message?.protocolID === packet.message?.protocolID && + p.message?.callID === packet.message?.callID + ) { + return true; + } + }); + + if (requestPacket && requestPacket.message) { + packet.message.methodID = requestPacket.message.methodID; + + if (requestPacket.message.methodName) { + packet.message.methodName = requestPacket.message.methodName; + } else { + packet.message.methodName = 'UnknownMethod'; + } + } + } + const protocol = getProtocol(packet.message); if (protocol) { @@ -194,25 +218,6 @@ export default class Connection { if (!packet.message.error) { protocol.handlePacket(packet); - } else { - const substreamID = packet.substreamID || 0; - const substream = packet.fromClientToServer ? this.clientSubstream(substreamID) : this.serverSubstream(substreamID); - const seenPackets = packet.fromClientToServer ? substream.servertoClientSeenPackets : substream.clientToServerSeenPackets; // * Search packets from the other end - const requestPacket = seenPackets.find(p => { - if ( - p.message?.type === RMCMessage.REQUEST && - p.message?.protocolID === packet.message?.protocolID && - p.message?.callID === packet.message?.callID - ) { - return true; - } - }); - - if (requestPacket && requestPacket.message?.methodName) { - packet.message.methodName = requestPacket.message.methodName; - } else { - packet.message.methodName = 'UnknownMethod'; - } } } else { const protocolID = packet.message.extendedProtocolID ? packet.message.extendedProtocolID : packet.message.protocolID; diff --git a/src/nex/rmc-message.ts b/src/nex/rmc-message.ts index 4f8d792..4d98bd0 100644 --- a/src/nex/rmc-message.ts +++ b/src/nex/rmc-message.ts @@ -10,13 +10,13 @@ export default class RMCMessage { private _type: 0 | 1; private _protocolID: number; private _extendedProtocolID?: number; - private _methodID: number; private _callID: number; private _error?: QResult; private _parametersData?: Buffer; public parameters?: any; public methodName: string; + public methodID: number; public protocolName: string; public connection: Connection; @@ -32,10 +32,6 @@ export default class RMCMessage { return this._extendedProtocolID; } - get methodID(): number { - return this._methodID; - } - get callID(): number { return this._callID; } @@ -85,7 +81,7 @@ export default class RMCMessage { private parseRequest(stream: ByteStream): void { this._callID = stream.readUInt32LE(); - this._methodID = stream.readUInt32LE(); + this.methodID = stream.readUInt32LE(); this._parametersData = stream.readRest(); } @@ -94,7 +90,7 @@ export default class RMCMessage { if (success) { this._callID = stream.readUInt32LE(); - this._methodID = stream.readUInt32LE() & ~0x8000; + this.methodID = stream.readUInt32LE() & ~0x8000; this._parametersData = stream.readRest(); } else { this._error = new QResult(); @@ -108,7 +104,7 @@ export default class RMCMessage { type: this._type, protocol_id: this._protocolID, protocol_name: this.protocolName, - method_id: this._methodID, + method_id: this.methodID, method_name: this.methodName, call_id: this._callID }; From 298bf85f0473bd8becb82974cd6c7a99b1371086 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 9 Jun 2024 16:51:18 -0400 Subject: [PATCH 23/67] chore(nex): add serialized Connection data --- src/nex/connection.ts | 24 ++++++++---------------- src/types/nex/serialized-connection.ts | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 src/types/nex/serialized-connection.ts diff --git a/src/nex/connection.ts b/src/nex/connection.ts index 3b3be38..ebf8099 100644 --- a/src/nex/connection.ts +++ b/src/nex/connection.ts @@ -5,8 +5,8 @@ import { keyDerivationOld, keyDerivationNew, Ticket } from '@/nex/kerberos'; import getProtocol from '@/nex/protocols/manager'; import TicketGrantingProtocol from '@/nex/protocols/ticket-granting'; import type Packet from '@/types/nex/packet'; -import type NEXByteStreamSettings from '@/types/nex/byte-stream-settings'; import type StationURL from '@/nex/types/station-url'; +import type { SerializedConnection, Title } from '@/types/nex/serialized-connection'; // TODO - Maybe this should be broken out into .ts files for each game? That way a game can define it's own signature calculation functions and such? import titles from '@/nex/titles.json'; @@ -24,21 +24,7 @@ export default class Connection { public serverStreamID: number; public packets: Packet[] = []; // * Stores all packets in the connection regardless of substream, reliability, etc. Used to display all packets in order as they are sent - public title: { - name: string; - game_server_id: string; - access_key: string; - library_versions: { - main: string; - ranking: string; - datastore: string; - match_making: string; - messaging: string; - utility: string; - }; - settings: NEXByteStreamSettings; - title_ids: string[]; - }; + public title: Title; public mainSecureStationTicket: Ticket; public specialSecureStationTicket: Ticket; // TODO - Currently unused. Also is this even accurate? @@ -311,4 +297,10 @@ export default class Connection { this.specialSecureStationTicket = ticket; } } + + toJSON(): SerializedConnection { + return { + title: this.title + }; + } } \ No newline at end of file diff --git a/src/types/nex/serialized-connection.ts b/src/types/nex/serialized-connection.ts new file mode 100644 index 0000000..052365a --- /dev/null +++ b/src/types/nex/serialized-connection.ts @@ -0,0 +1,23 @@ +import type NEXByteStreamSettings from '@/types/nex/byte-stream-settings'; + +export type Title = { + name: string; + game_server_id: string; + access_key: string; + library_versions: { + main: string; + ranking: string; + datastore: string; + match_making: string; + messaging: string; + utility: string; + }; + settings: NEXByteStreamSettings; + title_ids: string[]; +}; + +export type SerializedConnection = { + title: Title +}; + +export default SerializedConnection; \ No newline at end of file From 4e70ae262b0c12d2db70ecb434a19ef431f795cb Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 9 Jun 2024 17:27:13 -0400 Subject: [PATCH 24/67] fix: fix "seconds" type in PCAPNG parser --- src/pcapng-parser.ts | 2 +- src/types/pcapng-parser.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pcapng-parser.ts b/src/pcapng-parser.ts index 771b234..850fa74 100644 --- a/src/pcapng-parser.ts +++ b/src/pcapng-parser.ts @@ -205,7 +205,7 @@ export default class PCAPNGParser { timestamp: { high: timestampHigh, low: timestampLow, - sectonds: timestampSeconds + seconds: timestampSeconds }, storedLength, realLength, diff --git a/src/types/pcapng-parser.ts b/src/types/pcapng-parser.ts index ba02d00..335bbaa 100644 --- a/src/types/pcapng-parser.ts +++ b/src/types/pcapng-parser.ts @@ -20,7 +20,7 @@ export type EnhancedPacketBlock = { timestamp: { high: number; low: number; - sectonds: number; + seconds: number; }, storedLength: number; realLength: number; From 225876cd8bd7c4236faaae452c06e21874a937b6 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 16 Jun 2024 18:43:31 -0400 Subject: [PATCH 25/67] feat: add "time" value to packets --- src/nex/prudp-packet.ts | 2 ++ src/nex/session.ts | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/nex/prudp-packet.ts b/src/nex/prudp-packet.ts index 04ce1f4..d13b49d 100644 --- a/src/nex/prudp-packet.ts +++ b/src/nex/prudp-packet.ts @@ -4,6 +4,7 @@ import Connection from '@/nex/connection'; import type { SerializedPRUDPPacket } from '@/types/nex/serialized-packet'; export default class PRUDPPacket { + public time?: number; public readonly version: number; public fromClientToServer: boolean; @@ -149,6 +150,7 @@ export default class PRUDPPacket { public serialize(): SerializedPRUDPPacket { const serialized: SerializedPRUDPPacket = { + time: this.time, version: this.version, source_address: this.sourceAddress, source_port: this.sourcePort, diff --git a/src/nex/session.ts b/src/nex/session.ts index 81bc3d8..1ffe24d 100644 --- a/src/nex/session.ts +++ b/src/nex/session.ts @@ -20,6 +20,8 @@ function int2ip(int: number): string { export default class Session extends EventEmitter { private connections: Connection[] = []; private rawRMCMode = false; + private lastPacketTime = 0; + private elapsedTime = 0; constructor() { super(); @@ -46,13 +48,23 @@ export default class Session extends EventEmitter { } for (const packet of parser.packets()) { - this.handlePacket(packet); + let time = 0; + if ('timestamp' in packet) { + if (this.lastPacketTime !== 0) { + this.elapsedTime += packet.timestamp.seconds - this.lastPacketTime; + time = this.elapsedTime; + } + + this.lastPacketTime = packet.timestamp.seconds; + } + + this.handlePacket(packet, time); } this.emit('finished', this.connections); } - private handlePacket(frame: Frame): void { + private handlePacket(frame: Frame, time?: number): void { // * HokakuCTR produces dumps whose payloads are: // * - u8 Revision (1) // * - u64 Title ID @@ -69,6 +81,11 @@ export default class Session extends EventEmitter { for (const packet of packets) { this.processPacket(packet); + + if (!this.rawRMCMode) { + packet.time = time; + } + this.emit('packet', packet); } } From 2655d0f1132b586596e97e114837db3b64a2afce Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 16 Jun 2024 18:59:22 -0400 Subject: [PATCH 26/67] fix(nex): filter DNS packets by port --- src/nex/session.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nex/session.ts b/src/nex/session.ts index 1ffe24d..2ae00de 100644 --- a/src/nex/session.ts +++ b/src/nex/session.ts @@ -184,6 +184,11 @@ export default class Session extends EventEmitter { const destinationPort = udpStream.readUInt16BE(); const udpPacketLength = udpStream.readUInt16BE(); + if (sourcePort === 53 || destinationPort === 53) { + // * DNS packet + return; + } + if (udpPacketLength !== udpLength) { throw new Error(`Got bad UDP packet length. Expected ${udpLength}, got ${udpPacketLength}`); } From f8bc3230636208c1fcdd558dfa51dfc09c48b691 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 16 Jun 2024 19:56:50 -0400 Subject: [PATCH 27/67] fix(types): add "time" value to SerializedPRUDPPacket --- src/types/nex/serialized-packet.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/nex/serialized-packet.ts b/src/types/nex/serialized-packet.ts index f3a5288..a7ea3ab 100644 --- a/src/types/nex/serialized-packet.ts +++ b/src/types/nex/serialized-packet.ts @@ -1,6 +1,7 @@ import type SerializedRMCMessage from '@/types/nex/serialized-rmc-message'; export type SerializedPRUDPPacket = { + time?: number; version: number; source_address: string; source_port: number; From 98d80b2afb2f7393b9a5ca4f702f1b756cdfd943 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Sun, 16 Jun 2024 20:22:17 -0400 Subject: [PATCH 28/67] feat(nex): add stack traces to serialized packets --- src/nex/connection.ts | 157 +++++++++++++++-------------- src/nex/prudp-packet.ts | 5 + src/types/nex/serialized-packet.ts | 1 + 3 files changed, 87 insertions(+), 76 deletions(-) diff --git a/src/nex/connection.ts b/src/nex/connection.ts index ebf8099..7f42afe 100644 --- a/src/nex/connection.ts +++ b/src/nex/connection.ts @@ -74,99 +74,104 @@ export default class Connection { } public processPacket(packet: Packet): void { - if (packet.isTypeSyn() && packet.fromClientToServer && this.mainSecureStationTicket) { - this.reset(); // * Assume a new connection has started - } - - if (packet.isTypeSyn() && packet.fromServerToClient && packet.connectionSignature) { - this.serverConnectionSignature = packet.connectionSignature; - } - - if (packet.isTypeConnect() && packet.fromClientToServer && packet.connectionSignature) { - this.clientConnectionSignature = packet.connectionSignature; - } - - if (packet.version !== -1 && packet.hasFlagAck() || packet.hasFlagMultiAck()) { - // TODO - Actually handle these? - this.packets.push(packet); - return; - } + try { + if (packet.isTypeSyn() && packet.fromClientToServer && this.mainSecureStationTicket) { + this.reset(); // * Assume a new connection has started + } - if (packet.version !== -1 && packet.isTypeData() && !packet.hasFlagReliable()) { - // * Packet is an unreliable DATA packet. - // * These packets use their own RC4 stream - // * and are not yet supported. + if (packet.isTypeSyn() && packet.fromServerToClient && packet.connectionSignature) { + this.serverConnectionSignature = packet.connectionSignature; + } - this.packets.push(packet); - return; - } + if (packet.isTypeConnect() && packet.fromClientToServer && packet.connectionSignature) { + this.clientConnectionSignature = packet.connectionSignature; + } - if (packet.isTypePing()) { - // * Don't worry about handling PING packets + if (packet.version !== -1 && packet.hasFlagAck() || packet.hasFlagMultiAck()) { + // TODO - Actually handle these? + return; + } - this.packets.push(packet); - return; - } + if (packet.version !== -1 && packet.isTypeData() && !packet.hasFlagReliable()) { + // * Packet is an unreliable DATA packet. + // * These packets use their own RC4 stream + // * and are not yet supported. + return; + } - if (!this.title) { - for (const title of titles) { - if (packet.version === -1) { - if (title.title_ids.includes(packet.titleID)) { - this.title = title; - break; - } - } else if (packet.version === 0) { - const expectedChecksum = packet.checksum; - const calculatedChecksum = packet.calculateChecksum(title.access_key); + if (packet.isTypePing()) { + // * Don't worry about handling PING packets + return; + } - if (expectedChecksum === calculatedChecksum) { - this.title = title; - break; - } - } else { - // TODO - Legacy connection signature - const connectionSignature = packet.fromClientToServer ? this.clientConnectionSignature : this.serverConnectionSignature; - const expectedSignature = packet.signature; - const calculatedSignature = packet.calculateSignature(title.access_key, this.sessionKey, connectionSignature); - - if (expectedSignature.equals(calculatedSignature)) { - this.title = title; - break; + if (!this.title) { + for (const title of titles) { + if (packet.version === -1) { + if (title.title_ids.includes(packet.titleID)) { + this.title = title; + break; + } + } else if (packet.version === 0) { + const expectedChecksum = packet.checksum; + const calculatedChecksum = packet.calculateChecksum(title.access_key); + + if (expectedChecksum === calculatedChecksum) { + this.title = title; + break; + } + } else { + // TODO - Legacy connection signature + const connectionSignature = packet.fromClientToServer ? this.clientConnectionSignature : this.serverConnectionSignature; + const expectedSignature = packet.signature; + const calculatedSignature = packet.calculateSignature(title.access_key, this.sessionKey, connectionSignature); + + if (expectedSignature.equals(calculatedSignature)) { + this.title = title; + break; + } } } } - } - let packets: Packet[]; - const substreamID = packet.substreamID || 0; + let packets: Packet[]; + const substreamID = packet.substreamID || 0; - if (packet.version !== -1) { - const substream = packet.fromClientToServer ? this.clientSubstream(substreamID) : this.serverSubstream(substreamID); - packets = substream.update(packet); - } else { - packets = [packet]; - } + if (packet.version !== -1) { + const substream = packet.fromClientToServer ? this.clientSubstream(substreamID) : this.serverSubstream(substreamID); + packets = substream.update(packet); + } else { + packets = [packet]; + } - for (const packet of packets) { - if (packet.isTypeData()) { - // TODO - This whole section needs to be reworked to support different encryption and compression settings. Currently assumes RC4 and no compression - let defragmentedPayload: Buffer | null = null; + for (const packet of packets) { + if (packet.isTypeData()) { + // TODO - This whole section needs to be reworked to support different encryption and compression settings. Currently assumes RC4 and no compression + let defragmentedPayload: Buffer | null = null; - if (packet.version !== -1) { - const substream = this.clientSubstream(substreamID); - defragmentedPayload = substream.addFragment(packet); - } else if (packet.payload) { - defragmentedPayload = packet.payload; - } + if (packet.version !== -1) { + const substream = this.clientSubstream(substreamID); + defragmentedPayload = substream.addFragment(packet); + } else if (packet.payload) { + defragmentedPayload = packet.payload; + } - if (packet.fragmentID === 0 && defragmentedPayload) { - packet.defragmentedPayload = defragmentedPayload; - this.processPacketMessage(packet); + if (packet.fragmentID === 0 && defragmentedPayload) { + packet.defragmentedPayload = defragmentedPayload; + this.processPacketMessage(packet); + } } } + } catch (error) { + if (typeof error === 'string') { + packet.stackTrace = error; + } else if (error instanceof Error) { + packet.stackTrace = error.message; + } else { + packet.stackTrace = `Unknown error type: ${error}`; + } + } finally { + this.packets.push(packet); } - - this.packets.push(packet); } private processPacketMessage(packet: Packet): void { diff --git a/src/nex/prudp-packet.ts b/src/nex/prudp-packet.ts index d13b49d..e3e66ab 100644 --- a/src/nex/prudp-packet.ts +++ b/src/nex/prudp-packet.ts @@ -32,6 +32,7 @@ export default class PRUDPPacket { public defragmentedPayload?: Buffer; public connection: Connection; public message?: RMCMessage; + public stackTrace?: string; protected stream: ByteStream; @@ -191,6 +192,10 @@ export default class PRUDPPacket { } } + if (this.stackTrace) { + serialized.stack_trace = this.stackTrace; + } + return serialized; } diff --git a/src/types/nex/serialized-packet.ts b/src/types/nex/serialized-packet.ts index a7ea3ab..235ecd5 100644 --- a/src/types/nex/serialized-packet.ts +++ b/src/types/nex/serialized-packet.ts @@ -22,6 +22,7 @@ export type SerializedPRUDPPacket = { decrypted_payload?: Buffer; defragmented_payload?: Buffer; message?: SerializedRMCMessage; + stack_trace?: string; }; export type SerializedPRUDPV0Packet = SerializedPRUDPPacket & { From a4574fa90e14a952efdebd28b1781d3c48847eff Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 17 Jun 2024 13:04:11 -0400 Subject: [PATCH 29/67] refactor(nex): pass Buffer data as array values --- src/nex/prudp-packet.ts | 12 ++++++------ src/nex/prudp-packetv1.ts | 2 +- src/nex/types/buffer.ts | 2 +- src/nex/types/qbuffer.ts | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nex/prudp-packet.ts b/src/nex/prudp-packet.ts index e3e66ab..a7dffa9 100644 --- a/src/nex/prudp-packet.ts +++ b/src/nex/prudp-packet.ts @@ -164,27 +164,27 @@ export default class PRUDPPacket { type: this.serializeType(), flags: this.serializeFlags(), session_id: this.sessionID, - signature: this.signature, + signature: [...this.signature.values()], sequence_id: this.sequenceID }; if (this.connectionSignature) { - serialized.connection_signature = this.connectionSignature; + serialized.connection_signature = [...this.connectionSignature.values()]; } if (this.payload) { - serialized.payload = this.payload; + serialized.payload = [...this.payload.values()]; } if (this.decryptedPayload) { - serialized.decrypted_payload = this.decryptedPayload; + serialized.decrypted_payload = [...this.decryptedPayload.values()]; } if (this.isTypeData()) { serialized.fragment_id = this.fragmentID; - if (this.fragmentID === 0) { - serialized.defragmented_payload = this.defragmentedPayload; + if (this.fragmentID === 0 && this.defragmentedPayload) { + serialized.defragmented_payload = [...this.defragmentedPayload.values()]; } if (this.message) { diff --git a/src/nex/prudp-packetv1.ts b/src/nex/prudp-packetv1.ts index e28ec22..733768c 100644 --- a/src/nex/prudp-packetv1.ts +++ b/src/nex/prudp-packetv1.ts @@ -169,7 +169,7 @@ export default class PRUDPPacketV1 extends PRUDPPacket { serialized.substream_id = this.substreamID!; if (this.supportedFunctions) { - serialized.supported_functions = this.supportedFunctions; + serialized.supported_functions = [...this.supportedFunctions.values()]; } if (this.initialUnreliableSequenceID) { diff --git a/src/nex/types/buffer.ts b/src/nex/types/buffer.ts index 5cfdb47..fc60a31 100644 --- a/src/nex/types/buffer.ts +++ b/src/nex/types/buffer.ts @@ -20,7 +20,7 @@ export default class RVBuffer { return { __displayTypeName: this.typeName, __typeName: this.typeName, - __value: this.value + __value: [...this.value.values()] }; } } \ No newline at end of file diff --git a/src/nex/types/qbuffer.ts b/src/nex/types/qbuffer.ts index ef49d26..09d14b5 100644 --- a/src/nex/types/qbuffer.ts +++ b/src/nex/types/qbuffer.ts @@ -19,7 +19,7 @@ export default class QBuffer { return { __displayTypeName: this.typeName, __typeName: this.typeName, - __value: this.value + __value: [...this.value.values()] }; } } \ No newline at end of file From dfd9d4078119953cfa898117aa47c7ef22979e1f Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 17 Jun 2024 19:03:58 -0400 Subject: [PATCH 30/67] refactor: add window menu and update Settings --- src/nex/connection.ts | 6 +-- src/settings.ts | 93 ++++++++++++++++++++++++++++--------- src/types/settings.ts | 2 +- src/types/state.ts | 2 +- src/windows/main/index.ts | 39 ++++++---------- src/windows/main/menu.ts | 90 +++++++++++++++++++++++++++++++++-- src/windows/main/preload.ts | 8 ++++ 7 files changed, 184 insertions(+), 56 deletions(-) create mode 100644 src/windows/main/preload.ts diff --git a/src/nex/connection.ts b/src/nex/connection.ts index 7f42afe..6950d9f 100644 --- a/src/nex/connection.ts +++ b/src/nex/connection.ts @@ -1,4 +1,4 @@ -import settings, { saveSettings } from '@/settings'; +import settings from '@/settings'; import Substream from '@/nex/substream'; import RMCMessage from '@/nex/rmc-message'; import { keyDerivationOld, keyDerivationNew, Ticket } from '@/nex/kerberos'; @@ -259,7 +259,7 @@ export default class Connection { let key = Buffer.from(sourceKey, 'hex'); if (key.length === 0) { - const account = settings.accounts.find(({ pid }) => BigInt(pid) === sourcePID); + const account = settings.accounts().find(({ pid }) => BigInt(pid) === sourcePID); if (!account) { throw new Error(`No account found for PID ${sourcePID}`); @@ -285,7 +285,7 @@ export default class Connection { } } - saveSettings(); + settings.save(); } const ticket = new Ticket(ticketData, key, this.title.settings); diff --git a/src/settings.ts b/src/settings.ts index b90fdbb..9d09ff1 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,34 +1,83 @@ import path from 'node:path'; import { app } from 'electron'; import fs from 'fs-extra'; -import type { Settings } from '@/types/settings'; +import type { Account, SettingsJSON } from '@/types/settings'; -const appUserDataPath = app.getPath('userData'); -const settingsRootPath = path.join(appUserDataPath, 'settings.json'); +class SizedArray { + private elements: T[] = []; + private maxSize: number; -let settings: Settings = { - recent_files: [], - accounts: [] -}; + constructor(maxSize: number) { + this.maxSize = maxSize; + } -if (fs.existsSync(settingsRootPath)) { - settings = fs.readJSONSync(settingsRootPath); -} else { - saveSettings(); -} + public fromData(data: T[]): void { + this.elements = [...data]; + } -if (!settings.recent_files) { - settings.recent_files = []; -} + public add(item: T): void { + if (this.elements.length >= this.maxSize) { + this.elements.pop(); + } -if (!settings.accounts) { - settings.accounts = []; + this.elements.unshift(item); + } + + public getItems(): T[] { + return this.elements; + } } -export function saveSettings(): void { - fs.writeJSONSync(settingsRootPath, settings, { - spaces: '\t' - }); +export class Settings { + private path = path.join(app.getPath('userData'), 'settings.json'); + private _recentFiles = new SizedArray(10); + private _accounts: Account[] = []; + + constructor() { + this.load(); + } + + private load(): void { + if (!fs.existsSync(this.path)) { + this.save(); + } + + const settings: SettingsJSON = fs.readJSONSync(this.path); + + this._recentFiles.fromData(settings.recent_files); + this._accounts = settings.accounts; + } + + public save(): void { + const settings = { + recent_files: this.recentFiles(), + accounts: this.accounts() + }; + + fs.writeJSONSync(this.path, settings, { + spaces: '\t' + }); + } + + public recentFiles(): string[] { + return this._recentFiles.getItems(); + } + + public addRecentFile(path: string): string[] { + this._recentFiles.add(path); + this.save(); + + return this._recentFiles.getItems(); + } + + public clearRecentFiles(): void { + this._recentFiles = new SizedArray(10); + this.save(); + } + + public accounts(): Account[] { + return this._accounts; + } } -export default settings; \ No newline at end of file +export default new Settings(); \ No newline at end of file diff --git a/src/types/settings.ts b/src/types/settings.ts index 9c6b27d..67ca09e 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -6,7 +6,7 @@ export type Account = { password_hash_new?: string; } -export type Settings = { +export type SettingsJSON = { recent_files: string[]; accounts: Account[]; } \ No newline at end of file diff --git a/src/types/state.ts b/src/types/state.ts index 28cf96e..755b65d 100644 --- a/src/types/state.ts +++ b/src/types/state.ts @@ -1,4 +1,4 @@ -import type { Settings } from '@/types/settings'; +import type { Settings } from '@/settings'; type State = { raw_rmc: boolean; diff --git a/src/windows/main/index.ts b/src/windows/main/index.ts index 002e910..d34f938 100644 --- a/src/windows/main/index.ts +++ b/src/windows/main/index.ts @@ -1,11 +1,16 @@ // TODO - Should we just merge the "renderers" and "windows" folders? import path from 'node:path'; -import { app, BrowserWindow, ipcMain, Menu } from 'electron'; -import fs from 'fs-extra'; +import sourceMapSupport from 'source-map-support'; +import { app, BrowserWindow, ipcMain } from 'electron'; import createMenu from '@/windows/main/menu'; +import settings from '@/settings'; import type State from '@/types/state'; +// * Required for getting source maps to work in Electron apps +// * See https://github.com/electron/electron/issues/38875 +sourceMapSupport.install(); + global.Object.defineProperty(global.BigInt.prototype, 'toJSON', { value: function() { return this.toString(); }, configurable: true, @@ -15,48 +20,30 @@ global.Object.defineProperty(global.BigInt.prototype, 'toJSON', { app.setName('NEX Viewer'); -const appUserDataPath = app.getPath('userData'); -const settingsRootPath = path.join(appUserDataPath, 'settings.json'); - -if (!fs.existsSync(settingsRootPath)) { - fs.writeFileSync(settingsRootPath, JSON.stringify({ - recent_files: [] - })); -} - +// TODO - Should all of this just be combined into the Settings class and remove State? const state: State = { raw_rmc: false, - settings: fs.readJSONSync(settingsRootPath) + settings: settings }; -for (const recentFile of state.settings.recent_files) { - // TODO - Actually store these - app.addRecentDocument(recentFile); -} - function createWindow(): void { const window = new BrowserWindow({ - width: 800, - height: 600, - webPreferences: { // TODO - Use Electron's contextBridge instead - nodeIntegration: true, - contextIsolation: false + webPreferences: { + preload: path.join(__dirname, 'preload.js') // * Target the transpiled JS } }); window.webContents.openDevTools(); ipcMain.on('renderer-ready', () => { - Menu.setApplicationMenu(createMenu(state)); + window.setMenu(createMenu(state)); }); window.maximize(); - window.loadFile('../../renderers/main/index.html'); + window.loadFile(path.join(__dirname, '../../renderers/main/index.html')); } app.whenReady().then(() => { - Menu.setApplicationMenu(Menu.buildFromTemplate([])); // * Clear menu before frontend loads - createWindow(); app.on('activate', () => { diff --git a/src/windows/main/menu.ts b/src/windows/main/menu.ts index 2c4e9b7..b5f342f 100644 --- a/src/windows/main/menu.ts +++ b/src/windows/main/menu.ts @@ -1,8 +1,92 @@ -import { Menu } from 'electron'; +import { Menu, dialog, BrowserWindow } from 'electron'; +import Session from '@/nex/session'; +import type { MenuItemConstructorOptions } from 'electron'; import type State from '@/types/state'; -export default function createComponentBuilder(_state: State): Menu { +function openSession(path: string, state: State): void { + const browserWindow = BrowserWindow.getFocusedWindow()!; + + browserWindow.webContents.send('clear-sections'); + browserWindow.setTitle(`NEX Viewer - ${path}`); + + const session = new Session(); + + session.on('packet', packet => { + browserWindow.webContents.send('packet', JSON.stringify(packet)); + }); + + session.on('finished', connections => { + browserWindow.webContents.send('connections', JSON.stringify(connections)); + }); + + session.parse(path); + + state.settings.addRecentFile(path); + + browserWindow.setMenu(createMenu(state)); +} + +export default function createMenu(state: State): Menu { + let recentFiles: MenuItemConstructorOptions[] = state.settings.recentFiles().map(path => ({ + label: path, + click: (): void => openSession(path, state) + })); + + if (recentFiles.length) { + recentFiles = [ + ...recentFiles, + { + type: 'separator' + }, + { + label: 'Clear Menu', + click: (): void => state.settings.clearRecentFiles() + } + ]; + } else { + recentFiles = [ + { + label: 'No Recent Files', + enabled: false + } + ]; + } + return Menu.buildFromTemplate([ - // TODO + { + label: 'File', + id: 'file', + submenu: [ + { + label: 'Open...', + async click(menuItem, browserWindow): Promise { + const result = await dialog.showOpenDialog({ + properties: ['openFile'], + filters: [ + { name: 'Packet Capture', extensions: ['pcapng', 'pcap'] } + ] + }); + + if (result.canceled || !browserWindow) { + return; + } + + openSession(result.filePaths[0], state); + } + }, + { + type: 'separator' + + }, + { + label: 'Open Recent', + submenu: recentFiles + }, + { + role: 'quit' + } + ] + } + // TODO - Add back in the PING packet and maybe RawRMC settings? ]); } \ No newline at end of file diff --git a/src/windows/main/preload.ts b/src/windows/main/preload.ts new file mode 100644 index 0000000..07f75a5 --- /dev/null +++ b/src/windows/main/preload.ts @@ -0,0 +1,8 @@ +import { contextBridge, ipcRenderer } from 'electron'; + +contextBridge.exposeInMainWorld('electron', { + ready: () => ipcRenderer.send('renderer-ready'), + onClearSections: (callback: () => void) => ipcRenderer.on('clear-sections', (_event) => callback()), + onPacket: (callback: (packet: any) => void) => ipcRenderer.on('packet', (_event, packet) => callback(JSON.parse(packet))), + onConnections: (callback: (connections: any) => void) => ipcRenderer.on('connections', (_event, connections) => callback(JSON.parse(connections))) +}); \ No newline at end of file From de8f16fcf991bbc5f1c2bc27b0f8d34ea4109521 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 17 Jun 2024 19:04:34 -0400 Subject: [PATCH 31/67] fix(types): update SerializedPacket Buffer types --- src/types/nex/serialized-packet.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/types/nex/serialized-packet.ts b/src/types/nex/serialized-packet.ts index 235ecd5..3121e07 100644 --- a/src/types/nex/serialized-packet.ts +++ b/src/types/nex/serialized-packet.ts @@ -14,13 +14,13 @@ export type SerializedPRUDPPacket = { type: string flags: string[] session_id: number; - signature: Buffer; + signature: number[]; sequence_id: number; - connection_signature?: Buffer; + connection_signature?: number[]; fragment_id?: number; - payload?: Buffer; - decrypted_payload?: Buffer; - defragmented_payload?: Buffer; + payload?: number[]; + decrypted_payload?: number[]; + defragmented_payload?: number[]; message?: SerializedRMCMessage; stack_trace?: string; }; @@ -33,7 +33,7 @@ export type SerializedPRUDPV0Packet = SerializedPRUDPPacket & { export type SerializedPRUDPV1Packet = SerializedPRUDPPacket & { version: 1; substream_id: number; - supported_functions?: Buffer; + supported_functions?: number[]; initial_unreliable_sequence_id?: number; maximum_substream_id?: number; }; From f0b696a4e1266edd38a89e2b5277474a61f7d19d Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 17 Jun 2024 19:14:32 -0400 Subject: [PATCH 32/67] fix: revert Recent Files dialog. Caused issues --- src/windows/main/menu.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/windows/main/menu.ts b/src/windows/main/menu.ts index b5f342f..479a283 100644 --- a/src/windows/main/menu.ts +++ b/src/windows/main/menu.ts @@ -3,9 +3,7 @@ import Session from '@/nex/session'; import type { MenuItemConstructorOptions } from 'electron'; import type State from '@/types/state'; -function openSession(path: string, state: State): void { - const browserWindow = BrowserWindow.getFocusedWindow()!; - +function openSession(path: string, browserWindow: BrowserWindow, state: State): void { browserWindow.webContents.send('clear-sections'); browserWindow.setTitle(`NEX Viewer - ${path}`); @@ -29,7 +27,12 @@ function openSession(path: string, state: State): void { export default function createMenu(state: State): Menu { let recentFiles: MenuItemConstructorOptions[] = state.settings.recentFiles().map(path => ({ label: path, - click: (): void => openSession(path, state) + click: (): void => { + // TODO - Track the current window and pass it to openSession + dialog.showMessageBox({ + message: 'Recent files not yet implemented' + }); + } })); if (recentFiles.length) { @@ -71,7 +74,7 @@ export default function createMenu(state: State): Menu { return; } - openSession(result.filePaths[0], state); + openSession(result.filePaths[0], browserWindow, state); } }, { From f6ad9ae242f82b99784da9405cfd6339acbdb5a2 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 17 Jun 2024 19:14:58 -0400 Subject: [PATCH 33/67] fix(nex): fix raw RMC packet serializing --- src/nex/prudp-packet.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/nex/prudp-packet.ts b/src/nex/prudp-packet.ts index a7dffa9..4c72984 100644 --- a/src/nex/prudp-packet.ts +++ b/src/nex/prudp-packet.ts @@ -164,7 +164,7 @@ export default class PRUDPPacket { type: this.serializeType(), flags: this.serializeFlags(), session_id: this.sessionID, - signature: [...this.signature.values()], + signature: this.signature ? [...this.signature.values()] : [], // * Raw RMC packets have no signature sequence_id: this.sequenceID }; @@ -200,6 +200,11 @@ export default class PRUDPPacket { } private serializeStreamType(streamType: number): string { + // * Raw RMC packets have no VirtualPorts + if (this.version === -1) { + return ''; + } + switch(streamType) { case 1: return 'DO'; @@ -229,6 +234,11 @@ export default class PRUDPPacket { } private serializeType(): string { + // * Raw RMC packets have no VirtualPorts + if (this.version === -1) { + return ''; + } + switch(this.type) { case 0: return 'SYN'; From 26b1eb62ee11ed893194a0bbba6c3da2515801f8 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 17 Jun 2024 19:16:04 -0400 Subject: [PATCH 34/67] feat: add the start of UI --- eslint.config.js | 5 +- package-lock.json | 1295 ++++++++++++++++- package.json | 19 +- .../assets/css/connections-list-section.css | 0 src/renderers/main/assets/css/main.css | 101 ++ .../assets/css/packet-details-section.css | 35 + .../main/assets/css/packets-section.css | 62 + src/renderers/main/assets/js/electron.ts | 26 + src/renderers/main/assets/js/global.d.ts | 13 + src/renderers/main/assets/js/main.tsx | 111 ++ src/renderers/main/assets/js/resize.ts | 65 + src/renderers/main/assets/js/util.ts | 13 + src/renderers/main/index.html | 37 +- tsconfig.json | 2 + 14 files changed, 1748 insertions(+), 36 deletions(-) create mode 100644 src/renderers/main/assets/css/connections-list-section.css create mode 100644 src/renderers/main/assets/css/main.css create mode 100644 src/renderers/main/assets/css/packet-details-section.css create mode 100644 src/renderers/main/assets/css/packets-section.css create mode 100644 src/renderers/main/assets/js/electron.ts create mode 100644 src/renderers/main/assets/js/global.d.ts create mode 100644 src/renderers/main/assets/js/main.tsx create mode 100644 src/renderers/main/assets/js/resize.ts create mode 100644 src/renderers/main/assets/js/util.ts diff --git a/eslint.config.js b/eslint.config.js index 0ba95e2..aa0558e 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -14,7 +14,7 @@ module.exports = [ es6: true, BigInt: true }, - parser: tseslint.parser, + parser: tseslint.parser }, plugins: { '@typescript-eslint': tseslint.plugin @@ -32,7 +32,8 @@ module.exports = [ '@typescript-eslint/no-unused-vars': [ 'error', { - 'argsIgnorePattern': '^_' + 'argsIgnorePattern': '^_', + 'varsIgnorePattern': 'createElement' } ], 'no-extra-semi': 'off', diff --git a/package-lock.json b/package-lock.json index 74821f6..98242c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,29 @@ { - "name": "nex-viewer-rewrite", + "name": "nex-viewer", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "nex-viewer-rewrite", + "name": "nex-viewer", "version": "1.0.0", "license": "AGPL-3.0", "dependencies": { + "@pretendonetwork/yeah": "^1.0.0", "fs-extra": "^11.2.0", - "semver": "^7.6.0" + "semver": "^7.6.0", + "source-map-support": "^0.5.21" }, "devDependencies": { "@eslint/js": "^9.1.1", "@types/fs-extra": "^11.0.4", + "@types/react": "^18.3.3", "@types/semver": "^7.5.8", + "@types/source-map-support": "^0.5.10", "browserify": "^17.0.0", "electron": "^30.0.1", "eslint": "^8.57.0", + "eslint-plugin-react": "^7.34.2", "rimraf": "^5.0.5", "tsc-alias": "^1.8.8", "tsconfig-paths": "^4.2.0", @@ -275,6 +280,11 @@ "node": ">=14" } }, + "node_modules/@pretendonetwork/yeah": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@pretendonetwork/yeah/-/yeah-1.0.0.tgz", + "integrity": "sha512-w1yOVx0we1FaYUPs/v4tPAUg6EF5PJ+pI2mss9IGb1Y2CkpEN2ZwZepZy2/nvMCA8G3SKxWsuOiQwcKdbCoYdg==" + }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -360,6 +370,22 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, "node_modules/@types/responselike": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", @@ -375,6 +401,24 @@ "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, + "node_modules/@types/source-map-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/@types/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-tgVP2H469x9zq34Z0m/fgPewGhg/MLClalNOiPIzQlXrSS2YrKu/xCdSCKnEDwkFha51VKEKB6A9wW26/ZNwzA==", + "dev": true, + "dependencies": { + "source-map": "^0.6.0" + } + }, + "node_modules/@types/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@types/yauzl": { "version": "2.10.3", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", @@ -717,6 +761,42 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -726,6 +806,112 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/asn1.js": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", @@ -845,12 +1031,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1076,8 +1262,7 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/buffer-xor": { "version": "1.0.3", @@ -1377,12 +1562,69 @@ "node": "*" } }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, "node_modules/dash-ast": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", "dev": true }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -1663,6 +1905,66 @@ "node": ">=6" } }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -1684,6 +1986,83 @@ "node": ">= 0.4" } }, + "node_modules/es-iterator-helpers": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz", + "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -1758,6 +2137,76 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-plugin-react": { + "version": "7.34.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.2.tgz", + "integrity": "sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.19", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.hasown": "^1.1.4", + "object.values": "^1.2.0", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -1976,9 +2425,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -2125,6 +2574,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-assigned-identifiers": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", @@ -2165,6 +2641,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/glob": { "version": "10.3.12", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", @@ -2273,7 +2766,6 @@ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, - "optional": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -2361,6 +2853,15 @@ "node": ">= 0.4.0" } }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2601,6 +3102,20 @@ "insert-module-globals": "bin/cmd.js" } }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -2617,6 +3132,49 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2629,6 +3187,22 @@ "node": ">=8" } }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -2659,6 +3233,36 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2668,6 +3272,18 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -2704,6 +3320,30 @@ "node": ">=0.10.0" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2713,6 +3353,21 @@ "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -2722,6 +3377,79 @@ "node": ">=8" } }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-typed-array": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", @@ -2737,6 +3465,46 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -2749,6 +3517,19 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, "node_modules/jackspeak": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", @@ -2767,6 +3548,12 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2852,6 +3639,21 @@ "node": "*" } }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -2911,6 +3713,18 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -3128,6 +3942,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -3137,25 +3960,91 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.hasown": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", + "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -3449,6 +4338,17 @@ "node": ">=0.4.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -3572,6 +4472,12 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, "node_modules/read-only-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", @@ -3623,6 +4529,45 @@ "node": ">=8.10.0" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -3746,6 +4691,30 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -3766,6 +4735,23 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", @@ -3820,6 +4806,21 @@ "node": ">= 0.4" } }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", @@ -3940,6 +4941,23 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sprintf-js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", @@ -4091,6 +5109,81 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4311,6 +5404,79 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -4365,6 +5531,21 @@ "umd": "bin/cli.js" } }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/undeclared-identifiers": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", @@ -4460,6 +5641,72 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/which-typed-array": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", diff --git a/package.json b/package.json index 56318cd..ea1849e 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,18 @@ { - "name": "nex-viewer-rewrite", + "name": "nex-viewer", "version": "1.0.0", "description": "Utility for parsing and viewing NEX connections from packet captures", - "main": "index.js", + "main": "dist/windows/main", "scripts": { "lint": "./node_modules/.bin/eslint ./src", "clean": "rimraf ./dist", + "copy-static": "npm run copy-html && npm run copy-css", "copy-html": "mkdir -p ./dist/renderers/main && cp ./src/renderers/main/index.html ./dist/renderers/main/index.html", + "copy-css": "mkdir -p ./dist/renderers/main/assets/css && cp ./src/renderers/main/assets/css/* ./dist/renderers/main/assets/css/", "build": "npm run lint && npm run clean && npm run compile && npm run browserify", - "compile": "npx tsc && npx tsc-alias && npm run copy-html", - "browserify": "browserify ./dist/renderers/main/assets/js/util.js ./dist/renderers/main/assets/js/renderer.js -o ./dist/renderers/main/assets/js/bundle.js", - "start": "electron dist/windows/main/index.js" + "compile": "npx tsc && npx tsc-alias && npm run copy-static", + "browserify": "browserify ./dist/renderers/main/assets/js/*.js -o ./dist/renderers/main/assets/js/bundle.js", + "start": "electron ." }, "keywords": [], "author": "Pretendo Network", @@ -18,10 +20,13 @@ "devDependencies": { "@eslint/js": "^9.1.1", "@types/fs-extra": "^11.0.4", + "@types/react": "^18.3.3", "@types/semver": "^7.5.8", + "@types/source-map-support": "^0.5.10", "browserify": "^17.0.0", "electron": "^30.0.1", "eslint": "^8.57.0", + "eslint-plugin-react": "^7.34.2", "rimraf": "^5.0.5", "tsc-alias": "^1.8.8", "tsconfig-paths": "^4.2.0", @@ -29,7 +34,9 @@ "typescript-eslint": "^7.7.1" }, "dependencies": { + "@pretendonetwork/yeah": "^1.0.0", "fs-extra": "^11.2.0", - "semver": "^7.6.0" + "semver": "^7.6.0", + "source-map-support": "^0.5.21" } } diff --git a/src/renderers/main/assets/css/connections-list-section.css b/src/renderers/main/assets/css/connections-list-section.css new file mode 100644 index 0000000..e69de29 diff --git a/src/renderers/main/assets/css/main.css b/src/renderers/main/assets/css/main.css new file mode 100644 index 0000000..2cb2244 --- /dev/null +++ b/src/renderers/main/assets/css/main.css @@ -0,0 +1,101 @@ +body, html { + margin: 0; + padding: 0; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: flex-start; + box-sizing: border-box; + font-size: large; + font-family: monospace; +} + +.content-wrapper { + width: 100%; +} + +#header { + box-sizing: border-box; + width: 100%; + height: 50px; + padding: 5px; + background-color: #5D8AAD; + color: white; + display: flex; + align-items: center; + gap: 20px; +} + +#header-search { + flex: 1; + font-size: large; + padding: 5px; +} + +.container { + box-sizing: border-box; + display: grid; + grid-template-rows: 1fr auto 1fr; + grid-template-columns: 1fr auto 1fr; + grid-template-areas: + "packets packets packets" + "hr hr hr" + "packet-details vr connections"; + width: calc(100vw - 20px); + height: calc(100vh - 80px); + padding: 10px; + margin: auto; +} + +#packets { + grid-area: packets; + overflow-y: auto; + border-top: 5px solid #CCC; + border-left: 5px solid #CCC; + border-right: 5px solid #CCC; +} + +#packet-details { + grid-area: packet-details; + overflow-y: auto; + white-space: nowrap; + border-left: 5px solid #CCC; + border-bottom: 5px solid #CCC; +} + +#connections { + grid-area: connections; + overflow-y: auto; + overflow-x: hidden; + border-right: 5px solid #CCC; + border-bottom: 5px solid #CCC; +} + +.hr { + grid-area: hr; + height: 5px; + cursor: ns-resize; + background: #CCC; + z-index: 1; +} + +.vr { + grid-area: vr; + width: 5px; + cursor: ew-resize; + background: #CCC; + z-index: 1; +} + +.no-select { + user-select: none; +} + +.resizing-horizontal { + cursor: ns-resize; +} + +.resizing-vertical { + cursor: ew-resize; +} \ No newline at end of file diff --git a/src/renderers/main/assets/css/packet-details-section.css b/src/renderers/main/assets/css/packet-details-section.css new file mode 100644 index 0000000..22bfa5d --- /dev/null +++ b/src/renderers/main/assets/css/packet-details-section.css @@ -0,0 +1,35 @@ +/* Put the first
tag into place */ +#packet-details > details { + padding-top: 10px; + padding-left: 30px; +} + +/* Change the huge arrow with a smaller one */ +#packet-details details > summary { + list-style-type: '▸'; +} + +#packet-details details[open] > summary { + list-style-type: '▾'; +} + +/* Move the arrow/ tag back in line with the rest of the list */ +#packet-details details { + margin-left: -10px; +} + +/* Offset child
elements for a cascading effect */ +#packet-details details > div { + margin-left: 25px; +} + +/* Offset spans */ +#packet-details span.name { + margin-right: 3px; +} + +/* Used in packet stack traces */ +#packet-details code { + display: block; + white-space: pre-wrap; +} \ No newline at end of file diff --git a/src/renderers/main/assets/css/packets-section.css b/src/renderers/main/assets/css/packets-section.css new file mode 100644 index 0000000..aa678ba --- /dev/null +++ b/src/renderers/main/assets/css/packets-section.css @@ -0,0 +1,62 @@ +#packet-list { + border-collapse: collapse; + font-size: 16px; + min-width: 100%; + text-align: left; +} + +/* Keep header at the top during scrolling */ +#packet-list thead { + position: sticky; + top: 0; + background: white; +} + +/* Border between columns and remove click events */ +#packet-list th, +#packet-list td { + border-right: 1px solid grey; + cursor: default; +} + +#packet-list thead { + color: grey; + white-space: nowrap; +} + +#packet-list tbody tr { + background: #DAEEFF; +} + +#packet-list tbody tr:hover { + background: #8FBDDA !important; + color: black !important; +} + +#packet-list tbody tr.selected { + background: #308dc7; + color: white; +} + +#packet-list tbody tr.error { + background: #ffa4a4; +} + +#packet-list tbody tr.error:hover { + background: #ff5858 !important; + color: black !important; +} + +#packet-list tbody tr.error.selected { + background: #DD1717; + color: white; +} + +#packet-list tbody tr.hidden { + display: none; +} + +#packet-list tbody td { + white-space: nowrap; + cursor: pointer; +} \ No newline at end of file diff --git a/src/renderers/main/assets/js/electron.ts b/src/renderers/main/assets/js/electron.ts new file mode 100644 index 0000000..c58ba1c --- /dev/null +++ b/src/renderers/main/assets/js/electron.ts @@ -0,0 +1,26 @@ +import { ready, removeAllChildNodes } from '@/renderers/main/assets/js/util'; +import { + packetsListSection, + connectionsListSection, + packetDetailsSection, + addPacketToList, + addConnectionToList +} from '@/renderers/main/assets/js/main'; + +ready(() => { + window.electron.ready(); +}); + +window.electron.onClearSections(() => { + removeAllChildNodes(packetsListSection); + removeAllChildNodes(connectionsListSection); + removeAllChildNodes(packetDetailsSection); +}); + +window.electron.onPacket(addPacketToList); + +window.electron.onConnections(connections => { + for (const connection of connections) { + addConnectionToList(connection); + } +}); \ No newline at end of file diff --git a/src/renderers/main/assets/js/global.d.ts b/src/renderers/main/assets/js/global.d.ts new file mode 100644 index 0000000..086c0b6 --- /dev/null +++ b/src/renderers/main/assets/js/global.d.ts @@ -0,0 +1,13 @@ +import type SerializedPacket from '@/types/nex/serialized-packet'; +import type Connection from '@/nex/connection'; + +declare global { + interface Window { + electron: { + ready: () => void; + onClearSections: (callback: () => void) => void; + onPacket: (callback: (packet: SerializedPacket) => void) => void; + onConnections: (callback: (connections: Connection[]) => void) => void; + } + } +} diff --git a/src/renderers/main/assets/js/main.tsx b/src/renderers/main/assets/js/main.tsx new file mode 100644 index 0000000..2e39542 --- /dev/null +++ b/src/renderers/main/assets/js/main.tsx @@ -0,0 +1,111 @@ +import { createElement } from '@pretendonetwork/yeah'; +import RMCMessage from '@/nex/rmc-message'; +import type SerializedPacket from '@/types/nex/serialized-packet'; +import type SerializedConnection from '@/types/nex/serialized-connection'; +import { removeAllChildNodes } from '@/renderers/main/assets/js/util'; + +export const packetsListSection = document.querySelector('#packet-list tbody')!; +export const connectionsListSection = document.querySelector('#connections')!; +export const packetDetailsSection = document.getElementById('packet-details')!; + +export function addPacketToList(packet: SerializedPacket): void { + const infoData: string[] = []; + + if (packet.version !== -1) { // * Raw RMC packet + infoData.push(packet.type); + + if (packet.flags.includes('MULTI_ACK')) { + infoData.push('MULTI_ACK'); + } else { + infoData.push(`SEQ=${packet.sequence_id}`); + + if (packet.flags.includes('ACK')) { + infoData.push('ACK'); + } + } + + if (packet.type === 'DATA' && !packet.flags.includes('ACK') && !packet.flags.includes('MULTI_ACK')) { + infoData.push(`FRAGMENT=${packet.fragment_id}`); + } + } + + if (packet.message) { + infoData.push(`${packet.message.protocol_name}->${packet.message.method_name}`); + + if (packet.message.type === RMCMessage.REQUEST) { + infoData.push('REQUEST'); + } else { + infoData.push('RESPONSE'); + + if (packet.message.error) { + infoData.push('FAILURE'); + infoData.push(`ERROR ${packet.message.error.name} (0x${packet.message.error.code.toString(16)})`); + } else { + infoData.push('SUCCESS'); + } + } + } + + const timeString = packet.time !== undefined ? packet.time.toFixed(6) : ''; + const sourceString = packet.source_address; + const destinationString = packet.destination_address; + const versionString = packet.version === -1 ? 'Raw RMC' : `v${packet.version}`; + const infoString = infoData.join(', '); + + const row = ( + + {timeString} + {sourceString} + {destinationString} + {versionString} + {infoString} + + ); + + packetsListSection.appendChild(row as any); +} + +export function addConnectionToList(connection: SerializedConnection): void { + const row = ( +
+ {connection.title.name} +
+ ); + + connectionsListSection.appendChild(row as any); +} + +function setSelectedPacketRow(tr: HTMLElement): void { + document.querySelector('tr.selected')?.classList.toggle('selected'); + tr.classList.toggle('selected'); + + updatePacketDetails(JSON.parse(tr.dataset.serialized!)); +} + +function updatePacketDetails(_packet: SerializedPacket): void { + const root = document.createElement('details'); + + removeAllChildNodes(packetDetailsSection); + + packetDetailsSection.appendChild(root); +} + +document.addEventListener('click', event => { + event.stopPropagation(); + + if (!event.target || !(event.target instanceof HTMLElement)) { + return; + } + + if (event.target.tagName.toLowerCase() === 'td') { + setSelectedPacketRow(event.target.parentElement!); + } + + if (event.target.tagName.toLowerCase() === 'tr') { + setSelectedPacketRow(event.target); + } +}); \ No newline at end of file diff --git a/src/renderers/main/assets/js/resize.ts b/src/renderers/main/assets/js/resize.ts new file mode 100644 index 0000000..c230e20 --- /dev/null +++ b/src/renderers/main/assets/js/resize.ts @@ -0,0 +1,65 @@ +const container: HTMLElement = document.querySelector('.container')!; +const horizontalResizer: HTMLElement = document.querySelector('.hr')!; +const verticalResizer: HTMLElement = document.querySelector('.vr')!; +let isResizingHorizontal = false; +let isResizingVertical = false; + +horizontalResizer.addEventListener('mousedown', () => { + isResizingHorizontal = true; + + document.body.classList.add('no-select', 'resizing-horizontal'); + document.addEventListener('mousemove', resizeHorizontal); + document.addEventListener('mouseup', stopResizeHorizontal); +}); + +verticalResizer.addEventListener('mousedown', () => { + isResizingVertical = true; + + document.body.classList.add('no-select', 'resizing-vertical'); + document.addEventListener('mousemove', resizeVertical); + document.addEventListener('mouseup', stopResizeVertical); +}); + +function resizeHorizontal(event: MouseEvent): void { + if (!isResizingHorizontal) { + return; + } + + const containerRect = container.getBoundingClientRect(); + const offsetY = event.clientY - containerRect.top; + + if (offsetY > 20 && offsetY < containerRect.height - 20) { + const percentage = (offsetY / containerRect.height) * 100; + container.style.gridTemplateRows = `${percentage}% 5px calc(${100 - percentage}% - 5px)`; + } +} + +function stopResizeHorizontal(): void { + isResizingHorizontal = false; + + document.body.classList.remove('no-select', 'resizing-horizontal'); + document.removeEventListener('mousemove', resizeHorizontal); + document.removeEventListener('mouseup', stopResizeHorizontal); +} + +function resizeVertical(ev: MouseEvent): void { + if (!isResizingVertical) { + return; + } + + const containerRect = container.getBoundingClientRect(); + const offsetX = ev.clientX - containerRect.left; + + if (offsetX > 20 && offsetX < containerRect.width - 20) { + const percentage = (offsetX / containerRect.width) * 100; + container.style.gridTemplateColumns = `${percentage}% 5px calc(${100 - percentage}% - 5px)`; + } +} + +function stopResizeVertical(): void { + isResizingVertical = false; + + document.body.classList.remove('no-select', 'resizing-vertical'); + document.removeEventListener('mousemove', resizeVertical); + document.removeEventListener('mouseup', stopResizeVertical); +} \ No newline at end of file diff --git a/src/renderers/main/assets/js/util.ts b/src/renderers/main/assets/js/util.ts new file mode 100644 index 0000000..a33c7e0 --- /dev/null +++ b/src/renderers/main/assets/js/util.ts @@ -0,0 +1,13 @@ +export function removeAllChildNodes(parent: Element): void { + while (parent.firstChild) { + parent.removeChild(parent.firstChild); + } +} + +export function ready(callback: () => void): void { + if (document.readyState !== 'loading') { + callback(); + } else { + document.addEventListener('DOMContentLoaded', callback); + } +} \ No newline at end of file diff --git a/src/renderers/main/index.html b/src/renderers/main/index.html index 8f8c652..781d06c 100644 --- a/src/renderers/main/index.html +++ b/src/renderers/main/index.html @@ -2,11 +2,40 @@ - - + NEX Viewer + + + + - TODO +
+ +
+
+ + + + + + + + + + + +
TimeSourceDestinationVersionInfo
+
+
+
+
+
+
+
+ - \ No newline at end of file + diff --git a/tsconfig.json b/tsconfig.json index 063dcb0..24e4f65 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,8 @@ "allowJs": true, "target": "es2022", "noEmitOnError": true, + "jsx": "react", + "jsxFactory": "createElement", "paths": { "@/*": ["./*"] } From 4ee87dda7c0f60a3282af60930eb245e7b327653 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 11:09:55 -0400 Subject: [PATCH 35/67] refactor: condense protocol method classes into one folder --- src/nex/protocols/secure-connection/index.ts | 15 +++++----- .../secure-connection/methods/index.ts | 2 ++ .../{responses => methods}/register-ex.ts | 28 +++++++++++++++++-- .../{responses => methods}/register.ts | 23 +++++++++++++-- .../secure-connection/requests/index.ts | 2 -- .../secure-connection/requests/register-ex.ts | 26 ----------------- .../secure-connection/requests/register.ts | 22 --------------- .../secure-connection/responses/index.ts | 2 -- src/nex/protocols/ticket-granting/index.ts | 21 +++++++------- .../ticket-granting/methods/index.ts | 3 ++ .../{responses => methods}/login-ex.ts | 26 +++++++++++++++-- .../{responses => methods}/login.ts | 22 +++++++++++++-- .../{responses => methods}/request-ticket.ts | 24 +++++++++++++++- .../ticket-granting/requests/index.ts | 3 -- .../ticket-granting/requests/login-ex.ts | 25 ----------------- .../ticket-granting/requests/login.ts | 21 -------------- .../requests/request-ticket.ts | 24 ---------------- .../ticket-granting/responses/index.ts | 3 -- 18 files changed, 136 insertions(+), 156 deletions(-) create mode 100644 src/nex/protocols/secure-connection/methods/index.ts rename src/nex/protocols/secure-connection/{responses => methods}/register-ex.ts (58%) rename src/nex/protocols/secure-connection/{responses => methods}/register.ts (66%) delete mode 100644 src/nex/protocols/secure-connection/requests/index.ts delete mode 100644 src/nex/protocols/secure-connection/requests/register-ex.ts delete mode 100644 src/nex/protocols/secure-connection/requests/register.ts delete mode 100644 src/nex/protocols/secure-connection/responses/index.ts create mode 100644 src/nex/protocols/ticket-granting/methods/index.ts rename src/nex/protocols/ticket-granting/{responses => methods}/login-ex.ts (70%) rename src/nex/protocols/ticket-granting/{responses => methods}/login.ts (77%) rename src/nex/protocols/ticket-granting/{responses => methods}/request-ticket.ts (68%) delete mode 100644 src/nex/protocols/ticket-granting/requests/index.ts delete mode 100644 src/nex/protocols/ticket-granting/requests/login-ex.ts delete mode 100644 src/nex/protocols/ticket-granting/requests/login.ts delete mode 100644 src/nex/protocols/ticket-granting/requests/request-ticket.ts delete mode 100644 src/nex/protocols/ticket-granting/responses/index.ts diff --git a/src/nex/protocols/secure-connection/index.ts b/src/nex/protocols/secure-connection/index.ts index 5ef7ac2..24650b0 100644 --- a/src/nex/protocols/secure-connection/index.ts +++ b/src/nex/protocols/secure-connection/index.ts @@ -1,6 +1,5 @@ import RMCMessage from '@/nex/rmc-message'; -import * as Requests from '@/nex/protocols/secure-connection/requests'; -import * as Responses from '@/nex/protocols/secure-connection/responses'; +import * as Methods from '@/nex/protocols/secure-connection/methods'; import type Packet from '@/types/nex/packet'; export default class SecureConnectionProtocol { @@ -45,19 +44,19 @@ export default class SecureConnectionProtocol { packet.message.methodName = messageDecoder.Name; } - private static Register(message: RMCMessage): typeof Requests.RegisterRequest | typeof Responses.RegisterResponse { + private static Register(message: RMCMessage): typeof Methods.Register.Request | typeof Methods.Register.Response { if (message.type === RMCMessage.REQUEST) { - return Requests.RegisterRequest; + return Methods.Register.Request; } else { - return Responses.RegisterResponse; + return Methods.Register.Response; } } - private static RegisterEx(message: RMCMessage): typeof Requests.RegisterExRequest | typeof Responses.RegisterExResponse { + private static RegisterEx(message: RMCMessage): typeof Methods.RegisterEx.Request | typeof Methods.RegisterEx.Response { if (message.type === RMCMessage.REQUEST) { - return Requests.RegisterExRequest; + return Methods.RegisterEx.Request; } else { - return Responses.RegisterExResponse; + return Methods.RegisterEx.Response; } } } \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/index.ts b/src/nex/protocols/secure-connection/methods/index.ts new file mode 100644 index 0000000..c317e0f --- /dev/null +++ b/src/nex/protocols/secure-connection/methods/index.ts @@ -0,0 +1,2 @@ +export * as Register from '@/nex/protocols/secure-connection/methods/register'; +export * as RegisterEx from '@/nex/protocols/secure-connection/methods/register-ex'; \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/responses/register-ex.ts b/src/nex/protocols/secure-connection/methods/register-ex.ts similarity index 58% rename from src/nex/protocols/secure-connection/responses/register-ex.ts rename to src/nex/protocols/secure-connection/methods/register-ex.ts index 23f1b32..099452a 100644 --- a/src/nex/protocols/secure-connection/responses/register-ex.ts +++ b/src/nex/protocols/secure-connection/methods/register-ex.ts @@ -1,10 +1,34 @@ import NEXByteStream from '@/nex/byte-stream'; import RMCMessage from '@/nex/rmc-message'; +import StationURL from '@/nex/types/station-url'; +import List from '@/nex/types/list'; +import AnyDataHolder from '@/nex/types/any-data-holder'; import QResult from '@/nex/types/qresult'; import UInt32 from '@/nex/types/uint32'; -import StationURL from '@/nex/types/station-url'; -export default class RegisterExResponse { + +export class Request { + public static Name = 'RegisterEx'; + + private vecMyURLs = new List(new StationURL()); + private hCustomData = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.vecMyURLs.extractFrom(stream); + this.hCustomData.extractFrom(stream); + } + + public toJSON(): Record { + return { + vecMyURLs: this.vecMyURLs, + hCustomData: this.hCustomData + }; + } +} + +export class Response { public static Name = 'RegisterEx'; private retval = new QResult(); diff --git a/src/nex/protocols/secure-connection/responses/register.ts b/src/nex/protocols/secure-connection/methods/register.ts similarity index 66% rename from src/nex/protocols/secure-connection/responses/register.ts rename to src/nex/protocols/secure-connection/methods/register.ts index ccd5a49..f262230 100644 --- a/src/nex/protocols/secure-connection/responses/register.ts +++ b/src/nex/protocols/secure-connection/methods/register.ts @@ -1,10 +1,29 @@ import NEXByteStream from '@/nex/byte-stream'; import RMCMessage from '@/nex/rmc-message'; +import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; import QResult from '@/nex/types/qresult'; import UInt32 from '@/nex/types/uint32'; -import StationURL from '@/nex/types/station-url'; -export default class RegisterResponse { +export class Request { + public static Name = 'Register'; + + private vecMyURLs = new List(new StationURL()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.vecMyURLs.extractFrom(stream); + } + + public toJSON(): Record { + return { + vecMyURLs: this.vecMyURLs + }; + } +} + +export class Response { public static Name = 'Register'; private retval = new QResult(); diff --git a/src/nex/protocols/secure-connection/requests/index.ts b/src/nex/protocols/secure-connection/requests/index.ts deleted file mode 100644 index a0965a9..0000000 --- a/src/nex/protocols/secure-connection/requests/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as RegisterRequest } from '@/nex/protocols/secure-connection/requests/register'; -export { default as RegisterExRequest } from '@/nex/protocols/secure-connection/requests/register-ex'; \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/requests/register-ex.ts b/src/nex/protocols/secure-connection/requests/register-ex.ts deleted file mode 100644 index 3123d80..0000000 --- a/src/nex/protocols/secure-connection/requests/register-ex.ts +++ /dev/null @@ -1,26 +0,0 @@ -import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; -import List from '@/nex/types/list'; -import StationURL from '@/nex/types/station-url'; -import AnyDataHolder from '@/nex/types/any-data-holder'; - -export default class RegisterExRequest { - public static Name = 'RegisterEx'; - - private vecMyURLs = new List(new StationURL()); - private hCustomData = new AnyDataHolder(); - - constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); - - this.vecMyURLs.extractFrom(stream); - this.hCustomData.extractFrom(stream); - } - - public toJSON(): Record { - return { - vecMyURLs: this.vecMyURLs, - hCustomData: this.hCustomData - }; - } -} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/requests/register.ts b/src/nex/protocols/secure-connection/requests/register.ts deleted file mode 100644 index 19dba12..0000000 --- a/src/nex/protocols/secure-connection/requests/register.ts +++ /dev/null @@ -1,22 +0,0 @@ -import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; -import List from '@/nex/types/list'; -import StationURL from '@/nex/types/station-url'; - -export default class RegisterRequest { - public static Name = 'Register'; - - private vecMyURLs = new List(new StationURL()); - - constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); - - this.vecMyURLs.extractFrom(stream); - } - - public toJSON(): Record { - return { - vecMyURLs: this.vecMyURLs - }; - } -} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/responses/index.ts b/src/nex/protocols/secure-connection/responses/index.ts deleted file mode 100644 index 6e0f305..0000000 --- a/src/nex/protocols/secure-connection/responses/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as RegisterResponse } from '@/nex/protocols/secure-connection/responses/register'; -export { default as RegisterExResponse } from '@/nex/protocols/secure-connection/responses/register-ex'; \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/index.ts b/src/nex/protocols/ticket-granting/index.ts index 33adda4..e5ea73b 100644 --- a/src/nex/protocols/ticket-granting/index.ts +++ b/src/nex/protocols/ticket-granting/index.ts @@ -1,6 +1,5 @@ import RMCMessage from '@/nex/rmc-message'; -import * as Requests from '@/nex/protocols/ticket-granting/requests'; -import * as Responses from '@/nex/protocols/ticket-granting/responses'; +import * as Methods from '@/nex/protocols/ticket-granting/methods'; import type Packet from '@/types/nex/packet'; export default class TicketGrantingProtocol { @@ -53,27 +52,27 @@ export default class TicketGrantingProtocol { packet.message.methodName = messageDecoder.Name; } - private static Login(message: RMCMessage): typeof Requests.LoginRequest | typeof Responses.LoginResponse { + private static Login(message: RMCMessage): typeof Methods.Login.Request | typeof Methods.Login.Response { if (message.type === RMCMessage.REQUEST) { - return Requests.LoginRequest; + return Methods.Login.Request; } else { - return Responses.LoginResponse; + return Methods.Login.Response; } } - private static LoginEx(message: RMCMessage): typeof Requests.LoginExRequest | typeof Responses.LoginExResponse { + private static LoginEx(message: RMCMessage): typeof Methods.LoginEx.Request | typeof Methods.LoginEx.Response { if (message.type === RMCMessage.REQUEST) { - return Requests.LoginExRequest; + return Methods.LoginEx.Request; } else { - return Responses.LoginExResponse; + return Methods.LoginEx.Response; } } - private static RequestTicket(message: RMCMessage): typeof Requests.RequestTicketRequest | typeof Responses.RequestTicketResponse { + private static RequestTicket(message: RMCMessage): typeof Methods.RequestTicket.Request | typeof Methods.RequestTicket.Response { if (message.type === RMCMessage.REQUEST) { - return Requests.RequestTicketRequest; + return Methods.RequestTicket.Request; } else { - return Responses.RequestTicketResponse; + return Methods.RequestTicket.Response; } } } \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/index.ts b/src/nex/protocols/ticket-granting/methods/index.ts new file mode 100644 index 0000000..aa65097 --- /dev/null +++ b/src/nex/protocols/ticket-granting/methods/index.ts @@ -0,0 +1,3 @@ +export * as Login from '@/nex/protocols/ticket-granting/methods/login'; +export * as LoginEx from '@/nex/protocols/ticket-granting/methods/login-ex'; +export * as RequestTicket from '@/nex/protocols/ticket-granting/methods/request-ticket'; \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/responses/login-ex.ts b/src/nex/protocols/ticket-granting/methods/login-ex.ts similarity index 70% rename from src/nex/protocols/ticket-granting/responses/login-ex.ts rename to src/nex/protocols/ticket-granting/methods/login-ex.ts index 661cb59..ba73c03 100644 --- a/src/nex/protocols/ticket-granting/responses/login-ex.ts +++ b/src/nex/protocols/ticket-granting/methods/login-ex.ts @@ -1,12 +1,34 @@ import NEXByteStream from '@/nex/byte-stream'; import RMCMessage from '@/nex/rmc-message'; +import RVString from '@/nex/types/string'; +import AnyDataHolder from '@/nex/types/any-data-holder'; import QResult from '@/nex/types/qresult'; import PID from '@/nex/types/pid'; import RVBuffer from '@/nex/types/buffer'; import RVConnectionData from '@/nex/types/rv-connection-data'; -import RVString from '@/nex/types/string'; -export default class LoginExResponse { +export class Request { + public static Name = 'LoginEx'; + + private strUserName = new RVString(); + private oExtraData = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.strUserName.extractFrom(stream); + this.oExtraData.extractFrom(stream); + } + + public toJSON(): Record { + return { + strUserName: this.strUserName, + oExtraData: this.oExtraData + }; + } +} + +export class Response { public static Name = 'LoginEx'; private retval = new QResult(); diff --git a/src/nex/protocols/ticket-granting/responses/login.ts b/src/nex/protocols/ticket-granting/methods/login.ts similarity index 77% rename from src/nex/protocols/ticket-granting/responses/login.ts rename to src/nex/protocols/ticket-granting/methods/login.ts index edaae96..c2b9b54 100644 --- a/src/nex/protocols/ticket-granting/responses/login.ts +++ b/src/nex/protocols/ticket-granting/methods/login.ts @@ -1,12 +1,30 @@ import NEXByteStream from '@/nex/byte-stream'; import RMCMessage from '@/nex/rmc-message'; +import RVString from '@/nex/types/string'; import QResult from '@/nex/types/qresult'; import PID from '@/nex/types/pid'; import RVBuffer from '@/nex/types/buffer'; import RVConnectionData from '@/nex/types/rv-connection-data'; -import RVString from '@/nex/types/string'; -export default class LoginResponse { +export class Request { + public static Name = 'Login'; + + private strUserName = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.strUserName.extractFrom(stream); + } + + public toJSON(): Record { + return { + strUserName: this.strUserName + }; + } +} + +export class Response { public static Name = 'Login'; private retval = new QResult(); diff --git a/src/nex/protocols/ticket-granting/responses/request-ticket.ts b/src/nex/protocols/ticket-granting/methods/request-ticket.ts similarity index 68% rename from src/nex/protocols/ticket-granting/responses/request-ticket.ts rename to src/nex/protocols/ticket-granting/methods/request-ticket.ts index 4770233..331bcce 100644 --- a/src/nex/protocols/ticket-granting/responses/request-ticket.ts +++ b/src/nex/protocols/ticket-granting/methods/request-ticket.ts @@ -1,10 +1,32 @@ import NEXByteStream from '@/nex/byte-stream'; import RMCMessage from '@/nex/rmc-message'; +import PID from '@/nex/types/pid'; import QResult from '@/nex/types/qresult'; import RVBuffer from '@/nex/types/buffer'; import RVString from '@/nex/types/string'; -export default class RequestTicketResponse { +export class Request { + public static Name = 'RequestTicket'; + + private idSource = new PID(); + private idTarget = new PID(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.idSource.extractFrom(stream); + this.idTarget.extractFrom(stream); + } + + public toJSON(): Record { + return { + idSource: this.idSource, + idTarget: this.idTarget + }; + } +} + +export class Response { public static Name = 'RequestTicket'; private retval = new QResult(); diff --git a/src/nex/protocols/ticket-granting/requests/index.ts b/src/nex/protocols/ticket-granting/requests/index.ts deleted file mode 100644 index 9660ae0..0000000 --- a/src/nex/protocols/ticket-granting/requests/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { default as LoginRequest } from '@/nex/protocols/ticket-granting/requests/login'; -export { default as LoginExRequest } from '@/nex/protocols/ticket-granting/requests/login-ex'; -export { default as RequestTicketRequest } from '@/nex/protocols/ticket-granting/requests/request-ticket'; \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/requests/login-ex.ts b/src/nex/protocols/ticket-granting/requests/login-ex.ts deleted file mode 100644 index 1059818..0000000 --- a/src/nex/protocols/ticket-granting/requests/login-ex.ts +++ /dev/null @@ -1,25 +0,0 @@ -import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; -import RVString from '@/nex/types/string'; -import AnyDataHolder from '@/nex/types/any-data-holder'; - -export default class LoginExRequest { - public static Name = 'LoginEx'; - - private strUserName = new RVString(); - private oExtraData = new AnyDataHolder(); - - constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); - - this.strUserName.extractFrom(stream); - this.oExtraData.extractFrom(stream); - } - - public toJSON(): Record { - return { - strUserName: this.strUserName, - oExtraData: this.oExtraData - }; - } -} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/requests/login.ts b/src/nex/protocols/ticket-granting/requests/login.ts deleted file mode 100644 index 9ca03a0..0000000 --- a/src/nex/protocols/ticket-granting/requests/login.ts +++ /dev/null @@ -1,21 +0,0 @@ -import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; -import RVString from '@/nex/types/string'; - -export default class LoginRequest { - public static Name = 'Login'; - - private strUserName = new RVString(); - - constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); - - this.strUserName.extractFrom(stream); - } - - public toJSON(): Record { - return { - strUserName: this.strUserName - }; - } -} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/requests/request-ticket.ts b/src/nex/protocols/ticket-granting/requests/request-ticket.ts deleted file mode 100644 index 2a1716a..0000000 --- a/src/nex/protocols/ticket-granting/requests/request-ticket.ts +++ /dev/null @@ -1,24 +0,0 @@ -import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; -import PID from '@/nex/types/pid'; - -export default class RequestTicketRequest { - public static Name = 'RequestTicket'; - - private idSource = new PID(); - private idTarget = new PID(); - - constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); - - this.idSource.extractFrom(stream); - this.idTarget.extractFrom(stream); - } - - public toJSON(): Record { - return { - idSource: this.idSource, - idTarget: this.idTarget - }; - } -} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/responses/index.ts b/src/nex/protocols/ticket-granting/responses/index.ts deleted file mode 100644 index 97c7472..0000000 --- a/src/nex/protocols/ticket-granting/responses/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { default as LoginResponse } from '@/nex/protocols/ticket-granting/responses/login'; -export { default as LoginExResponse } from '@/nex/protocols/ticket-granting/responses/login-ex'; -export { default as RequestTicketResponse } from '@/nex/protocols/ticket-granting/responses/request-ticket'; \ No newline at end of file From 05fbd8da9fba32c8199c4e41dd2ff38d45749abb Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 11:34:20 -0400 Subject: [PATCH 36/67] feat: implement all of SecureConnection --- src/nex/protocols/secure-connection/index.ts | 58 ++++++++++++++++++- .../secure-connection/methods/index.ts | 8 ++- .../secure-connection/methods/replace-url.ts | 35 +++++++++++ .../methods/request-connection-data.ts | 48 +++++++++++++++ .../secure-connection/methods/request-urls.ts | 48 +++++++++++++++ .../secure-connection/methods/send-report.ts | 36 ++++++++++++ .../methods/test-connectivity.ts | 22 +++++++ .../secure-connection/methods/update-urls.ts | 33 +++++++++++ .../types/connection-data.ts | 34 +++++++++++ 9 files changed, 319 insertions(+), 3 deletions(-) create mode 100644 src/nex/protocols/secure-connection/methods/replace-url.ts create mode 100644 src/nex/protocols/secure-connection/methods/request-connection-data.ts create mode 100644 src/nex/protocols/secure-connection/methods/request-urls.ts create mode 100644 src/nex/protocols/secure-connection/methods/send-report.ts create mode 100644 src/nex/protocols/secure-connection/methods/test-connectivity.ts create mode 100644 src/nex/protocols/secure-connection/methods/update-urls.ts create mode 100644 src/nex/protocols/secure-connection/types/connection-data.ts diff --git a/src/nex/protocols/secure-connection/index.ts b/src/nex/protocols/secure-connection/index.ts index 24650b0..a09f481 100644 --- a/src/nex/protocols/secure-connection/index.ts +++ b/src/nex/protocols/secure-connection/index.ts @@ -9,7 +9,7 @@ export default class SecureConnectionProtocol { static Methods = { Register: 0x1, RequestConnectionData: 0x2, - RequestUrls: 0x3, + RequestURLs: 0x3, RegisterEx: 0x4, TestConnectivity: 0x5, UpdateURLs: 0x6, @@ -19,7 +19,13 @@ export default class SecureConnectionProtocol { private static handlers: Record any> = { 0x1: SecureConnectionProtocol.Register, - 0x4: SecureConnectionProtocol.RegisterEx + 0x2: SecureConnectionProtocol.RequestConnectionData, + 0x3: SecureConnectionProtocol.RequestURLs, + 0x4: SecureConnectionProtocol.RegisterEx, + 0x5: SecureConnectionProtocol.TestConnectivity, + 0x6: SecureConnectionProtocol.UpdateURLs, + 0x7: SecureConnectionProtocol.ReplaceURL, + 0x8: SecureConnectionProtocol.SendReport }; static handlePacket(packet: Packet): void { @@ -52,6 +58,22 @@ export default class SecureConnectionProtocol { } } + private static RequestConnectionData(message: RMCMessage): typeof Methods.RequestConnectionData.Request | typeof Methods.RequestConnectionData.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.RequestConnectionData.Request; + } else { + return Methods.RequestConnectionData.Response; + } + } + + private static RequestURLs(message: RMCMessage): typeof Methods.RequestURLs.Request | typeof Methods.RequestURLs.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.RequestURLs.Request; + } else { + return Methods.RequestURLs.Response; + } + } + private static RegisterEx(message: RMCMessage): typeof Methods.RegisterEx.Request | typeof Methods.RegisterEx.Response { if (message.type === RMCMessage.REQUEST) { return Methods.RegisterEx.Request; @@ -59,4 +81,36 @@ export default class SecureConnectionProtocol { return Methods.RegisterEx.Response; } } + + private static TestConnectivity(message: RMCMessage): typeof Methods.TestConnectivity.Request | typeof Methods.TestConnectivity.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.TestConnectivity.Request; + } else { + return Methods.TestConnectivity.Response; + } + } + + private static UpdateURLs(message: RMCMessage): typeof Methods.UpdateURLs.Request | typeof Methods.UpdateURLs.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateURLs.Request; + } else { + return Methods.UpdateURLs.Response; + } + } + + private static ReplaceURL(message: RMCMessage): typeof Methods.ReplaceURL.Request | typeof Methods.ReplaceURL.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ReplaceURL.Request; + } else { + return Methods.ReplaceURL.Response; + } + } + + private static SendReport(message: RMCMessage): typeof Methods.SendReport.Request | typeof Methods.SendReport.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.SendReport.Request; + } else { + return Methods.SendReport.Response; + } + } } \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/index.ts b/src/nex/protocols/secure-connection/methods/index.ts index c317e0f..2ac5803 100644 --- a/src/nex/protocols/secure-connection/methods/index.ts +++ b/src/nex/protocols/secure-connection/methods/index.ts @@ -1,2 +1,8 @@ export * as Register from '@/nex/protocols/secure-connection/methods/register'; -export * as RegisterEx from '@/nex/protocols/secure-connection/methods/register-ex'; \ No newline at end of file +export * as RequestConnectionData from '@/nex/protocols/secure-connection/methods/request-connection-data'; +export * as RequestURLs from '@/nex/protocols/secure-connection/methods/request-urls'; +export * as RegisterEx from '@/nex/protocols/secure-connection/methods/register-ex'; +export * as TestConnectivity from '@/nex/protocols/secure-connection/methods/test-connectivity'; +export * as UpdateURLs from '@/nex/protocols/secure-connection/methods/update-urls'; +export * as ReplaceURL from '@/nex/protocols/secure-connection/methods/replace-url'; +export * as SendReport from '@/nex/protocols/secure-connection/methods/send-report'; \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/replace-url.ts b/src/nex/protocols/secure-connection/methods/replace-url.ts new file mode 100644 index 0000000..f21d403 --- /dev/null +++ b/src/nex/protocols/secure-connection/methods/replace-url.ts @@ -0,0 +1,35 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import StationURL from '@/nex/types/station-url'; + +export class Request { + public static Name = 'ReplaceURL'; + + private target = new StationURL(); + private url = new StationURL(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.target.extractFrom(stream); + this.url.extractFrom(stream); + } + + public toJSON(): Record { + return { + target: this.target, + url: this.url + }; + } +} + +// * No response data +export class Response { + public static Name = 'ReplaceURL'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/request-connection-data.ts b/src/nex/protocols/secure-connection/methods/request-connection-data.ts new file mode 100644 index 0000000..e80e941 --- /dev/null +++ b/src/nex/protocols/secure-connection/methods/request-connection-data.ts @@ -0,0 +1,48 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import List from '@/nex/types/list'; +import ConnectionData from '@/nex/protocols/secure-connection/types/connection-data'; + +export class Request { + public static Name = 'RequestConnectionData'; + + private cidTarget = new UInt32(); + private pidTarget = new UInt32(); // TODO - Is this actually a PID type? Check the Switch + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.cidTarget.extractFrom(stream); + this.pidTarget.extractFrom(stream); + } + + public toJSON(): Record { + return { + cidTarget: this.cidTarget, + pidTarget: this.pidTarget + }; + } +} + +export class Response { + public static Name = 'RequestConnectionData'; + + private retval = new Bool(); + private pvecConnectionsData = new List(new ConnectionData()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.retval.extractFrom(stream); + this.pvecConnectionsData.extractFrom(stream); + } + + public toJSON(): Record { + return { + retval: this.retval, + pvecConnectionsData: this.pvecConnectionsData + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/request-urls.ts b/src/nex/protocols/secure-connection/methods/request-urls.ts new file mode 100644 index 0000000..8c7484f --- /dev/null +++ b/src/nex/protocols/secure-connection/methods/request-urls.ts @@ -0,0 +1,48 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; + +export class Request { + public static Name = 'RequestUrls'; + + private cidTarget = new UInt32(); + private pidTarget = new UInt32(); // TODO - Is this actually a PID type? Check the Switch + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.cidTarget.extractFrom(stream); + this.pidTarget.extractFrom(stream); + } + + public toJSON(): Record { + return { + cidTarget: this.cidTarget, + pidTarget: this.pidTarget + }; + } +} + +export class Response { + public static Name = 'RequestUrls'; + + private retval = new Bool(); + private plstURLs = new List(new StationURL()); // TODO - Is this actually a PID type? Check the Switch + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.retval.extractFrom(stream); + this.plstURLs.extractFrom(stream); + } + + public toJSON(): Record { + return { + retval: this.retval, + plstURLs: this.plstURLs + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/send-report.ts b/src/nex/protocols/secure-connection/methods/send-report.ts new file mode 100644 index 0000000..e78f593 --- /dev/null +++ b/src/nex/protocols/secure-connection/methods/send-report.ts @@ -0,0 +1,36 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import UInt32 from '@/nex/types/uint32'; +import QBuffer from '@/nex/types/qbuffer'; + +export class Request { + public static Name = 'SendReport'; + + private reportId = new UInt32(); + private reportData = new QBuffer(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.reportId.extractFrom(stream); + this.reportData.extractFrom(stream); + } + + public toJSON(): Record { + return { + reportId: this.reportId, + reportData: this.reportData + }; + } +} + +// * No response data +export class Response { + public static Name = 'SendReport'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/test-connectivity.ts b/src/nex/protocols/secure-connection/methods/test-connectivity.ts new file mode 100644 index 0000000..95b5554 --- /dev/null +++ b/src/nex/protocols/secure-connection/methods/test-connectivity.ts @@ -0,0 +1,22 @@ + +// * No request data +export class Request { + public static Name = 'TestConnectivity'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} + +// * No response data +export class Response { + public static Name = 'TestConnectivity'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/update-urls.ts b/src/nex/protocols/secure-connection/methods/update-urls.ts new file mode 100644 index 0000000..4b6b821 --- /dev/null +++ b/src/nex/protocols/secure-connection/methods/update-urls.ts @@ -0,0 +1,33 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; + +export class Request { + public static Name = 'UpdateURLs'; + + private vecMyURLs = new List(new StationURL()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.vecMyURLs.extractFrom(stream); + } + + public toJSON(): Record { + return { + vecMyURLs: this.vecMyURLs + }; + } +} + +// * No response data +export class Response { + public static Name = 'UpdateURLs'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/types/connection-data.ts b/src/nex/protocols/secure-connection/types/connection-data.ts new file mode 100644 index 0000000..39fea4c --- /dev/null +++ b/src/nex/protocols/secure-connection/types/connection-data.ts @@ -0,0 +1,34 @@ +import Structure from '@/nex/types/structure'; +import StationURL from '@/nex/types/station-url'; +import UInt32 from '@/nex/types/uint32'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class ConnectionData extends Structure { + public readonly typeName = 'ConnectionData'; + + private m_StationUrl = new StationURL(); + private m_ConnectionID = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_StationUrl.extractFrom(stream); + this.m_ConnectionID.extractFrom(stream); + } + + public new(): ConnectionData { + return new ConnectionData(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_StationUrl: this.m_StationUrl, + m_ConnectionID: this.m_ConnectionID + } + }; + } +} \ No newline at end of file From 191a1b931bca0a38322e8fead795e8bd9d28eb83 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 14:27:34 -0400 Subject: [PATCH 37/67] feat: add NintendoLoginData/AccountExtraInfo types --- .../types/account-extra-info.ts | 35 +++++++++++++++++++ .../types/nintendo-login-data.ts | 35 +++++++++++++++++++ src/nex/types/data.ts | 9 +++-- 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 src/nex/protocols/secure-connection/types/account-extra-info.ts create mode 100644 src/nex/protocols/secure-connection/types/nintendo-login-data.ts diff --git a/src/nex/protocols/secure-connection/types/account-extra-info.ts b/src/nex/protocols/secure-connection/types/account-extra-info.ts new file mode 100644 index 0000000..e8f8ecc --- /dev/null +++ b/src/nex/protocols/secure-connection/types/account-extra-info.ts @@ -0,0 +1,35 @@ +import Data from '@/nex/types/data'; +import String from '@/nex/types/string'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class AccountExtraInfo extends Data { + public get typeName(): string { + return 'AccountExtraInfo'; + } + + private token = new String(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.token.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + token: this.token + } + }; + } +} + +AnyDataHolder.Classes['AccountExtraInfo'] = AccountExtraInfo; diff --git a/src/nex/protocols/secure-connection/types/nintendo-login-data.ts b/src/nex/protocols/secure-connection/types/nintendo-login-data.ts new file mode 100644 index 0000000..baf68a9 --- /dev/null +++ b/src/nex/protocols/secure-connection/types/nintendo-login-data.ts @@ -0,0 +1,35 @@ +import Data from '@/nex/types/data'; +import String from '@/nex/types/string'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class NintendoLoginData extends Data { + public get typeName(): string { + return 'NintendoLoginData'; + } + + private token = new String(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.token.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + token: this.token + } + }; + } +} + +AnyDataHolder.Classes['NintendoLoginData'] = NintendoLoginData; diff --git a/src/nex/types/data.ts b/src/nex/types/data.ts index ec5daeb..4f24845 100644 --- a/src/nex/types/data.ts +++ b/src/nex/types/data.ts @@ -4,14 +4,17 @@ import type NEXByteStream from '@/nex/byte-stream'; // * Data has no fields itself. // * This is the parent class for all types which are allowed in AnyDataHolder export default class Data extends Structure { - public readonly typeName = 'Data'; + // * Make this a getter so it can be overridden by child classes + public get typeName(): string { + return 'Data'; + } public extractFrom(stream: NEXByteStream): void { this.extractHeaderFrom(stream); } - public new(): Data { - return new Data(); + public new(): this { + return new (this.constructor as new () => this)(); } public toJSON(): Record { From 39f409b49c57b1d1bfde28acd1bf471eca3800ca Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 15:39:35 -0400 Subject: [PATCH 38/67] feat: implement all of NAT Traversal --- src/nex/protocols/manager.ts | 3 + src/nex/protocols/nat-traversal/index.ts | 106 ++++++++++++++++++ .../methods/get-relay-signature-key.ts | 51 +++++++++ .../protocols/nat-traversal/methods/index.ts | 7 ++ .../nat-traversal/methods/initiate-probe.ts | 32 ++++++ .../methods/report-nat-properties.ts | 38 +++++++ .../report-nat-traversal-result-detail.ts | 43 +++++++ .../methods/report-nat-traversal-result.ts | 49 ++++++++ .../methods/request-probe-initiation-ext.ts | 36 ++++++ .../methods/request-probe-initiation.ts | 33 ++++++ 10 files changed, 398 insertions(+) create mode 100644 src/nex/protocols/nat-traversal/index.ts create mode 100644 src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts create mode 100644 src/nex/protocols/nat-traversal/methods/index.ts create mode 100644 src/nex/protocols/nat-traversal/methods/initiate-probe.ts create mode 100644 src/nex/protocols/nat-traversal/methods/report-nat-properties.ts create mode 100644 src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts create mode 100644 src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts create mode 100644 src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts create mode 100644 src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts diff --git a/src/nex/protocols/manager.ts b/src/nex/protocols/manager.ts index 308be63..a22334a 100644 --- a/src/nex/protocols/manager.ts +++ b/src/nex/protocols/manager.ts @@ -1,4 +1,5 @@ import RMCMessage from '@/nex/rmc-message'; +import NATTraversalProtocol from '@/nex/protocols/nat-traversal'; import TicketGrantingProtocol from '@/nex/protocols/ticket-granting'; import SecureConnectionProtocol from '@/nex/protocols/secure-connection'; import type ServiceProtocol from '@/types/nex/service-protocol'; @@ -7,6 +8,8 @@ export default function getProtocol(message: RMCMessage): ServiceProtocol | null const protocolID = message.protocolID === 0x7F ? message.extendedProtocolID : message.protocolID; switch (protocolID) { + case NATTraversalProtocol.ID: + return NATTraversalProtocol; case TicketGrantingProtocol.ID: return TicketGrantingProtocol; case SecureConnectionProtocol.ID: diff --git a/src/nex/protocols/nat-traversal/index.ts b/src/nex/protocols/nat-traversal/index.ts new file mode 100644 index 0000000..daf6c5b --- /dev/null +++ b/src/nex/protocols/nat-traversal/index.ts @@ -0,0 +1,106 @@ +import RMCMessage from '@/nex/rmc-message'; +import * as Methods from '@/nex/protocols/nat-traversal/methods'; +import type Packet from '@/types/nex/packet'; + +export default class NATTraversalProtocol { + static ID = 0x3; + static Name = 'NATTraversal'; + + static Methods = { + RequestProbeInitiation: 0x1, + InitiateProbe: 0x2, + RequestProbeInitiationExt: 0x3, + ReportNATTraversalResult: 0x4, + ReportNATProperties: 0x5, + GetRelaySignatureKey: 0x6, + ReportNATTraversalResultDetail: 0x7 + }; + + private static handlers: Record any> = { + 0x1: NATTraversalProtocol.RequestProbeInitiation, + 0x2: NATTraversalProtocol.InitiateProbe, + 0x3: NATTraversalProtocol.RequestProbeInitiationExt, + 0x4: NATTraversalProtocol.ReportNATTraversalResult, + 0x5: NATTraversalProtocol.ReportNATProperties, + 0x6: NATTraversalProtocol.GetRelaySignatureKey, + 0x7: NATTraversalProtocol.ReportNATTraversalResultDetail + }; + + static handlePacket(packet: Packet): void { + if (!packet.message) { + // * This will never happen. Only checked to make TypeScript happy + return; + } + + const methodID = packet.message.methodID; + + // TODO - Use Switch names when parsing Switch packets + const handler = NATTraversalProtocol.handlers[methodID]; + + if (!handler) { + packet.message.methodName = `UnknownMethod_0x${methodID.toString(16).toUpperCase().padStart(2, '0')}`; + return; + } + + const messageDecoder = handler(packet.message); + + packet.message.parameters = new messageDecoder(packet.message); + packet.message.methodName = messageDecoder.Name; + } + + private static RequestProbeInitiation(message: RMCMessage): typeof Methods.RequestProbeInitiation.Request | typeof Methods.RequestProbeInitiation.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.RequestProbeInitiation.Request; + } else { + return Methods.RequestProbeInitiation.Response; + } + } + + private static InitiateProbe(message: RMCMessage): typeof Methods.InitiateProbe.Request | typeof Methods.InitiateProbe.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.InitiateProbe.Request; + } else { + return Methods.InitiateProbe.Response; + } + } + + private static RequestProbeInitiationExt(message: RMCMessage): typeof Methods.RequestProbeInitiationExt.Request | typeof Methods.RequestProbeInitiationExt.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.RequestProbeInitiationExt.Request; + } else { + return Methods.RequestProbeInitiationExt.Response; + } + } + + private static ReportNATTraversalResult(message: RMCMessage): typeof Methods.ReportNATTraversalResult.Request | typeof Methods.ReportNATTraversalResult.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ReportNATTraversalResult.Request; + } else { + return Methods.ReportNATTraversalResult.Response; + } + } + + private static ReportNATProperties(message: RMCMessage): typeof Methods.ReportNATProperties.Request | typeof Methods.ReportNATProperties.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ReportNATProperties.Request; + } else { + return Methods.ReportNATProperties.Response; + } + } + + private static GetRelaySignatureKey(message: RMCMessage): typeof Methods.GetRelaySignatureKey.Request | typeof Methods.GetRelaySignatureKey.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetRelaySignatureKey.Request; + } else { + return Methods.GetRelaySignatureKey.Response; + } + } + + private static ReportNATTraversalResultDetail(message: RMCMessage): typeof Methods.ReportNATTraversalResultDetail.Request | typeof Methods.ReportNATTraversalResultDetail.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ReportNATTraversalResultDetail.Request; + } else { + return Methods.ReportNATTraversalResultDetail.Response; + } + } +} \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts b/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts new file mode 100644 index 0000000..33cb5a5 --- /dev/null +++ b/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts @@ -0,0 +1,51 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import Int32 from '@/nex/types/int32'; +import DateTime from '@/nex/types/datetime'; +import RVString from '@/nex/types/string'; +import UInt16 from '@/nex/types/uint16'; +import UInt32 from '@/nex/types/uint32'; + +// * No request data +export class Request { + public static Name = 'GetRelaySignatureKey'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} + +export class Response { + public static Name = 'GetRelaySignatureKey'; + + private relayMode = new Int32(); + private currentUTCTime = new DateTime(); + private address = new RVString(); + private port = new UInt16(); + private relayAddressType = new Int32(); + private gameServerID = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.relayMode.extractFrom(stream); + this.currentUTCTime.extractFrom(stream); + this.address.extractFrom(stream); + this.port.extractFrom(stream); + this.relayAddressType.extractFrom(stream); + this.gameServerID.extractFrom(stream); + } + + public toJSON(): Record { + return { + relayMode: this.relayMode, + currentUTCTime: this.currentUTCTime, + address: this.address, + port: this.port, + relayAddressType: this.relayAddressType, + gameServerID: this.gameServerID + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/index.ts b/src/nex/protocols/nat-traversal/methods/index.ts new file mode 100644 index 0000000..eefa204 --- /dev/null +++ b/src/nex/protocols/nat-traversal/methods/index.ts @@ -0,0 +1,7 @@ +export * as RequestProbeInitiation from '@/nex/protocols/nat-traversal/methods/request-probe-initiation'; +export * as InitiateProbe from '@/nex/protocols/nat-traversal/methods/initiate-probe'; +export * as RequestProbeInitiationExt from '@/nex/protocols/nat-traversal/methods/request-probe-initiation-ext'; +export * as ReportNATTraversalResult from '@/nex/protocols/nat-traversal/methods/report-nat-traversal-result'; +export * as ReportNATProperties from '@/nex/protocols/nat-traversal/methods/report-nat-properties'; +export * as GetRelaySignatureKey from '@/nex/protocols/nat-traversal/methods/get-relay-signature-key'; +export * as ReportNATTraversalResultDetail from '@/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail'; \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/initiate-probe.ts b/src/nex/protocols/nat-traversal/methods/initiate-probe.ts new file mode 100644 index 0000000..2dd491a --- /dev/null +++ b/src/nex/protocols/nat-traversal/methods/initiate-probe.ts @@ -0,0 +1,32 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import StationURL from '@/nex/types/station-url'; + +export class Request { + public static Name = 'InitiateProbe'; + + private urlStationToProbe = new StationURL(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.urlStationToProbe.extractFrom(stream); + } + + public toJSON(): Record { + return { + urlStationToProbe: this.urlStationToProbe + }; + } +} + +// * No response data +export class Response { + public static Name = 'InitiateProbe'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts b/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts new file mode 100644 index 0000000..5d566d3 --- /dev/null +++ b/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts @@ -0,0 +1,38 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import UInt32 from '@/nex/types/uint32'; + +export class Request { + public static Name = 'ReportNATProperties'; + + private natmapping = new UInt32(); + private natfiltering = new UInt32(); + private rtt = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.natmapping.extractFrom(stream); + this.natfiltering.extractFrom(stream); + this.rtt.extractFrom(stream); + } + + public toJSON(): Record { + return { + natmapping: this.natmapping, + natfiltering: this.natfiltering, + rtt: this.rtt + }; + } +} + +// * No response data +export class Response { + public static Name = 'ReportNATProperties'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts new file mode 100644 index 0000000..d2e3e11 --- /dev/null +++ b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/int32'; +import Int32 from '@/nex/types/bool'; + +export class Request { + public static Name = 'ReportNATTraversalResultDetail'; + + private cid = new UInt32(); + private result = new Bool(); + private detail = new Int32(); + private rtt = new UInt32(); // * ReportNATTraversalResult does not send this on the 3DS, is that true here too? + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.cid.extractFrom(stream); + this.result.extractFrom(stream); + this.detail.extractFrom(stream); + this.rtt.extractFrom(stream); + } + + public toJSON(): Record { + return { + cid: this.cid, + result: this.result, + detail: this.detail, + rtt: this.rtt + }; + } +} + +// * No response data +export class Response { + public static Name = 'ReportNATTraversalResultDetail'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts new file mode 100644 index 0000000..33319b8 --- /dev/null +++ b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts @@ -0,0 +1,49 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/int32'; + +export class Request { + public static Name = 'ReportNATTraversalResult'; + + private cid = new UInt32(); + private result = new Bool(); + private rtt: UInt32; // * Not seen on the 3DS. NEX version difference? + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.cid.extractFrom(stream); + this.result.extractFrom(stream); + + if (stream.hasDataLeft()) { + this.rtt = new UInt32(); + this.rtt.extractFrom(stream); + } + } + + public toJSON(): Record { + const json: Record = { + cid: this.cid, + result: this.result, + rtt: this.rtt + }; + + if (this.rtt !== undefined) { + json.rtt = this.rtt; + } + + return json; + } +} + +// * No response data +export class Response { + public static Name = 'ReportNATTraversalResult'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts b/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts new file mode 100644 index 0000000..e51730b --- /dev/null +++ b/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts @@ -0,0 +1,36 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; + +export class Request { + public static Name = 'RequestProbeInitiationExt'; + + private urlTargetList = new List(new StationURL()); + private urlStationToProbe = new StationURL(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.urlTargetList.extractFrom(stream); + this.urlStationToProbe.extractFrom(stream); + } + + public toJSON(): Record { + return { + urlTargetList: this.urlTargetList, + urlStationToProbe: this.urlStationToProbe + }; + } +} + +// * No response data +export class Response { + public static Name = 'RequestProbeInitiationExt'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts b/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts new file mode 100644 index 0000000..babccbd --- /dev/null +++ b/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts @@ -0,0 +1,33 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RMCMessage from '@/nex/rmc-message'; +import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; + +export class Request { + public static Name = 'RequestProbeInitiationExt'; + + private urlTargetList = new List(new StationURL()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + + this.urlTargetList.extractFrom(stream); + } + + public toJSON(): Record { + return { + urlTargetList: this.urlTargetList + }; + } +} + +// * No response data +export class Response { + public static Name = 'RequestProbeInitiationExt'; + + constructor() {} + + public toJSON(): Record { + return {}; + } +} \ No newline at end of file From 2293de57b4e0935b3ae7f3824a928708830c57f7 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 15:43:00 -0400 Subject: [PATCH 39/67] refactor: replace RMCMessage with type import in RMC methods --- .../protocols/nat-traversal/methods/get-relay-signature-key.ts | 2 +- src/nex/protocols/nat-traversal/methods/initiate-probe.ts | 2 +- .../protocols/nat-traversal/methods/report-nat-properties.ts | 2 +- .../nat-traversal/methods/report-nat-traversal-result-detail.ts | 2 +- .../nat-traversal/methods/report-nat-traversal-result.ts | 2 +- .../nat-traversal/methods/request-probe-initiation-ext.ts | 2 +- .../protocols/nat-traversal/methods/request-probe-initiation.ts | 2 +- src/nex/protocols/secure-connection/methods/register-ex.ts | 2 +- src/nex/protocols/secure-connection/methods/register.ts | 2 +- src/nex/protocols/secure-connection/methods/replace-url.ts | 2 +- .../secure-connection/methods/request-connection-data.ts | 2 +- src/nex/protocols/secure-connection/methods/request-urls.ts | 2 +- src/nex/protocols/secure-connection/methods/send-report.ts | 2 +- src/nex/protocols/secure-connection/methods/update-urls.ts | 2 +- src/nex/protocols/ticket-granting/methods/login-ex.ts | 2 +- src/nex/protocols/ticket-granting/methods/login.ts | 2 +- src/nex/protocols/ticket-granting/methods/request-ticket.ts | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts b/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts index 33cb5a5..7532b35 100644 --- a/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts +++ b/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts @@ -1,10 +1,10 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import Int32 from '@/nex/types/int32'; import DateTime from '@/nex/types/datetime'; import RVString from '@/nex/types/string'; import UInt16 from '@/nex/types/uint16'; import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; // * No request data export class Request { diff --git a/src/nex/protocols/nat-traversal/methods/initiate-probe.ts b/src/nex/protocols/nat-traversal/methods/initiate-probe.ts index 2dd491a..a5b7d08 100644 --- a/src/nex/protocols/nat-traversal/methods/initiate-probe.ts +++ b/src/nex/protocols/nat-traversal/methods/initiate-probe.ts @@ -1,6 +1,6 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import StationURL from '@/nex/types/station-url'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'InitiateProbe'; diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts b/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts index 5d566d3..d1ef54b 100644 --- a/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts +++ b/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts @@ -1,6 +1,6 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'ReportNATProperties'; diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts index d2e3e11..9ec3f07 100644 --- a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts +++ b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts @@ -1,8 +1,8 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import UInt32 from '@/nex/types/uint32'; import Bool from '@/nex/types/int32'; import Int32 from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'ReportNATTraversalResultDetail'; diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts index 33319b8..56a77e3 100644 --- a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts +++ b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts @@ -1,7 +1,7 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import UInt32 from '@/nex/types/uint32'; import Bool from '@/nex/types/int32'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'ReportNATTraversalResult'; diff --git a/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts b/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts index e51730b..6093114 100644 --- a/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts +++ b/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts @@ -1,7 +1,7 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import List from '@/nex/types/list'; import StationURL from '@/nex/types/station-url'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'RequestProbeInitiationExt'; diff --git a/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts b/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts index babccbd..bf95113 100644 --- a/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts +++ b/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts @@ -1,7 +1,7 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import List from '@/nex/types/list'; import StationURL from '@/nex/types/station-url'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'RequestProbeInitiationExt'; diff --git a/src/nex/protocols/secure-connection/methods/register-ex.ts b/src/nex/protocols/secure-connection/methods/register-ex.ts index 099452a..28c9138 100644 --- a/src/nex/protocols/secure-connection/methods/register-ex.ts +++ b/src/nex/protocols/secure-connection/methods/register-ex.ts @@ -1,10 +1,10 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import StationURL from '@/nex/types/station-url'; import List from '@/nex/types/list'; import AnyDataHolder from '@/nex/types/any-data-holder'; import QResult from '@/nex/types/qresult'; import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { diff --git a/src/nex/protocols/secure-connection/methods/register.ts b/src/nex/protocols/secure-connection/methods/register.ts index f262230..69c070c 100644 --- a/src/nex/protocols/secure-connection/methods/register.ts +++ b/src/nex/protocols/secure-connection/methods/register.ts @@ -1,9 +1,9 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import List from '@/nex/types/list'; import StationURL from '@/nex/types/station-url'; import QResult from '@/nex/types/qresult'; import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'Register'; diff --git a/src/nex/protocols/secure-connection/methods/replace-url.ts b/src/nex/protocols/secure-connection/methods/replace-url.ts index f21d403..3539451 100644 --- a/src/nex/protocols/secure-connection/methods/replace-url.ts +++ b/src/nex/protocols/secure-connection/methods/replace-url.ts @@ -1,6 +1,6 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import StationURL from '@/nex/types/station-url'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'ReplaceURL'; diff --git a/src/nex/protocols/secure-connection/methods/request-connection-data.ts b/src/nex/protocols/secure-connection/methods/request-connection-data.ts index e80e941..7d4b4de 100644 --- a/src/nex/protocols/secure-connection/methods/request-connection-data.ts +++ b/src/nex/protocols/secure-connection/methods/request-connection-data.ts @@ -1,9 +1,9 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import UInt32 from '@/nex/types/uint32'; import Bool from '@/nex/types/bool'; import List from '@/nex/types/list'; import ConnectionData from '@/nex/protocols/secure-connection/types/connection-data'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'RequestConnectionData'; diff --git a/src/nex/protocols/secure-connection/methods/request-urls.ts b/src/nex/protocols/secure-connection/methods/request-urls.ts index 8c7484f..c1987e4 100644 --- a/src/nex/protocols/secure-connection/methods/request-urls.ts +++ b/src/nex/protocols/secure-connection/methods/request-urls.ts @@ -1,9 +1,9 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import UInt32 from '@/nex/types/uint32'; import Bool from '@/nex/types/bool'; import List from '@/nex/types/list'; import StationURL from '@/nex/types/station-url'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'RequestUrls'; diff --git a/src/nex/protocols/secure-connection/methods/send-report.ts b/src/nex/protocols/secure-connection/methods/send-report.ts index e78f593..7543b19 100644 --- a/src/nex/protocols/secure-connection/methods/send-report.ts +++ b/src/nex/protocols/secure-connection/methods/send-report.ts @@ -1,7 +1,7 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import UInt32 from '@/nex/types/uint32'; import QBuffer from '@/nex/types/qbuffer'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'SendReport'; diff --git a/src/nex/protocols/secure-connection/methods/update-urls.ts b/src/nex/protocols/secure-connection/methods/update-urls.ts index 4b6b821..30d81c0 100644 --- a/src/nex/protocols/secure-connection/methods/update-urls.ts +++ b/src/nex/protocols/secure-connection/methods/update-urls.ts @@ -1,7 +1,7 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import List from '@/nex/types/list'; import StationURL from '@/nex/types/station-url'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'UpdateURLs'; diff --git a/src/nex/protocols/ticket-granting/methods/login-ex.ts b/src/nex/protocols/ticket-granting/methods/login-ex.ts index ba73c03..b9f9480 100644 --- a/src/nex/protocols/ticket-granting/methods/login-ex.ts +++ b/src/nex/protocols/ticket-granting/methods/login-ex.ts @@ -1,11 +1,11 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import RVString from '@/nex/types/string'; import AnyDataHolder from '@/nex/types/any-data-holder'; import QResult from '@/nex/types/qresult'; import PID from '@/nex/types/pid'; import RVBuffer from '@/nex/types/buffer'; import RVConnectionData from '@/nex/types/rv-connection-data'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'LoginEx'; diff --git a/src/nex/protocols/ticket-granting/methods/login.ts b/src/nex/protocols/ticket-granting/methods/login.ts index c2b9b54..69c653b 100644 --- a/src/nex/protocols/ticket-granting/methods/login.ts +++ b/src/nex/protocols/ticket-granting/methods/login.ts @@ -1,10 +1,10 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import RVString from '@/nex/types/string'; import QResult from '@/nex/types/qresult'; import PID from '@/nex/types/pid'; import RVBuffer from '@/nex/types/buffer'; import RVConnectionData from '@/nex/types/rv-connection-data'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'Login'; diff --git a/src/nex/protocols/ticket-granting/methods/request-ticket.ts b/src/nex/protocols/ticket-granting/methods/request-ticket.ts index 331bcce..4cf72b6 100644 --- a/src/nex/protocols/ticket-granting/methods/request-ticket.ts +++ b/src/nex/protocols/ticket-granting/methods/request-ticket.ts @@ -1,9 +1,9 @@ import NEXByteStream from '@/nex/byte-stream'; -import RMCMessage from '@/nex/rmc-message'; import PID from '@/nex/types/pid'; import QResult from '@/nex/types/qresult'; import RVBuffer from '@/nex/types/buffer'; import RVString from '@/nex/types/string'; +import type RMCMessage from '@/nex/rmc-message'; export class Request { public static Name = 'RequestTicket'; From f6d3dfd7d144012424ece1d33897c1ea6af5ad1f Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 16:35:13 -0400 Subject: [PATCH 40/67] refactor: strongly type RMCs --- .../methods/get-relay-signature-key.ts | 5 +++-- .../nat-traversal/methods/initiate-probe.ts | 5 +++-- .../methods/report-nat-properties.ts | 5 +++-- .../report-nat-traversal-result-detail.ts | 9 +++++---- .../methods/report-nat-traversal-result.ts | 9 +++++---- .../methods/request-probe-initiation-ext.ts | 5 +++-- .../methods/request-probe-initiation.ts | 5 +++-- .../secure-connection/methods/register-ex.ts | 8 ++++---- .../secure-connection/methods/register.ts | 5 +++-- .../secure-connection/methods/replace-url.ts | 5 +++-- .../methods/request-connection-data.ts | 5 +++-- .../secure-connection/methods/request-urls.ts | 5 +++-- .../secure-connection/methods/send-report.ts | 5 +++-- .../methods/test-connectivity.ts | 5 +++-- .../secure-connection/methods/update-urls.ts | 5 +++-- .../ticket-granting/methods/login-ex.ts | 7 ++++--- .../ticket-granting/methods/login.ts | 7 ++++--- .../ticket-granting/methods/request-ticket.ts | 19 +++++++++++++------ .../nat-traversal/get-relay-signature-key.ts | 16 ++++++++++++++++ .../nex/rmcs/nat-traversal/initiate-probe.ts | 7 +++++++ .../nat-traversal/report-nat-properties.ts | 9 +++++++++ .../report-nat-traversal-result-detail.ts | 12 ++++++++++++ .../report-nat-traversal-result.ts | 10 ++++++++++ .../request-probe-initiation-ext.ts | 9 +++++++++ .../nat-traversal/request-probe-initiation.ts | 8 ++++++++ .../nex/rmcs/secure-connection/register-ex.ts | 16 ++++++++++++++++ .../nex/rmcs/secure-connection/register.ts | 14 ++++++++++++++ .../nex/rmcs/secure-connection/replace-url.ts | 8 ++++++++ .../request-connection-data.ts | 14 ++++++++++++++ .../rmcs/secure-connection/request-urls.ts | 14 ++++++++++++++ .../nex/rmcs/secure-connection/send-report.ts | 9 +++++++++ .../secure-connection/test-connectivity.ts | 3 +++ .../nex/rmcs/secure-connection/update-urls.ts | 8 ++++++++ .../nex/rmcs/ticket-granting/login-ex.ts | 19 +++++++++++++++++++ src/types/nex/rmcs/ticket-granting/login.ts | 17 +++++++++++++++++ .../rmcs/ticket-granting/request-ticket.ts | 15 +++++++++++++++ 36 files changed, 279 insertions(+), 48 deletions(-) create mode 100644 src/types/nex/rmcs/nat-traversal/get-relay-signature-key.ts create mode 100644 src/types/nex/rmcs/nat-traversal/initiate-probe.ts create mode 100644 src/types/nex/rmcs/nat-traversal/report-nat-properties.ts create mode 100644 src/types/nex/rmcs/nat-traversal/report-nat-traversal-result-detail.ts create mode 100644 src/types/nex/rmcs/nat-traversal/report-nat-traversal-result.ts create mode 100644 src/types/nex/rmcs/nat-traversal/request-probe-initiation-ext.ts create mode 100644 src/types/nex/rmcs/nat-traversal/request-probe-initiation.ts create mode 100644 src/types/nex/rmcs/secure-connection/register-ex.ts create mode 100644 src/types/nex/rmcs/secure-connection/register.ts create mode 100644 src/types/nex/rmcs/secure-connection/replace-url.ts create mode 100644 src/types/nex/rmcs/secure-connection/request-connection-data.ts create mode 100644 src/types/nex/rmcs/secure-connection/request-urls.ts create mode 100644 src/types/nex/rmcs/secure-connection/send-report.ts create mode 100644 src/types/nex/rmcs/secure-connection/test-connectivity.ts create mode 100644 src/types/nex/rmcs/secure-connection/update-urls.ts create mode 100644 src/types/nex/rmcs/ticket-granting/login-ex.ts create mode 100644 src/types/nex/rmcs/ticket-granting/login.ts create mode 100644 src/types/nex/rmcs/ticket-granting/request-ticket.ts diff --git a/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts b/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts index 7532b35..317f811 100644 --- a/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts +++ b/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts @@ -5,6 +5,7 @@ import RVString from '@/nex/types/string'; import UInt16 from '@/nex/types/uint16'; import UInt32 from '@/nex/types/uint32'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/nat-traversal/get-relay-signature-key'; // * No request data export class Request { @@ -12,7 +13,7 @@ export class Request { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Request { return {}; } } @@ -38,7 +39,7 @@ export class Response { this.gameServerID.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Response { return { relayMode: this.relayMode, currentUTCTime: this.currentUTCTime, diff --git a/src/nex/protocols/nat-traversal/methods/initiate-probe.ts b/src/nex/protocols/nat-traversal/methods/initiate-probe.ts index a5b7d08..08aad85 100644 --- a/src/nex/protocols/nat-traversal/methods/initiate-probe.ts +++ b/src/nex/protocols/nat-traversal/methods/initiate-probe.ts @@ -1,6 +1,7 @@ import NEXByteStream from '@/nex/byte-stream'; import StationURL from '@/nex/types/station-url'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/nat-traversal/initiate-probe'; export class Request { public static Name = 'InitiateProbe'; @@ -13,7 +14,7 @@ export class Request { this.urlStationToProbe.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { urlStationToProbe: this.urlStationToProbe }; @@ -26,7 +27,7 @@ export class Response { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Response { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts b/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts index d1ef54b..6000d42 100644 --- a/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts +++ b/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts @@ -1,6 +1,7 @@ import NEXByteStream from '@/nex/byte-stream'; import UInt32 from '@/nex/types/uint32'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/nat-traversal/report-nat-properties'; export class Request { public static Name = 'ReportNATProperties'; @@ -17,7 +18,7 @@ export class Request { this.rtt.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { natmapping: this.natmapping, natfiltering: this.natfiltering, @@ -32,7 +33,7 @@ export class Response { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Response { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts index 9ec3f07..3c4144c 100644 --- a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts +++ b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts @@ -1,8 +1,9 @@ import NEXByteStream from '@/nex/byte-stream'; import UInt32 from '@/nex/types/uint32'; -import Bool from '@/nex/types/int32'; -import Int32 from '@/nex/types/bool'; +import Bool from '@/nex/types/bool'; +import Int32 from '@/nex/types/int32'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/nat-traversal/report-nat-traversal-result-detail'; export class Request { public static Name = 'ReportNATTraversalResultDetail'; @@ -21,7 +22,7 @@ export class Request { this.rtt.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { cid: this.cid, result: this.result, @@ -37,7 +38,7 @@ export class Response { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Response { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts index 56a77e3..f27565c 100644 --- a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts +++ b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts @@ -1,7 +1,8 @@ import NEXByteStream from '@/nex/byte-stream'; import UInt32 from '@/nex/types/uint32'; -import Bool from '@/nex/types/int32'; +import Bool from '@/nex/types/bool'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/nat-traversal/report-nat-traversal-result'; export class Request { public static Name = 'ReportNATTraversalResult'; @@ -22,8 +23,8 @@ export class Request { } } - public toJSON(): Record { - const json: Record = { + public toJSON(): RMCs.Request { + const json: RMCs.Request = { cid: this.cid, result: this.result, rtt: this.rtt @@ -43,7 +44,7 @@ export class Response { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Response { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts b/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts index 6093114..079067d 100644 --- a/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts +++ b/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts @@ -2,6 +2,7 @@ import NEXByteStream from '@/nex/byte-stream'; import List from '@/nex/types/list'; import StationURL from '@/nex/types/station-url'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/nat-traversal/request-probe-initiation-ext'; export class Request { public static Name = 'RequestProbeInitiationExt'; @@ -16,7 +17,7 @@ export class Request { this.urlStationToProbe.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { urlTargetList: this.urlTargetList, urlStationToProbe: this.urlStationToProbe @@ -30,7 +31,7 @@ export class Response { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Response { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts b/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts index bf95113..0169afe 100644 --- a/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts +++ b/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts @@ -2,6 +2,7 @@ import NEXByteStream from '@/nex/byte-stream'; import List from '@/nex/types/list'; import StationURL from '@/nex/types/station-url'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/nat-traversal/request-probe-initiation'; export class Request { public static Name = 'RequestProbeInitiationExt'; @@ -14,7 +15,7 @@ export class Request { this.urlTargetList.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { urlTargetList: this.urlTargetList }; @@ -27,7 +28,7 @@ export class Response { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Response { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/register-ex.ts b/src/nex/protocols/secure-connection/methods/register-ex.ts index 28c9138..2a8fae4 100644 --- a/src/nex/protocols/secure-connection/methods/register-ex.ts +++ b/src/nex/protocols/secure-connection/methods/register-ex.ts @@ -1,11 +1,11 @@ import NEXByteStream from '@/nex/byte-stream'; -import StationURL from '@/nex/types/station-url'; import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; import AnyDataHolder from '@/nex/types/any-data-holder'; import QResult from '@/nex/types/qresult'; import UInt32 from '@/nex/types/uint32'; import type RMCMessage from '@/nex/rmc-message'; - +import type * as RMCs from '@/types/nex/rmcs/secure-connection/register-ex'; export class Request { public static Name = 'RegisterEx'; @@ -20,7 +20,7 @@ export class Request { this.hCustomData.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { vecMyURLs: this.vecMyURLs, hCustomData: this.hCustomData @@ -47,7 +47,7 @@ export class Response { } } - public toJSON(): Record { + public toJSON(): RMCs.Response { return { retval: this.retval, pidConnectionID: this.pidConnectionID, diff --git a/src/nex/protocols/secure-connection/methods/register.ts b/src/nex/protocols/secure-connection/methods/register.ts index 69c070c..07ea9ea 100644 --- a/src/nex/protocols/secure-connection/methods/register.ts +++ b/src/nex/protocols/secure-connection/methods/register.ts @@ -4,6 +4,7 @@ import StationURL from '@/nex/types/station-url'; import QResult from '@/nex/types/qresult'; import UInt32 from '@/nex/types/uint32'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/secure-connection/register'; export class Request { public static Name = 'Register'; @@ -16,7 +17,7 @@ export class Request { this.vecMyURLs.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { vecMyURLs: this.vecMyURLs }; @@ -42,7 +43,7 @@ export class Response { } } - public toJSON(): Record { + public toJSON(): RMCs.Response { return { retval: this.retval, pidConnectionID: this.pidConnectionID, diff --git a/src/nex/protocols/secure-connection/methods/replace-url.ts b/src/nex/protocols/secure-connection/methods/replace-url.ts index 3539451..17a4bf7 100644 --- a/src/nex/protocols/secure-connection/methods/replace-url.ts +++ b/src/nex/protocols/secure-connection/methods/replace-url.ts @@ -1,6 +1,7 @@ import NEXByteStream from '@/nex/byte-stream'; import StationURL from '@/nex/types/station-url'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/secure-connection/replace-url'; export class Request { public static Name = 'ReplaceURL'; @@ -15,7 +16,7 @@ export class Request { this.url.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { target: this.target, url: this.url @@ -29,7 +30,7 @@ export class Response { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Response { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/request-connection-data.ts b/src/nex/protocols/secure-connection/methods/request-connection-data.ts index 7d4b4de..ba1bb40 100644 --- a/src/nex/protocols/secure-connection/methods/request-connection-data.ts +++ b/src/nex/protocols/secure-connection/methods/request-connection-data.ts @@ -4,6 +4,7 @@ import Bool from '@/nex/types/bool'; import List from '@/nex/types/list'; import ConnectionData from '@/nex/protocols/secure-connection/types/connection-data'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/secure-connection/request-connection-data'; export class Request { public static Name = 'RequestConnectionData'; @@ -18,7 +19,7 @@ export class Request { this.pidTarget.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { cidTarget: this.cidTarget, pidTarget: this.pidTarget @@ -39,7 +40,7 @@ export class Response { this.pvecConnectionsData.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Response { return { retval: this.retval, pvecConnectionsData: this.pvecConnectionsData diff --git a/src/nex/protocols/secure-connection/methods/request-urls.ts b/src/nex/protocols/secure-connection/methods/request-urls.ts index c1987e4..ebb15b2 100644 --- a/src/nex/protocols/secure-connection/methods/request-urls.ts +++ b/src/nex/protocols/secure-connection/methods/request-urls.ts @@ -4,6 +4,7 @@ import Bool from '@/nex/types/bool'; import List from '@/nex/types/list'; import StationURL from '@/nex/types/station-url'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/secure-connection/request-urls'; export class Request { public static Name = 'RequestUrls'; @@ -18,7 +19,7 @@ export class Request { this.pidTarget.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { cidTarget: this.cidTarget, pidTarget: this.pidTarget @@ -39,7 +40,7 @@ export class Response { this.plstURLs.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Response { return { retval: this.retval, plstURLs: this.plstURLs diff --git a/src/nex/protocols/secure-connection/methods/send-report.ts b/src/nex/protocols/secure-connection/methods/send-report.ts index 7543b19..0d92c20 100644 --- a/src/nex/protocols/secure-connection/methods/send-report.ts +++ b/src/nex/protocols/secure-connection/methods/send-report.ts @@ -2,6 +2,7 @@ import NEXByteStream from '@/nex/byte-stream'; import UInt32 from '@/nex/types/uint32'; import QBuffer from '@/nex/types/qbuffer'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/secure-connection/send-report'; export class Request { public static Name = 'SendReport'; @@ -16,7 +17,7 @@ export class Request { this.reportData.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { reportId: this.reportId, reportData: this.reportData @@ -30,7 +31,7 @@ export class Response { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Response { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/test-connectivity.ts b/src/nex/protocols/secure-connection/methods/test-connectivity.ts index 95b5554..7d84754 100644 --- a/src/nex/protocols/secure-connection/methods/test-connectivity.ts +++ b/src/nex/protocols/secure-connection/methods/test-connectivity.ts @@ -1,3 +1,4 @@ +import type * as RMCs from '@/types/nex/rmcs/secure-connection/test-connectivity'; // * No request data export class Request { @@ -5,7 +6,7 @@ export class Request { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Request { return {}; } } @@ -16,7 +17,7 @@ export class Response { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Response { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/update-urls.ts b/src/nex/protocols/secure-connection/methods/update-urls.ts index 30d81c0..4c6bc31 100644 --- a/src/nex/protocols/secure-connection/methods/update-urls.ts +++ b/src/nex/protocols/secure-connection/methods/update-urls.ts @@ -2,6 +2,7 @@ import NEXByteStream from '@/nex/byte-stream'; import List from '@/nex/types/list'; import StationURL from '@/nex/types/station-url'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/secure-connection/update-urls'; export class Request { public static Name = 'UpdateURLs'; @@ -14,7 +15,7 @@ export class Request { this.vecMyURLs.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { vecMyURLs: this.vecMyURLs }; @@ -27,7 +28,7 @@ export class Response { constructor() {} - public toJSON(): Record { + public toJSON(): RMCs.Response { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/login-ex.ts b/src/nex/protocols/ticket-granting/methods/login-ex.ts index b9f9480..07a7b6a 100644 --- a/src/nex/protocols/ticket-granting/methods/login-ex.ts +++ b/src/nex/protocols/ticket-granting/methods/login-ex.ts @@ -6,6 +6,7 @@ import PID from '@/nex/types/pid'; import RVBuffer from '@/nex/types/buffer'; import RVConnectionData from '@/nex/types/rv-connection-data'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/ticket-granting/login-ex'; export class Request { public static Name = 'LoginEx'; @@ -20,7 +21,7 @@ export class Request { this.oExtraData.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { strUserName: this.strUserName, oExtraData: this.oExtraData @@ -53,13 +54,13 @@ export class Response { } } - public toJSON(): Record { + public toJSON(): RMCs.Response { return { retval: this.retval, pidPrincipal: this.pidPrincipal, pbufResponse: this.pbufResponse, pConnectionData: this.pConnectionData, - strReturnMsg: this.strReturnMsg.value + strReturnMsg: this.strReturnMsg }; } } \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/login.ts b/src/nex/protocols/ticket-granting/methods/login.ts index 69c653b..70fb0c2 100644 --- a/src/nex/protocols/ticket-granting/methods/login.ts +++ b/src/nex/protocols/ticket-granting/methods/login.ts @@ -5,6 +5,7 @@ import PID from '@/nex/types/pid'; import RVBuffer from '@/nex/types/buffer'; import RVConnectionData from '@/nex/types/rv-connection-data'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/ticket-granting/login'; export class Request { public static Name = 'Login'; @@ -17,7 +18,7 @@ export class Request { this.strUserName.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { strUserName: this.strUserName }; @@ -49,13 +50,13 @@ export class Response { } } - public toJSON(): Record { + public toJSON(): RMCs.Response { return { retval: this.retval, pidPrincipal: this.pidPrincipal, pbufResponse: this.pbufResponse, pConnectionData: this.pConnectionData, - strReturnMsg: this.strReturnMsg.value + strReturnMsg: this.strReturnMsg }; } } \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/request-ticket.ts b/src/nex/protocols/ticket-granting/methods/request-ticket.ts index 4cf72b6..0c07e3c 100644 --- a/src/nex/protocols/ticket-granting/methods/request-ticket.ts +++ b/src/nex/protocols/ticket-granting/methods/request-ticket.ts @@ -4,6 +4,7 @@ import QResult from '@/nex/types/qresult'; import RVBuffer from '@/nex/types/buffer'; import RVString from '@/nex/types/string'; import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/ticket-granting/request-ticket'; export class Request { public static Name = 'RequestTicket'; @@ -18,7 +19,7 @@ export class Request { this.idTarget.extractFrom(stream); } - public toJSON(): Record { + public toJSON(): RMCs.Request { return { idSource: this.idSource, idTarget: this.idTarget @@ -31,7 +32,7 @@ export class Response { private retval = new QResult(); private bufResponse = new RVBuffer(); - private pSourceKey = new RVString(); + private pSourceKey: RVString; constructor(message: RMCMessage) { const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); @@ -47,16 +48,22 @@ export class Response { // * Only on the Switch // TODO - Is this a good enough check? if (stream.hasDataLeft()) { + this.pSourceKey = new RVString(); this.pSourceKey.extractFrom(stream); } } } - public toJSON(): Record { - return { + public toJSON(): RMCs.Response { + const json: RMCs.Response = { retval: this.retval, - bufResponse: this.bufResponse, - pSourceKey: this.pSourceKey.value + bufResponse: this.bufResponse }; + + if (this.pSourceKey !== undefined) { + json.pSourceKey = this.pSourceKey; + } + + return json; } } \ No newline at end of file diff --git a/src/types/nex/rmcs/nat-traversal/get-relay-signature-key.ts b/src/types/nex/rmcs/nat-traversal/get-relay-signature-key.ts new file mode 100644 index 0000000..bf252d3 --- /dev/null +++ b/src/types/nex/rmcs/nat-traversal/get-relay-signature-key.ts @@ -0,0 +1,16 @@ +import type Int32 from '@/nex/types/int32'; +import type DateTime from '@/nex/types/datetime'; +import type RVString from '@/nex/types/string'; +import type UInt16 from '@/nex/types/uint16'; +import type UInt32 from '@/nex/types/uint32'; + +export type Request = object; // * No request data + +export type Response = { + relayMode: Int32; + currentUTCTime: DateTime; + address: RVString; + port: UInt16; + relayAddressType: Int32; + gameServerID: UInt32; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/nat-traversal/initiate-probe.ts b/src/types/nex/rmcs/nat-traversal/initiate-probe.ts new file mode 100644 index 0000000..fa01d32 --- /dev/null +++ b/src/types/nex/rmcs/nat-traversal/initiate-probe.ts @@ -0,0 +1,7 @@ +import type StationURL from '@/nex/types/station-url'; + +export type Request = { + urlStationToProbe: StationURL; +}; + +export type Response = object; // * No response data \ No newline at end of file diff --git a/src/types/nex/rmcs/nat-traversal/report-nat-properties.ts b/src/types/nex/rmcs/nat-traversal/report-nat-properties.ts new file mode 100644 index 0000000..0c88508 --- /dev/null +++ b/src/types/nex/rmcs/nat-traversal/report-nat-properties.ts @@ -0,0 +1,9 @@ +import type UInt32 from '@/nex/types/uint32'; + +export type Request = { + natmapping: UInt32; + natfiltering: UInt32; + rtt: UInt32; +}; + +export type Response = object; // * No response data \ No newline at end of file diff --git a/src/types/nex/rmcs/nat-traversal/report-nat-traversal-result-detail.ts b/src/types/nex/rmcs/nat-traversal/report-nat-traversal-result-detail.ts new file mode 100644 index 0000000..f18babb --- /dev/null +++ b/src/types/nex/rmcs/nat-traversal/report-nat-traversal-result-detail.ts @@ -0,0 +1,12 @@ +import type UInt32 from '@/nex/types/uint32'; +import type Bool from '@/nex/types/bool'; +import type Int32 from '@/nex/types/int32'; + +export type Request = { + cid: UInt32; + result: Bool; + detail: Int32; + rtt: UInt32; // * ReportNATTraversalResult does not send this on the 3DS, is that true here too? +}; + +export type Response = object; // * No response data \ No newline at end of file diff --git a/src/types/nex/rmcs/nat-traversal/report-nat-traversal-result.ts b/src/types/nex/rmcs/nat-traversal/report-nat-traversal-result.ts new file mode 100644 index 0000000..9d51a99 --- /dev/null +++ b/src/types/nex/rmcs/nat-traversal/report-nat-traversal-result.ts @@ -0,0 +1,10 @@ +import type UInt32 from '@/nex/types/uint32'; +import type Bool from '@/nex/types/bool'; + +export type Request = { + cid: UInt32; + result: Bool; + rtt?: UInt32; // * Not seen on the 3DS. NEX version difference? +}; + +export type Response = object; // * No response data \ No newline at end of file diff --git a/src/types/nex/rmcs/nat-traversal/request-probe-initiation-ext.ts b/src/types/nex/rmcs/nat-traversal/request-probe-initiation-ext.ts new file mode 100644 index 0000000..c5ae9f5 --- /dev/null +++ b/src/types/nex/rmcs/nat-traversal/request-probe-initiation-ext.ts @@ -0,0 +1,9 @@ +import type List from '@/nex/types/list'; +import type StationURL from '@/nex/types/station-url'; + +export type Request = { + urlTargetList: List; + urlStationToProbe: StationURL; +}; + +export type Response = object; // * No response data \ No newline at end of file diff --git a/src/types/nex/rmcs/nat-traversal/request-probe-initiation.ts b/src/types/nex/rmcs/nat-traversal/request-probe-initiation.ts new file mode 100644 index 0000000..5b212be --- /dev/null +++ b/src/types/nex/rmcs/nat-traversal/request-probe-initiation.ts @@ -0,0 +1,8 @@ +import type List from '@/nex/types/list'; +import type StationURL from '@/nex/types/station-url'; + +export type Request = { + urlTargetList: List; +}; + +export type Response = object; // * No response data \ No newline at end of file diff --git a/src/types/nex/rmcs/secure-connection/register-ex.ts b/src/types/nex/rmcs/secure-connection/register-ex.ts new file mode 100644 index 0000000..14e7cd1 --- /dev/null +++ b/src/types/nex/rmcs/secure-connection/register-ex.ts @@ -0,0 +1,16 @@ +import type List from '@/nex/types/list'; +import type StationURL from '@/nex/types/station-url'; +import type AnyDataHolder from '@/nex/types/any-data-holder'; +import type QResult from '@/nex/types/qresult'; +import type UInt32 from '@/nex/types/uint32'; + +export type Request = { + vecMyURLs: List; + hCustomData: AnyDataHolder; +}; + +export type Response = { + retval: QResult; + pidConnectionID: UInt32; + urlPublic: StationURL; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/secure-connection/register.ts b/src/types/nex/rmcs/secure-connection/register.ts new file mode 100644 index 0000000..2282a52 --- /dev/null +++ b/src/types/nex/rmcs/secure-connection/register.ts @@ -0,0 +1,14 @@ +import type List from '@/nex/types/list'; +import type StationURL from '@/nex/types/station-url'; +import type QResult from '@/nex/types/qresult'; +import type UInt32 from '@/nex/types/uint32'; + +export type Request = { + vecMyURLs: List; +}; + +export type Response = { + retval: QResult; + pidConnectionID: UInt32; + urlPublic: StationURL; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/secure-connection/replace-url.ts b/src/types/nex/rmcs/secure-connection/replace-url.ts new file mode 100644 index 0000000..aaf7a87 --- /dev/null +++ b/src/types/nex/rmcs/secure-connection/replace-url.ts @@ -0,0 +1,8 @@ +import type StationURL from '@/nex/types/station-url'; + +export type Request = { + target: StationURL; + url: StationURL; +}; + +export type Response = object; // * No response data \ No newline at end of file diff --git a/src/types/nex/rmcs/secure-connection/request-connection-data.ts b/src/types/nex/rmcs/secure-connection/request-connection-data.ts new file mode 100644 index 0000000..76c95fa --- /dev/null +++ b/src/types/nex/rmcs/secure-connection/request-connection-data.ts @@ -0,0 +1,14 @@ +import type UInt32 from '@/nex/types/uint32'; +import type Bool from '@/nex/types/bool'; +import type List from '@/nex/types/list'; +import type ConnectionData from '@/nex/protocols/secure-connection/types/connection-data'; + +export type Request = { + cidTarget: UInt32; + pidTarget: UInt32; +}; + +export type Response = { + retval: Bool; + pvecConnectionsData: List; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/secure-connection/request-urls.ts b/src/types/nex/rmcs/secure-connection/request-urls.ts new file mode 100644 index 0000000..57a747e --- /dev/null +++ b/src/types/nex/rmcs/secure-connection/request-urls.ts @@ -0,0 +1,14 @@ +import type UInt32 from '@/nex/types/uint32'; +import type Bool from '@/nex/types/bool'; +import type List from '@/nex/types/list'; +import type StationURL from '@/nex/types/station-url'; + +export type Request = { + cidTarget: UInt32; + pidTarget: UInt32; +}; + +export type Response = { + retval: Bool; + plstURLs: List; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/secure-connection/send-report.ts b/src/types/nex/rmcs/secure-connection/send-report.ts new file mode 100644 index 0000000..0bf5f3f --- /dev/null +++ b/src/types/nex/rmcs/secure-connection/send-report.ts @@ -0,0 +1,9 @@ +import type UInt32 from '@/nex/types/uint32'; +import type QBuffer from '@/nex/types/qbuffer'; + +export type Request = { + reportId: UInt32; + reportData: QBuffer; +}; + +export type Response = object; // * No response data \ No newline at end of file diff --git a/src/types/nex/rmcs/secure-connection/test-connectivity.ts b/src/types/nex/rmcs/secure-connection/test-connectivity.ts new file mode 100644 index 0000000..493e795 --- /dev/null +++ b/src/types/nex/rmcs/secure-connection/test-connectivity.ts @@ -0,0 +1,3 @@ +export type Request = object; // * No request data + +export type Response = object; // * No response data \ No newline at end of file diff --git a/src/types/nex/rmcs/secure-connection/update-urls.ts b/src/types/nex/rmcs/secure-connection/update-urls.ts new file mode 100644 index 0000000..8d2b67f --- /dev/null +++ b/src/types/nex/rmcs/secure-connection/update-urls.ts @@ -0,0 +1,8 @@ +import type List from '@/nex/types/list'; +import type StationURL from '@/nex/types/station-url'; + +export type Request = { + vecMyURLs: List +}; + +export type Response = object; // * No response data \ No newline at end of file diff --git a/src/types/nex/rmcs/ticket-granting/login-ex.ts b/src/types/nex/rmcs/ticket-granting/login-ex.ts new file mode 100644 index 0000000..cb4300d --- /dev/null +++ b/src/types/nex/rmcs/ticket-granting/login-ex.ts @@ -0,0 +1,19 @@ +import type RVString from '@/nex/types/string'; +import type AnyDataHolder from '@/nex/types/any-data-holder'; +import type QResult from '@/nex/types/qresult'; +import type PID from '@/nex/types/pid'; +import type RVBuffer from '@/nex/types/buffer'; +import type RVConnectionData from '@/nex/types/rv-connection-data'; + +export type Request = { + strUserName: RVString; + oExtraData: AnyDataHolder; +}; + +export type Response = { + retval: QResult; + pidPrincipal: PID; + pbufResponse: RVBuffer; + pConnectionData: RVConnectionData; + strReturnMsg: RVString; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/ticket-granting/login.ts b/src/types/nex/rmcs/ticket-granting/login.ts new file mode 100644 index 0000000..b995f59 --- /dev/null +++ b/src/types/nex/rmcs/ticket-granting/login.ts @@ -0,0 +1,17 @@ +import type RVString from '@/nex/types/string'; +import type QResult from '@/nex/types/qresult'; +import type PID from '@/nex/types/pid'; +import type RVBuffer from '@/nex/types/buffer'; +import type RVConnectionData from '@/nex/types/rv-connection-data'; + +export type Request = { + strUserName: RVString; +}; + +export type Response = { + retval: QResult; + pidPrincipal: PID; + pbufResponse: RVBuffer; + pConnectionData: RVConnectionData; + strReturnMsg: RVString; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/ticket-granting/request-ticket.ts b/src/types/nex/rmcs/ticket-granting/request-ticket.ts new file mode 100644 index 0000000..ec98f45 --- /dev/null +++ b/src/types/nex/rmcs/ticket-granting/request-ticket.ts @@ -0,0 +1,15 @@ +import type RVString from '@/nex/types/string'; +import type QResult from '@/nex/types/qresult'; +import type PID from '@/nex/types/pid'; +import type RVBuffer from '@/nex/types/buffer'; + +export type Request = { + idSource: PID; + idTarget: PID; +}; + +export type Response = { + retval: QResult; + bufResponse: RVBuffer; + pSourceKey?: RVString; // * Only on the Switch +}; \ No newline at end of file From af610ee19314741ebbc87b8989c936c32010b1a5 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 16:49:11 -0400 Subject: [PATCH 41/67] fix: fix pSourceKey value check in connection --- src/nex/connection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nex/connection.ts b/src/nex/connection.ts index 6950d9f..a955516 100644 --- a/src/nex/connection.ts +++ b/src/nex/connection.ts @@ -245,7 +245,7 @@ export default class Connection { if (this.ticketRequestPIDs[packet.message.callID]) { const sourcePID = this.ticketRequestPIDs[packet.message.callID]; const ticketData = packet.message.parameters.bufResponse.value; - const sourceKey = packet.message.parameters.pSourceKey.value ? packet.message.parameters.pSourceKey.value : ''; + const sourceKey = packet.message.parameters.pSourceKey?.value ? packet.message.parameters.pSourceKey.value : ''; delete this.ticketRequestPIDs[packet.message.callID]; From a3a8fb5a945ee05c3032d08568786b9170eebeef Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 16:54:03 -0400 Subject: [PATCH 42/67] chore: remove incorrect comments from SecureConnection and NAT Traversal --- src/nex/protocols/nat-traversal/index.ts | 2 -- src/nex/protocols/secure-connection/index.ts | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/nex/protocols/nat-traversal/index.ts b/src/nex/protocols/nat-traversal/index.ts index daf6c5b..63b66a1 100644 --- a/src/nex/protocols/nat-traversal/index.ts +++ b/src/nex/protocols/nat-traversal/index.ts @@ -33,8 +33,6 @@ export default class NATTraversalProtocol { } const methodID = packet.message.methodID; - - // TODO - Use Switch names when parsing Switch packets const handler = NATTraversalProtocol.handlers[methodID]; if (!handler) { diff --git a/src/nex/protocols/secure-connection/index.ts b/src/nex/protocols/secure-connection/index.ts index a09f481..030e39b 100644 --- a/src/nex/protocols/secure-connection/index.ts +++ b/src/nex/protocols/secure-connection/index.ts @@ -35,8 +35,6 @@ export default class SecureConnectionProtocol { } const methodID = packet.message.methodID; - - // TODO - Use Switch names when parsing Switch packets const handler = SecureConnectionProtocol.handlers[methodID]; if (!handler) { From 92f3d2c9022cd434f9ee1fe247fdf2a810a5b840 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 17:28:55 -0400 Subject: [PATCH 43/67] feat: implement all of NotificationEvents --- package-lock.json | 6 ++ package.json | 1 + src/nex/byte-stream.ts | 8 +-- src/nex/connection.ts | 2 +- src/nex/kerberos.ts | 8 +-- src/nex/protocols/manager.ts | 10 ++-- .../methods/get-relay-signature-key.ts | 2 +- .../nat-traversal/methods/initiate-probe.ts | 2 +- .../methods/report-nat-properties.ts | 2 +- .../report-nat-traversal-result-detail.ts | 2 +- .../methods/report-nat-traversal-result.ts | 2 +- .../methods/request-probe-initiation-ext.ts | 2 +- .../methods/request-probe-initiation.ts | 2 +- .../protocols/notification-events/index.ts | 44 ++++++++++++++ .../notification-events/methods/index.ts | 1 + .../methods/process-notification-event.ts | 33 ++++++++++ .../types/notification-event.ts | 60 +++++++++++++++++++ .../secure-connection/methods/register-ex.ts | 4 +- .../secure-connection/methods/register.ts | 4 +- .../secure-connection/methods/replace-url.ts | 2 +- .../methods/request-connection-data.ts | 4 +- .../secure-connection/methods/request-urls.ts | 4 +- .../secure-connection/methods/send-report.ts | 2 +- .../secure-connection/methods/update-urls.ts | 2 +- .../ticket-granting/methods/login-ex.ts | 4 +- .../ticket-granting/methods/login.ts | 4 +- .../ticket-granting/methods/request-ticket.ts | 4 +- src/nex/types/any-data-holder.ts | 2 +- src/nex/types/pid.ts | 4 +- src/nex/types/string.ts | 2 +- src/nex/types/structure.ts | 2 +- .../process-notification-event.ts | 7 +++ 32 files changed, 196 insertions(+), 42 deletions(-) create mode 100644 src/nex/protocols/notification-events/index.ts create mode 100644 src/nex/protocols/notification-events/methods/index.ts create mode 100644 src/nex/protocols/notification-events/methods/process-notification-event.ts create mode 100644 src/nex/protocols/notification-events/types/notification-event.ts create mode 100644 src/types/nex/rmcs/notification-events/process-notification-event.ts diff --git a/package-lock.json b/package-lock.json index 98242c1..0da5db4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "AGPL-3.0", "dependencies": { "@pretendonetwork/yeah": "^1.0.0", + "compare-versions": "^6.1.1", "fs-extra": "^11.2.0", "semver": "^7.6.0", "source-map-support": "^0.5.21" @@ -1438,6 +1439,11 @@ "node": "^12.20.0 || >=14" } }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", diff --git a/package.json b/package.json index ea1849e..b6bd191 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ }, "dependencies": { "@pretendonetwork/yeah": "^1.0.0", + "compare-versions": "^6.1.1", "fs-extra": "^11.2.0", "semver": "^7.6.0", "source-map-support": "^0.5.21" diff --git a/src/nex/byte-stream.ts b/src/nex/byte-stream.ts index f696c96..d064e69 100644 --- a/src/nex/byte-stream.ts +++ b/src/nex/byte-stream.ts @@ -1,12 +1,12 @@ import ByteStream from '@/byte-stream'; -import type NEXByteStreamSettings from '@/types/nex/byte-stream-settings'; +import type { Title } from '@/types/nex/serialized-connection'; export default class NEXByteStream extends ByteStream { - public settings: NEXByteStreamSettings; + public title: Title; - constructor(buffer: Buffer, settings: NEXByteStreamSettings) { + constructor(buffer: Buffer, title: Title) { super(buffer); - this.settings = settings; + this.title = title; } } \ No newline at end of file diff --git a/src/nex/connection.ts b/src/nex/connection.ts index a955516..caad54e 100644 --- a/src/nex/connection.ts +++ b/src/nex/connection.ts @@ -288,7 +288,7 @@ export default class Connection { settings.save(); } - const ticket = new Ticket(ticketData, key, this.title.settings); + const ticket = new Ticket(ticketData, key, this.title); // TODO - Is this accurate to how special stations are handled? const mainTarget = BigInt(this.mainSecureStation.getParam('PID') || 0); diff --git a/src/nex/kerberos.ts b/src/nex/kerberos.ts index c428412..543d986 100644 --- a/src/nex/kerberos.ts +++ b/src/nex/kerberos.ts @@ -3,7 +3,7 @@ import RC4Stream from '@/rc4'; import NEXByteStream from '@/nex/byte-stream'; import PID from '@/nex/types/pid'; import RVBuffer from '@/nex/types/buffer'; -import type NEXByteStreamSettings from '@/types/nex/byte-stream-settings'; +import type { Title } from '@/types/nex/serialized-connection'; // * Only define the client ticket, since we can never decrypt the server ticket export class Ticket { @@ -12,12 +12,12 @@ export class Ticket { private internal = new RVBuffer(); // TODO - Is this useful to expose? - constructor(data: Buffer, key: Buffer, settings: NEXByteStreamSettings) { + constructor(data: Buffer, key: Buffer, title: Title) { const decrypted = decrypt(data, key); - const stream = new NEXByteStream(decrypted, settings); + const stream = new NEXByteStream(decrypted, title); - this.sessionKey = stream.read(settings.session_key_size); + this.sessionKey = stream.read(title.settings.session_key_size); this.target.extractFrom(stream); this.internal.extractFrom(stream); } diff --git a/src/nex/protocols/manager.ts b/src/nex/protocols/manager.ts index a22334a..52a806c 100644 --- a/src/nex/protocols/manager.ts +++ b/src/nex/protocols/manager.ts @@ -1,7 +1,8 @@ -import RMCMessage from '@/nex/rmc-message'; import NATTraversalProtocol from '@/nex/protocols/nat-traversal'; import TicketGrantingProtocol from '@/nex/protocols/ticket-granting'; import SecureConnectionProtocol from '@/nex/protocols/secure-connection'; +import NotificationEventsProtocol from '@/nex/protocols/notification-events'; +import type RMCMessage from '@/nex/rmc-message'; import type ServiceProtocol from '@/types/nex/service-protocol'; export default function getProtocol(message: RMCMessage): ServiceProtocol | null { @@ -14,8 +15,9 @@ export default function getProtocol(message: RMCMessage): ServiceProtocol | null return TicketGrantingProtocol; case SecureConnectionProtocol.ID: return SecureConnectionProtocol; - - default: - return null; + case NotificationEventsProtocol.ID: + return NotificationEventsProtocol; } + + return null; } \ No newline at end of file diff --git a/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts b/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts index 317f811..31564c5 100644 --- a/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts +++ b/src/nex/protocols/nat-traversal/methods/get-relay-signature-key.ts @@ -29,7 +29,7 @@ export class Response { private gameServerID = new UInt32(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.relayMode.extractFrom(stream); this.currentUTCTime.extractFrom(stream); diff --git a/src/nex/protocols/nat-traversal/methods/initiate-probe.ts b/src/nex/protocols/nat-traversal/methods/initiate-probe.ts index 08aad85..a419058 100644 --- a/src/nex/protocols/nat-traversal/methods/initiate-probe.ts +++ b/src/nex/protocols/nat-traversal/methods/initiate-probe.ts @@ -9,7 +9,7 @@ export class Request { private urlStationToProbe = new StationURL(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.urlStationToProbe.extractFrom(stream); } diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts b/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts index 6000d42..87326cf 100644 --- a/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts +++ b/src/nex/protocols/nat-traversal/methods/report-nat-properties.ts @@ -11,7 +11,7 @@ export class Request { private rtt = new UInt32(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.natmapping.extractFrom(stream); this.natfiltering.extractFrom(stream); diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts index 3c4144c..c6c2cf4 100644 --- a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts +++ b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result-detail.ts @@ -14,7 +14,7 @@ export class Request { private rtt = new UInt32(); // * ReportNATTraversalResult does not send this on the 3DS, is that true here too? constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.cid.extractFrom(stream); this.result.extractFrom(stream); diff --git a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts index f27565c..ce83198 100644 --- a/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts +++ b/src/nex/protocols/nat-traversal/methods/report-nat-traversal-result.ts @@ -12,7 +12,7 @@ export class Request { private rtt: UInt32; // * Not seen on the 3DS. NEX version difference? constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.cid.extractFrom(stream); this.result.extractFrom(stream); diff --git a/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts b/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts index 079067d..735e7bd 100644 --- a/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts +++ b/src/nex/protocols/nat-traversal/methods/request-probe-initiation-ext.ts @@ -11,7 +11,7 @@ export class Request { private urlStationToProbe = new StationURL(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.urlTargetList.extractFrom(stream); this.urlStationToProbe.extractFrom(stream); diff --git a/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts b/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts index 0169afe..3def4c1 100644 --- a/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts +++ b/src/nex/protocols/nat-traversal/methods/request-probe-initiation.ts @@ -10,7 +10,7 @@ export class Request { private urlTargetList = new List(new StationURL()); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.urlTargetList.extractFrom(stream); } diff --git a/src/nex/protocols/notification-events/index.ts b/src/nex/protocols/notification-events/index.ts new file mode 100644 index 0000000..f1f214a --- /dev/null +++ b/src/nex/protocols/notification-events/index.ts @@ -0,0 +1,44 @@ +import RMCMessage from '@/nex/rmc-message'; +import * as Methods from '@/nex/protocols/notification-events/methods'; +import type Packet from '@/types/nex/packet'; + +export default class NotificationEventsProtocol { + static ID = 0xE; + static Name = 'NotificationEvents'; + + static Methods = { + ProcessNotificationEvent: 0x1 + }; + + private static handlers: Record any> = { + 0x1: NotificationEventsProtocol.ProcessNotificationEvent + }; + + static handlePacket(packet: Packet): void { + if (!packet.message) { + // * This will never happen. Only checked to make TypeScript happy + return; + } + + const methodID = packet.message.methodID; + const handler = NotificationEventsProtocol.handlers[methodID]; + + if (!handler) { + packet.message.methodName = `UnknownMethod_0x${methodID.toString(16).toUpperCase().padStart(2, '0')}`; + return; + } + + const messageDecoder = handler(packet.message); + + packet.message.parameters = new messageDecoder(packet.message); + packet.message.methodName = messageDecoder.Name; + } + + private static ProcessNotificationEvent(message: RMCMessage): typeof Methods.ProcessNotificationEvent.Request | typeof Methods.ProcessNotificationEvent.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ProcessNotificationEvent.Request; + } else { + return Methods.ProcessNotificationEvent.Response; + } + } +} \ No newline at end of file diff --git a/src/nex/protocols/notification-events/methods/index.ts b/src/nex/protocols/notification-events/methods/index.ts new file mode 100644 index 0000000..29166a4 --- /dev/null +++ b/src/nex/protocols/notification-events/methods/index.ts @@ -0,0 +1 @@ +export * as ProcessNotificationEvent from '@/nex/protocols/notification-events/methods/process-notification-event'; \ No newline at end of file diff --git a/src/nex/protocols/notification-events/methods/process-notification-event.ts b/src/nex/protocols/notification-events/methods/process-notification-event.ts new file mode 100644 index 0000000..e1ea74d --- /dev/null +++ b/src/nex/protocols/notification-events/methods/process-notification-event.ts @@ -0,0 +1,33 @@ +import NEXByteStream from '@/nex/byte-stream'; +import NotificationEvent from '@/nex/protocols/notification-events/types/notification-event'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/notification-events/process-notification-event'; + +export class Request { + public static Name = 'ProcessNotificationEvent'; + + private oEvent = new NotificationEvent(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.oEvent.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + oEvent: this.oEvent + }; + } +} + +// * No response data +export class Response { + public static Name = 'ProcessNotificationEvent'; + + constructor() {} + + public toJSON(): RMCs.Response { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/notification-events/types/notification-event.ts b/src/nex/protocols/notification-events/types/notification-event.ts new file mode 100644 index 0000000..40ba788 --- /dev/null +++ b/src/nex/protocols/notification-events/types/notification-event.ts @@ -0,0 +1,60 @@ +import semver from 'compare-versions'; +import Structure from '@/nex/types/structure'; +import PID from '@/nex/types/uint32'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import type NEXByteStream from '@/nex/byte-stream'; + + +// * ONLY IMPLEMENTS THE 3DS AND WII U VERSION! +// * THE SWITCH USES A DIFFERENT STRUCTURE! +export default class NotificationEvent extends Structure { + public readonly typeName = 'NotificationEvent'; + + private m_pidSource = new PID(); + private m_uiType = new UInt32(); + private m_uiParam1 = new UInt32(); + private m_uiParam2 = new UInt32(); + private m_strParam = new RVString(); + private m_uiParam3: UInt32; // * NEX 3.4 + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_pidSource.extractFrom(stream); + this.m_uiType.extractFrom(stream); + this.m_uiParam1.extractFrom(stream); + this.m_uiParam2.extractFrom(stream); + this.m_strParam.extractFrom(stream); + + if (semver.satisfies(stream.title.library_versions.main, '>=3.4.0')) { + this.m_uiParam3 = new UInt32(); + this.m_uiParam3.extractFrom(stream); + } + } + + public new(): NotificationEvent { + return new NotificationEvent(); + } + + public toJSON(): Record { + const json: Record = { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_pidSource: this.m_pidSource, + m_uiType: this.m_uiType, + m_uiParam1: this.m_uiParam1, + m_uiParam2: this.m_uiParam2, + m_strParam: this.m_strParam + } + }; + + if (this.m_uiParam3 !== undefined) { + json.__fields.m_uiParam3 = this.m_uiParam3; + } + + return json; + } +} \ No newline at end of file diff --git a/src/nex/protocols/secure-connection/methods/register-ex.ts b/src/nex/protocols/secure-connection/methods/register-ex.ts index 2a8fae4..9e48f34 100644 --- a/src/nex/protocols/secure-connection/methods/register-ex.ts +++ b/src/nex/protocols/secure-connection/methods/register-ex.ts @@ -14,7 +14,7 @@ export class Request { private hCustomData = new AnyDataHolder(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.vecMyURLs.extractFrom(stream); this.hCustomData.extractFrom(stream); @@ -36,7 +36,7 @@ export class Response { private urlPublic = new StationURL(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.retval.extractFrom(stream); diff --git a/src/nex/protocols/secure-connection/methods/register.ts b/src/nex/protocols/secure-connection/methods/register.ts index 07ea9ea..93ed60b 100644 --- a/src/nex/protocols/secure-connection/methods/register.ts +++ b/src/nex/protocols/secure-connection/methods/register.ts @@ -12,7 +12,7 @@ export class Request { private vecMyURLs = new List(new StationURL()); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.vecMyURLs.extractFrom(stream); } @@ -32,7 +32,7 @@ export class Response { private urlPublic = new StationURL(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.retval.extractFrom(stream); diff --git a/src/nex/protocols/secure-connection/methods/replace-url.ts b/src/nex/protocols/secure-connection/methods/replace-url.ts index 17a4bf7..40b742b 100644 --- a/src/nex/protocols/secure-connection/methods/replace-url.ts +++ b/src/nex/protocols/secure-connection/methods/replace-url.ts @@ -10,7 +10,7 @@ export class Request { private url = new StationURL(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.target.extractFrom(stream); this.url.extractFrom(stream); diff --git a/src/nex/protocols/secure-connection/methods/request-connection-data.ts b/src/nex/protocols/secure-connection/methods/request-connection-data.ts index ba1bb40..2c167d2 100644 --- a/src/nex/protocols/secure-connection/methods/request-connection-data.ts +++ b/src/nex/protocols/secure-connection/methods/request-connection-data.ts @@ -13,7 +13,7 @@ export class Request { private pidTarget = new UInt32(); // TODO - Is this actually a PID type? Check the Switch constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.cidTarget.extractFrom(stream); this.pidTarget.extractFrom(stream); @@ -34,7 +34,7 @@ export class Response { private pvecConnectionsData = new List(new ConnectionData()); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.retval.extractFrom(stream); this.pvecConnectionsData.extractFrom(stream); diff --git a/src/nex/protocols/secure-connection/methods/request-urls.ts b/src/nex/protocols/secure-connection/methods/request-urls.ts index ebb15b2..92ee670 100644 --- a/src/nex/protocols/secure-connection/methods/request-urls.ts +++ b/src/nex/protocols/secure-connection/methods/request-urls.ts @@ -13,7 +13,7 @@ export class Request { private pidTarget = new UInt32(); // TODO - Is this actually a PID type? Check the Switch constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.cidTarget.extractFrom(stream); this.pidTarget.extractFrom(stream); @@ -34,7 +34,7 @@ export class Response { private plstURLs = new List(new StationURL()); // TODO - Is this actually a PID type? Check the Switch constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.retval.extractFrom(stream); this.plstURLs.extractFrom(stream); diff --git a/src/nex/protocols/secure-connection/methods/send-report.ts b/src/nex/protocols/secure-connection/methods/send-report.ts index 0d92c20..9cf5bbe 100644 --- a/src/nex/protocols/secure-connection/methods/send-report.ts +++ b/src/nex/protocols/secure-connection/methods/send-report.ts @@ -11,7 +11,7 @@ export class Request { private reportData = new QBuffer(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.reportId.extractFrom(stream); this.reportData.extractFrom(stream); diff --git a/src/nex/protocols/secure-connection/methods/update-urls.ts b/src/nex/protocols/secure-connection/methods/update-urls.ts index 4c6bc31..2cd95bf 100644 --- a/src/nex/protocols/secure-connection/methods/update-urls.ts +++ b/src/nex/protocols/secure-connection/methods/update-urls.ts @@ -10,7 +10,7 @@ export class Request { private vecMyURLs = new List(new StationURL()); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.vecMyURLs.extractFrom(stream); } diff --git a/src/nex/protocols/ticket-granting/methods/login-ex.ts b/src/nex/protocols/ticket-granting/methods/login-ex.ts index 07a7b6a..786ae2a 100644 --- a/src/nex/protocols/ticket-granting/methods/login-ex.ts +++ b/src/nex/protocols/ticket-granting/methods/login-ex.ts @@ -15,7 +15,7 @@ export class Request { private oExtraData = new AnyDataHolder(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.strUserName.extractFrom(stream); this.oExtraData.extractFrom(stream); @@ -39,7 +39,7 @@ export class Response { private strReturnMsg = new RVString(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.retval.extractFrom(stream); diff --git a/src/nex/protocols/ticket-granting/methods/login.ts b/src/nex/protocols/ticket-granting/methods/login.ts index 70fb0c2..9e3df1d 100644 --- a/src/nex/protocols/ticket-granting/methods/login.ts +++ b/src/nex/protocols/ticket-granting/methods/login.ts @@ -13,7 +13,7 @@ export class Request { private strUserName = new RVString(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.strUserName.extractFrom(stream); } @@ -35,7 +35,7 @@ export class Response { private strReturnMsg = new RVString(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.retval.extractFrom(stream); diff --git a/src/nex/protocols/ticket-granting/methods/request-ticket.ts b/src/nex/protocols/ticket-granting/methods/request-ticket.ts index 0c07e3c..0d80bdd 100644 --- a/src/nex/protocols/ticket-granting/methods/request-ticket.ts +++ b/src/nex/protocols/ticket-granting/methods/request-ticket.ts @@ -13,7 +13,7 @@ export class Request { private idTarget = new PID(); constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.idSource.extractFrom(stream); this.idTarget.extractFrom(stream); @@ -35,7 +35,7 @@ export class Response { private pSourceKey: RVString; constructor(message: RMCMessage) { - const stream = new NEXByteStream(message.parametersData!, message.connection.title.settings); + const stream = new NEXByteStream(message.parametersData!, message.connection.title); this.retval.extractFrom(stream); diff --git a/src/nex/types/any-data-holder.ts b/src/nex/types/any-data-holder.ts index 7dd03eb..33063aa 100644 --- a/src/nex/types/any-data-holder.ts +++ b/src/nex/types/any-data-holder.ts @@ -19,7 +19,7 @@ export default class AnyDataHolder extends Structure { this.length1.extractFrom(stream); this.length2.extractFrom(stream); - const objectStream = new NEXByteStream(stream.read(this.length2.value), stream.settings); + const objectStream = new NEXByteStream(stream.read(this.length2.value), stream.title); if (AnyDataHolder.Classes[this.name.value]) { this.objectData = new AnyDataHolder.Classes[this.name.value](); diff --git a/src/nex/types/pid.ts b/src/nex/types/pid.ts index 9df0dd5..ee38b51 100644 --- a/src/nex/types/pid.ts +++ b/src/nex/types/pid.ts @@ -8,13 +8,13 @@ export default class PID { private size: number; public extractFrom(stream: NEXByteStream): void { - if (stream.settings.pid_size === 8) { + if (stream.title.settings.pid_size === 8) { this.value = stream.readUInt64LE(); } else { this.value = BigInt(stream.readUInt32LE()); } - this.size = stream.settings.pid_size; + this.size = stream.title.settings.pid_size; } public new(): PID { diff --git a/src/nex/types/string.ts b/src/nex/types/string.ts index 75aa976..0ace488 100644 --- a/src/nex/types/string.ts +++ b/src/nex/types/string.ts @@ -9,7 +9,7 @@ export default class RVString { public extractFrom(stream: NEXByteStream): void { let length = 0; - if (stream.settings.string_length_size === 4) { + if (stream.title.settings.string_length_size === 4) { length = stream.readUInt32LE(); } else { length = stream.readUInt16LE(); diff --git a/src/nex/types/structure.ts b/src/nex/types/structure.ts index 257d041..adad51e 100644 --- a/src/nex/types/structure.ts +++ b/src/nex/types/structure.ts @@ -8,7 +8,7 @@ export default class Structure { } protected extractHeaderFrom(stream: NEXByteStream): void { - if (stream.settings.use_structure_header) { + if (stream.title.settings.use_structure_header) { this._structureVersion = stream.readUInt8(); stream.skip(4); // * Ignore the size } diff --git a/src/types/nex/rmcs/notification-events/process-notification-event.ts b/src/types/nex/rmcs/notification-events/process-notification-event.ts new file mode 100644 index 0000000..a6f924f --- /dev/null +++ b/src/types/nex/rmcs/notification-events/process-notification-event.ts @@ -0,0 +1,7 @@ +import type NotificationEvent from '@/nex/protocols/notification-events/types/notification-event'; + +export type Request = { + oEvent: NotificationEvent; +}; + +export type Response = object; // * No response data \ No newline at end of file From c26cc680b29817514ebd3b16ccacc0da3b32ba1f Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 17:48:11 -0400 Subject: [PATCH 44/67] feat: display packet JSON in UI when selected --- src/renderers/main/assets/js/main.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/renderers/main/assets/js/main.tsx b/src/renderers/main/assets/js/main.tsx index 2e39542..2621f53 100644 --- a/src/renderers/main/assets/js/main.tsx +++ b/src/renderers/main/assets/js/main.tsx @@ -86,8 +86,12 @@ function setSelectedPacketRow(tr: HTMLElement): void { updatePacketDetails(JSON.parse(tr.dataset.serialized!)); } -function updatePacketDetails(_packet: SerializedPacket): void { +function updatePacketDetails(packet: SerializedPacket): void { const root = document.createElement('details'); + const pre = document.createElement('pre'); + + pre.appendChild(document.createTextNode(JSON.stringify(packet, null, '\t'))); + root.appendChild(pre); removeAllChildNodes(packetDetailsSection); From c6ebc8f1ada11a26982bea519f3cc1edef397cb6 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 17:52:44 -0400 Subject: [PATCH 45/67] feat: start implementing MatchMaking --- src/nex/protocols/manager.ts | 3 + src/nex/protocols/match-making/index.ts | 96 +++++++++++++++++++ .../match-making/methods/get-session-urls.ts | 43 +++++++++ .../protocols/match-making/methods/index.ts | 2 + .../methods/update-session-host.ts | 37 +++++++ .../nex/rmcs/match-making/get-session-urls.ts | 11 +++ .../rmcs/match-making/update-session-host.ts | 9 ++ 7 files changed, 201 insertions(+) create mode 100644 src/nex/protocols/match-making/index.ts create mode 100644 src/nex/protocols/match-making/methods/get-session-urls.ts create mode 100644 src/nex/protocols/match-making/methods/index.ts create mode 100644 src/nex/protocols/match-making/methods/update-session-host.ts create mode 100644 src/types/nex/rmcs/match-making/get-session-urls.ts create mode 100644 src/types/nex/rmcs/match-making/update-session-host.ts diff --git a/src/nex/protocols/manager.ts b/src/nex/protocols/manager.ts index 52a806c..5fb266d 100644 --- a/src/nex/protocols/manager.ts +++ b/src/nex/protocols/manager.ts @@ -2,6 +2,7 @@ import NATTraversalProtocol from '@/nex/protocols/nat-traversal'; import TicketGrantingProtocol from '@/nex/protocols/ticket-granting'; import SecureConnectionProtocol from '@/nex/protocols/secure-connection'; import NotificationEventsProtocol from '@/nex/protocols/notification-events'; +import MatchMakingProtocol from '@/nex/protocols/match-making'; import type RMCMessage from '@/nex/rmc-message'; import type ServiceProtocol from '@/types/nex/service-protocol'; @@ -17,6 +18,8 @@ export default function getProtocol(message: RMCMessage): ServiceProtocol | null return SecureConnectionProtocol; case NotificationEventsProtocol.ID: return NotificationEventsProtocol; + case MatchMakingProtocol.ID: + return MatchMakingProtocol; } return null; diff --git a/src/nex/protocols/match-making/index.ts b/src/nex/protocols/match-making/index.ts new file mode 100644 index 0000000..1dcf155 --- /dev/null +++ b/src/nex/protocols/match-making/index.ts @@ -0,0 +1,96 @@ +import RMCMessage from '@/nex/rmc-message'; +import * as Methods from '@/nex/protocols/match-making/methods'; +import type Packet from '@/types/nex/packet'; + +export default class MatchMakingProtocol { + static ID = 0x15; + static Name = 'MatchMaking'; + + static Methods = { + RegisterGathering: 0x1, + UnregisterGathering: 0x2, + UnregisterGatherings: 0x3, + UpdateGathering: 0x4, + Invite: 0x5, + AcceptInvitation: 0x6, + DeclineInvitation: 0x7, + CancelInvitation: 0x8, + GetInvitationsSent: 0x9, + GetInvitationsReceived: 0xA, + Participate: 0xB, + CancelParticipation: 0xC, + GetParticipants: 0xD, + AddParticipants: 0xE, + GetDetailedParticipants: 0xF, + GetParticipantsURLs: 0x10, + FindByType: 0x11, + FindByDescription: 0x12, + FindByDescriptionRegex: 0x13, + FindByID: 0x14, + FindBySingleID: 0x15, + FindByOwner: 0x16, + FindByParticipants: 0x17, + FindInvitations: 0x18, + FindBySQLQuery: 0x19, + LaunchSession: 0x1A, + UpdateSessionURL: 0x1B, + GetSessionURL: 0x1C, + GetState: 0x1D, + SetState: 0x1E, + ReportStats: 0x1F, + GetStats: 0x20, + DeleteGathering: 0x21, + GetPendingDeletions: 0x22, + DeleteFromDeletions: 0x23, + MigrateGatheringOwnershipV1: 0x24, + FindByDescriptionLike: 0x25, + RegisterLocalURL: 0x26, + RegisterLocalURLs: 0x27, + UpdateSessionHostV1: 0x28, + GetSessionURLs: 0x29, + UpdateSessionHost: 0x2A, + UpdateGatheringOwnership: 0x2B, + MigrateGatheringOwnership: 0x2C + }; + + private static handlers: Record any> = { + 0x29: MatchMakingProtocol.GetSessionURLs, + 0x2A: MatchMakingProtocol.UpdateSessionHost + }; + + static handlePacket(packet: Packet): void { + if (!packet.message) { + // * This will never happen. Only checked to make TypeScript happy + return; + } + + const methodID = packet.message.methodID; + const handler = MatchMakingProtocol.handlers[methodID]; + + if (!handler) { + packet.message.methodName = `UnknownMethod_0x${methodID.toString(16).toUpperCase().padStart(2, '0')}`; + return; + } + + const messageDecoder = handler(packet.message); + + packet.message.parameters = new messageDecoder(packet.message); + packet.message.methodName = messageDecoder.Name; + } + + private static GetSessionURLs(message: RMCMessage): typeof Methods.GetSessionURLs.Request | typeof Methods.GetSessionURLs.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetSessionURLs.Request; + } else { + return Methods.GetSessionURLs.Response; + } + } + + private static UpdateSessionHost(message: RMCMessage): typeof Methods.UpdateSessionHost.Request | typeof Methods.UpdateSessionHost.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateSessionHost.Request; + } else { + return Methods.UpdateSessionHost.Response; + } + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/get-session-urls.ts b/src/nex/protocols/match-making/methods/get-session-urls.ts new file mode 100644 index 0000000..349a5ed --- /dev/null +++ b/src/nex/protocols/match-making/methods/get-session-urls.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/match-making/get-session-urls'; + +export class Request { + public static Name = 'GetSessionURLs'; + + private gid = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + gid: this.gid + }; + } +} + +// * No response data +export class Response { + public static Name = 'GetSessionURLs'; + + private lstURLs = new List(new StationURL()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstURLs.extractFrom(stream); + } + + public toJSON(): RMCs.Response { + return { + lstURLs: this.lstURLs + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/index.ts b/src/nex/protocols/match-making/methods/index.ts new file mode 100644 index 0000000..74874e5 --- /dev/null +++ b/src/nex/protocols/match-making/methods/index.ts @@ -0,0 +1,2 @@ +export * as GetSessionURLs from '@/nex/protocols/match-making/methods/get-session-urls'; +export * as UpdateSessionHost from '@/nex/protocols/match-making/methods/update-session-host'; \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/update-session-host.ts b/src/nex/protocols/match-making/methods/update-session-host.ts new file mode 100644 index 0000000..737f410 --- /dev/null +++ b/src/nex/protocols/match-making/methods/update-session-host.ts @@ -0,0 +1,37 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/match-making/update-session-host'; + +export class Request { + public static Name = 'UpdateSessionHost'; + + private gid = new UInt32(); + private isMigrateOwner = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.isMigrateOwner.extractFrom(stream); + } + + public toJSON(): RMCs.Response { + return { + gid: this.gid, + isMigrateOwner: this.isMigrateOwner + }; + } +} + +// * No response data +export class Response { + public static Name = 'UpdateSessionHost'; + + constructor() {} + + public toJSON(): RMCs.Response { + return {}; + } +} \ No newline at end of file diff --git a/src/types/nex/rmcs/match-making/get-session-urls.ts b/src/types/nex/rmcs/match-making/get-session-urls.ts new file mode 100644 index 0000000..8e3651a --- /dev/null +++ b/src/types/nex/rmcs/match-making/get-session-urls.ts @@ -0,0 +1,11 @@ +import type UInt32 from '@/nex/types/uint32'; +import type List from '@/nex/types/list'; +import type StationURL from '@/nex/types/station-url'; + +export type Request = { + gid: UInt32; +}; + +export type Response = { + lstURLs: List; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/match-making/update-session-host.ts b/src/types/nex/rmcs/match-making/update-session-host.ts new file mode 100644 index 0000000..c3c1c54 --- /dev/null +++ b/src/types/nex/rmcs/match-making/update-session-host.ts @@ -0,0 +1,9 @@ +import type UInt32 from '@/nex/types/uint32'; +import type Bool from '@/nex/types/bool'; + +export type Request = { + gid: UInt32; + isMigrateOwner: Bool; +}; + +export type Response = object; // * No response data \ No newline at end of file From 8a910e9ce355df6a7a2c24418de5bbfe499fd1ac Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 18:05:53 -0400 Subject: [PATCH 46/67] feat: add basic search to packet list --- .../main/assets/css/packets-section.css | 4 +++ src/renderers/main/assets/js/main.tsx | 31 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/renderers/main/assets/css/packets-section.css b/src/renderers/main/assets/css/packets-section.css index aa678ba..9306fc3 100644 --- a/src/renderers/main/assets/css/packets-section.css +++ b/src/renderers/main/assets/css/packets-section.css @@ -59,4 +59,8 @@ #packet-list tbody td { white-space: nowrap; cursor: pointer; +} + +.search-hidden { + display: none; } \ No newline at end of file diff --git a/src/renderers/main/assets/js/main.tsx b/src/renderers/main/assets/js/main.tsx index 2621f53..3863b19 100644 --- a/src/renderers/main/assets/js/main.tsx +++ b/src/renderers/main/assets/js/main.tsx @@ -8,6 +8,35 @@ export const packetsListSection = document.querySelector('#packet-list tbody')!; export const connectionsListSection = document.querySelector('#connections')!; export const packetDetailsSection = document.getElementById('packet-details')!; +let selectedPacket: HTMLElement; + +document.querySelector('#header-search')!.addEventListener('keyup', event => { + if (!event.target || !(event.target instanceof HTMLInputElement)) { + return; + } + + const filter = event.target.value; + + const packets = packetsListSection.querySelectorAll('tr[data-serialized]'); + + for (const packet of packets) { + if (packet.dataset.serialized?.toLowerCase().includes(filter.toLowerCase())) { + packet.classList.remove('search-hidden'); + } else { + packet.classList.add('search-hidden'); + } + } + + if (filter.trim() === '') { + if (selectedPacket) { + selectedPacket.scrollIntoView({ + block: 'nearest', + inline: 'nearest' + }); + } + } +}); + export function addPacketToList(packet: SerializedPacket): void { const infoData: string[] = []; @@ -83,6 +112,8 @@ function setSelectedPacketRow(tr: HTMLElement): void { document.querySelector('tr.selected')?.classList.toggle('selected'); tr.classList.toggle('selected'); + selectedPacket = tr; + updatePacketDetails(JSON.parse(tr.dataset.serialized!)); } From 331beca80c24361b4a98ca6d9d556d9fdd476842 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 18:20:25 -0400 Subject: [PATCH 47/67] feat: start implementing MatchMakingExt --- src/nex/protocols/manager.ts | 3 ++ src/nex/protocols/match-making-ext/index.ts | 49 +++++++++++++++++++ .../methods/end-participation.ts | 45 +++++++++++++++++ .../match-making-ext/methods/index.ts | 1 + .../match-making/methods/get-session-urls.ts | 1 - .../match-making-ext/end-participation.ts | 12 +++++ 6 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 src/nex/protocols/match-making-ext/index.ts create mode 100644 src/nex/protocols/match-making-ext/methods/end-participation.ts create mode 100644 src/nex/protocols/match-making-ext/methods/index.ts create mode 100644 src/types/nex/rmcs/match-making-ext/end-participation.ts diff --git a/src/nex/protocols/manager.ts b/src/nex/protocols/manager.ts index 5fb266d..24c6330 100644 --- a/src/nex/protocols/manager.ts +++ b/src/nex/protocols/manager.ts @@ -3,6 +3,7 @@ import TicketGrantingProtocol from '@/nex/protocols/ticket-granting'; import SecureConnectionProtocol from '@/nex/protocols/secure-connection'; import NotificationEventsProtocol from '@/nex/protocols/notification-events'; import MatchMakingProtocol from '@/nex/protocols/match-making'; +import MatchMakingExtProtocol from '@/nex/protocols/match-making-ext'; import type RMCMessage from '@/nex/rmc-message'; import type ServiceProtocol from '@/types/nex/service-protocol'; @@ -20,6 +21,8 @@ export default function getProtocol(message: RMCMessage): ServiceProtocol | null return NotificationEventsProtocol; case MatchMakingProtocol.ID: return MatchMakingProtocol; + case MatchMakingExtProtocol.ID: + return MatchMakingExtProtocol; } return null; diff --git a/src/nex/protocols/match-making-ext/index.ts b/src/nex/protocols/match-making-ext/index.ts new file mode 100644 index 0000000..3af0f34 --- /dev/null +++ b/src/nex/protocols/match-making-ext/index.ts @@ -0,0 +1,49 @@ +import RMCMessage from '@/nex/rmc-message'; +import * as Methods from '@/nex/protocols/match-making-ext/methods'; +import type Packet from '@/types/nex/packet'; + +export default class MatchMakingExtProtocol { + static ID = 0x32; + static Name = 'MatchMakingExt'; + + static Methods = { + EndParticipation: 0x1, + GetParticipants: 0x2, + GetDetailedParticipants: 0x3, + GetParticipantsURLs: 0x4, + GetGatheringRelations: 0x5, + DeleteFromDeletions: 0x6 + }; + + private static handlers: Record any> = { + 0x1: MatchMakingExtProtocol.EndParticipation + }; + + static handlePacket(packet: Packet): void { + if (!packet.message) { + // * This will never happen. Only checked to make TypeScript happy + return; + } + + const methodID = packet.message.methodID; + const handler = MatchMakingExtProtocol.handlers[methodID]; + + if (!handler) { + packet.message.methodName = `UnknownMethod_0x${methodID.toString(16).toUpperCase().padStart(2, '0')}`; + return; + } + + const messageDecoder = handler(packet.message); + + packet.message.parameters = new messageDecoder(packet.message); + packet.message.methodName = messageDecoder.Name; + } + + private static EndParticipation(message: RMCMessage): typeof Methods.EndParticipation.Request | typeof Methods.EndParticipation.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.EndParticipation.Request; + } else { + return Methods.EndParticipation.Response; + } + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making-ext/methods/end-participation.ts b/src/nex/protocols/match-making-ext/methods/end-participation.ts new file mode 100644 index 0000000..0d7853a --- /dev/null +++ b/src/nex/protocols/match-making-ext/methods/end-participation.ts @@ -0,0 +1,45 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/match-making-ext/end-participation'; + +export class Request { + public static Name = 'EndParticipation'; + + private idGathering = new UInt32(); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + idGathering: this.idGathering, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'EndParticipation'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): RMCs.Response { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making-ext/methods/index.ts b/src/nex/protocols/match-making-ext/methods/index.ts new file mode 100644 index 0000000..923f3be --- /dev/null +++ b/src/nex/protocols/match-making-ext/methods/index.ts @@ -0,0 +1 @@ +export * as EndParticipation from '@/nex/protocols/match-making-ext/methods/end-participation'; \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/get-session-urls.ts b/src/nex/protocols/match-making/methods/get-session-urls.ts index 349a5ed..68d679f 100644 --- a/src/nex/protocols/match-making/methods/get-session-urls.ts +++ b/src/nex/protocols/match-making/methods/get-session-urls.ts @@ -23,7 +23,6 @@ export class Request { } } -// * No response data export class Response { public static Name = 'GetSessionURLs'; diff --git a/src/types/nex/rmcs/match-making-ext/end-participation.ts b/src/types/nex/rmcs/match-making-ext/end-participation.ts new file mode 100644 index 0000000..351314d --- /dev/null +++ b/src/types/nex/rmcs/match-making-ext/end-participation.ts @@ -0,0 +1,12 @@ +import type UInt32 from '@/nex/types/uint32'; +import type RVString from '@/nex/types/string'; +import type Bool from '@/nex/types/bool'; + +export type Request = { + idGathering: UInt32; + strMessage: RVString; +}; + +export type Response = { + retval: Bool; +}; \ No newline at end of file From dd0276a7a3fa8b90d1b2f0999a1033b0fd25ca4f Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 22:30:07 -0400 Subject: [PATCH 48/67] feat: start implementing MatchmakeExtension --- src/nex/protocols/manager.ts | 3 + .../types/auto-matchmake-param.ts | 71 ++++++++ .../protocols/match-making/types/gathering.ts | 65 ++++++++ .../types/matchmake-block-list-param.ts | 30 ++++ .../match-making/types/matchmake-param.ts | 32 ++++ .../matchmake-session-search-criteria.ts | 152 +++++++++++++++++ .../match-making/types/matchmake-session.ts | 156 ++++++++++++++++++ .../types/persistent-gathering.ts | 63 +++++++ .../match-making/types/playing-session.ts | 34 ++++ .../types/simple-playing-session.ts | 40 +++++ .../protocols/matchmake-extension/index.ts | 133 +++++++++++++++ .../auto-matchmake-with-param-postpone.ts | 41 +++++ .../methods/close-participation.ts | 33 ++++ .../methods/get-playing-session.ts | 42 +++++ .../methods/get-simple-playing-session.ts | 46 ++++++ .../matchmake-extension/methods/index.ts | 5 + .../methods/update-progress-score.ts | 37 +++++ .../types/notification-event.ts | 1 - .../auto-matchmake-with-param-postpone.ts | 10 ++ .../close-participation.ts | 7 + .../get-playing-session.ts | 11 ++ .../get-simple-playing-session.ts | 13 ++ .../update-progress-score.ts | 9 + 23 files changed, 1033 insertions(+), 1 deletion(-) create mode 100644 src/nex/protocols/match-making/types/auto-matchmake-param.ts create mode 100644 src/nex/protocols/match-making/types/gathering.ts create mode 100644 src/nex/protocols/match-making/types/matchmake-block-list-param.ts create mode 100644 src/nex/protocols/match-making/types/matchmake-param.ts create mode 100644 src/nex/protocols/match-making/types/matchmake-session-search-criteria.ts create mode 100644 src/nex/protocols/match-making/types/matchmake-session.ts create mode 100644 src/nex/protocols/match-making/types/persistent-gathering.ts create mode 100644 src/nex/protocols/match-making/types/playing-session.ts create mode 100644 src/nex/protocols/match-making/types/simple-playing-session.ts create mode 100644 src/nex/protocols/matchmake-extension/index.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/close-participation.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/get-playing-session.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/get-simple-playing-session.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/index.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/update-progress-score.ts create mode 100644 src/types/nex/rmcs/matchmake-extension/auto-matchmake-with-param-postpone.ts create mode 100644 src/types/nex/rmcs/matchmake-extension/close-participation.ts create mode 100644 src/types/nex/rmcs/matchmake-extension/get-playing-session.ts create mode 100644 src/types/nex/rmcs/matchmake-extension/get-simple-playing-session.ts create mode 100644 src/types/nex/rmcs/matchmake-extension/update-progress-score.ts diff --git a/src/nex/protocols/manager.ts b/src/nex/protocols/manager.ts index 24c6330..f501cd2 100644 --- a/src/nex/protocols/manager.ts +++ b/src/nex/protocols/manager.ts @@ -4,6 +4,7 @@ import SecureConnectionProtocol from '@/nex/protocols/secure-connection'; import NotificationEventsProtocol from '@/nex/protocols/notification-events'; import MatchMakingProtocol from '@/nex/protocols/match-making'; import MatchMakingExtProtocol from '@/nex/protocols/match-making-ext'; +import MatchmakeExtensionProtocol from '@/nex/protocols/matchmake-extension'; import type RMCMessage from '@/nex/rmc-message'; import type ServiceProtocol from '@/types/nex/service-protocol'; @@ -23,6 +24,8 @@ export default function getProtocol(message: RMCMessage): ServiceProtocol | null return MatchMakingProtocol; case MatchMakingExtProtocol.ID: return MatchMakingExtProtocol; + case MatchmakeExtensionProtocol.ID: + return MatchmakeExtensionProtocol; } return null; diff --git a/src/nex/protocols/match-making/types/auto-matchmake-param.ts b/src/nex/protocols/match-making/types/auto-matchmake-param.ts new file mode 100644 index 0000000..4501e6c --- /dev/null +++ b/src/nex/protocols/match-making/types/auto-matchmake-param.ts @@ -0,0 +1,71 @@ +import semver from 'compare-versions'; +import Structure from '@/nex/types/structure'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import UInt16 from '@/nex/types/uint16'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import MatchmakeSessionSearchCriteria from '@/nex/protocols/match-making/types/matchmake-session-search-criteria'; +import MatchmakeBlockListParam from '@/nex/protocols/match-making/types/matchmake-block-list-param'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class AutoMatchmakeParam extends Structure { + public readonly typeName = 'AutoMatchmakeParam'; + + private sourceMatchmakeSession = new MatchmakeSession(); + private additionalParticipants = new List(new PID()); + private gidForParticipationCheck = new UInt32(); + private autoMatchmakeOption = new UInt32(); + private joinMessage = new RVString(); + private participationCount = new UInt16(); + private lstSearchCriteria = new List(new MatchmakeSessionSearchCriteria()); + private targetGids = new List(new UInt32()); + private blockListParam: MatchmakeBlockListParam; // * NEX 4.0 + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.sourceMatchmakeSession.extractFrom(stream); + this.additionalParticipants.extractFrom(stream); + this.gidForParticipationCheck.extractFrom(stream); + this.autoMatchmakeOption.extractFrom(stream); + this.joinMessage.extractFrom(stream); + this.participationCount.extractFrom(stream); + this.lstSearchCriteria.extractFrom(stream); + this.targetGids.extractFrom(stream); + + if (semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) { + this.blockListParam = new MatchmakeBlockListParam(); + this.blockListParam.extractFrom(stream); + } + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + const json: Record = { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + sourceMatchmakeSession: this.sourceMatchmakeSession, + additionalParticipants: this.additionalParticipants, + gidForParticipationCheck: this.gidForParticipationCheck, + autoMatchmakeOption: this.autoMatchmakeOption, + joinMessage: this.joinMessage, + participationCount: this.participationCount, + lstSearchCriteria: this.lstSearchCriteria, + targetGids: this.targetGids + } + }; + + if (this.blockListParam !== undefined) { + json.__fields.blockListParam = this.blockListParam; + } + + return json; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/gathering.ts b/src/nex/protocols/match-making/types/gathering.ts new file mode 100644 index 0000000..5535d98 --- /dev/null +++ b/src/nex/protocols/match-making/types/gathering.ts @@ -0,0 +1,65 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import PID from '@/nex/types/pid'; +import UInt16 from '@/nex/types/uint16'; +import RVString from '@/nex/types/string'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class Gathering extends Structure { + public get typeName(): string { + return 'Gathering'; + } + + private m_idMyself = new UInt32(); + private m_pidOwner = new PID(); + private m_pidHost = new PID(); + private m_uiMinParticipants = new UInt16(); + private m_uiMaxParticipants = new UInt16(); + private m_uiParticipationPolicy = new UInt32(); + private m_uiPolicyArgument = new UInt32(); + private m_uiFlags = new UInt32(); + private m_uiState = new UInt32(); + private m_strDescription = new RVString(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_idMyself.extractFrom(stream); + this.m_pidOwner.extractFrom(stream); + this.m_pidHost.extractFrom(stream); + this.m_uiMinParticipants.extractFrom(stream); + this.m_uiMaxParticipants.extractFrom(stream); + this.m_uiParticipationPolicy.extractFrom(stream); + this.m_uiPolicyArgument.extractFrom(stream); + this.m_uiFlags.extractFrom(stream); + this.m_uiState.extractFrom(stream); + this.m_strDescription.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_idMyself: this.m_idMyself, + m_pidOwner: this.m_pidOwner, + m_pidHost: this.m_pidHost, + m_uiMinParticipants: this.m_uiMinParticipants, + m_uiMaxParticipants: this.m_uiMaxParticipants, + m_uiParticipationPolicy: this.m_uiParticipationPolicy, + m_uiPolicyArgument: this.m_uiPolicyArgument, + m_uiFlags: this.m_uiFlags, + m_uiState: this.m_uiState, + m_strDescription: this.m_strDescription + } + }; + } +} + +AnyDataHolder.Classes['Gathering'] = Gathering; \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/matchmake-block-list-param.ts b/src/nex/protocols/match-making/types/matchmake-block-list-param.ts new file mode 100644 index 0000000..7be5e0a --- /dev/null +++ b/src/nex/protocols/match-making/types/matchmake-block-list-param.ts @@ -0,0 +1,30 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class MatchmakeBlockListParam extends Structure { + public readonly typeName = 'MatchmakeBlockListParam'; + + private optionFlag = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.optionFlag.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + optionFlag: this.optionFlag + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/matchmake-param.ts b/src/nex/protocols/match-making/types/matchmake-param.ts new file mode 100644 index 0000000..2313f84 --- /dev/null +++ b/src/nex/protocols/match-making/types/matchmake-param.ts @@ -0,0 +1,32 @@ +import Structure from '@/nex/types/structure'; +import RVMap from '@/nex/types/map'; +import RVString from '@/nex/types/string'; +import Variant from '@/nex/types/variant'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class MatchmakeParam extends Structure { + public readonly typeName = 'MatchmakeParam'; + + private m_Params = new RVMap(new RVString(), new Variant()); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_Params.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_Params: this.m_Params + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/matchmake-session-search-criteria.ts b/src/nex/protocols/match-making/types/matchmake-session-search-criteria.ts new file mode 100644 index 0000000..012e29e --- /dev/null +++ b/src/nex/protocols/match-making/types/matchmake-session-search-criteria.ts @@ -0,0 +1,152 @@ +import Structure from '@/nex/types/structure'; +import semver from 'compare-versions'; +import List from '@/nex/types/list'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import UInt32 from '@/nex/types/uint32'; +import UInt16 from '@/nex/types/uint16'; +import ResultRange from '@/nex/types/result-range'; +import MatchmakeParam from '@/nex/protocols/match-making/types/matchmake-param'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class MatchmakeSessionSearchCriteria extends Structure { + public get typeName(): string { + return 'MatchmakeSessionSearchCriteria'; + } + + private m_Attribs = new List(new RVString()); + private m_GameMode = new RVString(); + private m_MinParticipants: RVString; // * NEX 2.0 + private m_MaxParticipants: RVString; // * NEX 2.0 + private m_MatchmakeSystemType = new RVString(); + private m_VacantOnly = new Bool(); + private m_ExcludeLocked = new Bool(); + private m_ExcludeNonHostPid = new Bool(); + private m_SelectionMethod: UInt32; // * NEX 3.0 + private m_VacantParticipants: UInt16; // * NEX 3.4 + private m_MatchmakeParam: MatchmakeParam; // * NEX 3.6 & revision 1 + private m_ExcludeUserPasswordSet: Bool; // * NEX 3.7 & revision 2 + private m_ExcludeSystemPasswordSet: Bool; // * NEX 3.7 & revision 2 + private m_ReferGid: UInt32; // * NEX 3.8 & revision 3 + private m_Codeword: RVString; // * NEX 4.0 + private m_ResultRange: ResultRange; // * NEX 4.0 + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_Attribs.extractFrom(stream); + this.m_GameMode.extractFrom(stream); + + if (semver.satisfies(stream.title.library_versions.match_making, '>=2.0.0')) { + this.m_MinParticipants = new RVString(); + this.m_MaxParticipants = new RVString(); + + this.m_MinParticipants.extractFrom(stream); + this.m_MaxParticipants.extractFrom(stream); + } + + this.m_MatchmakeSystemType.extractFrom(stream); + this.m_VacantOnly.extractFrom(stream); + this.m_ExcludeLocked.extractFrom(stream); + this.m_ExcludeNonHostPid.extractFrom(stream); + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.0.0')) { + this.m_SelectionMethod = new UInt32(); + this.m_SelectionMethod.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.4.0')) { + this.m_VacantParticipants = new UInt16(); + this.m_VacantParticipants.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.6.0')) { + this.m_MatchmakeParam = new MatchmakeParam(); + this.m_MatchmakeParam.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.7.0')) { + this.m_ExcludeUserPasswordSet = new Bool(); + this.m_ExcludeSystemPasswordSet = new Bool(); + + this.m_ExcludeUserPasswordSet.extractFrom(stream); + this.m_ExcludeSystemPasswordSet.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.8.0')) { + this.m_ReferGid = new UInt32(); + this.m_ReferGid.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) { + this.m_Codeword = new RVString(); + this.m_ResultRange = new ResultRange(); + + this.m_Codeword.extractFrom(stream); + this.m_ResultRange.extractFrom(stream); + } + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + const json: Record = { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_Attribs: this.m_Attribs, + m_GameMode: this.m_GameMode + } + }; + + if (this.m_MinParticipants !== undefined) { + json.__fields.m_MinParticipants = this.m_MinParticipants; + } + + if (this.m_MaxParticipants !== undefined) { + json.__fields.m_MaxParticipants = this.m_MaxParticipants; + } + + json.__fields.m_MatchmakeSystemType = this.m_MatchmakeSystemType; + json.__fields.m_VacantOnly = this.m_VacantOnly; + json.__fields.m_ExcludeLocked = this.m_ExcludeLocked; + json.__fields.m_ExcludeNonHostPid = this.m_ExcludeNonHostPid; + + if (this.m_SelectionMethod !== undefined) { + json.__fields.m_SelectionMethod = this.m_SelectionMethod; + } + + if (this.m_VacantParticipants !== undefined) { + json.__fields.m_VacantParticipants = this.m_VacantParticipants; + } + + if (this.m_MatchmakeParam !== undefined) { + json.__fields.m_MatchmakeParam = this.m_MatchmakeParam; + } + + if (this.m_ExcludeUserPasswordSet !== undefined) { + json.__fields.m_ExcludeUserPasswordSet = this.m_ExcludeUserPasswordSet; + } + + if (this.m_ExcludeSystemPasswordSet !== undefined) { + json.__fields.m_ExcludeSystemPasswordSet = this.m_ExcludeSystemPasswordSet; + } + + if (this.m_ReferGid !== undefined) { + json.__fields.m_ReferGid = this.m_ReferGid; + } + + if (this.m_Codeword !== undefined) { + json.__fields.m_Codeword = this.m_Codeword; + } + + if (this.m_ResultRange !== undefined) { + json.__fields.m_ResultRange = this.m_ResultRange; + } + + return json; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/matchmake-session.ts b/src/nex/protocols/match-making/types/matchmake-session.ts new file mode 100644 index 0000000..e844e1f --- /dev/null +++ b/src/nex/protocols/match-making/types/matchmake-session.ts @@ -0,0 +1,156 @@ +import semver from 'compare-versions'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import Bool from '@/nex/types/bool'; +import RVBuffer from '@/nex/types/buffer'; +import UInt8 from '@/nex/types/uint8'; +import DateTime from '@/nex/types/datetime'; +import RVString from '@/nex/types/string'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import Gathering from '@/nex/protocols/match-making/types/gathering'; +import MatchmakeParam from '@/nex/protocols/match-making/types/matchmake-param'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class MatchmakeSession extends Gathering { + public get typeName(): string { + return 'MatchmakeSession'; + } + + private m_GameMode = new UInt32(); + private m_Attribs = new List(new UInt32()); + private m_OpenParticipation = new Bool(); + private m_MatchmakeSystemType = new UInt32(); + private m_ApplicationBuffer = new RVBuffer(); + private m_ParticipationCount = new UInt32(); + private m_ProgressScore: UInt8; // * NEX 3.4 + private m_SessionKey: RVBuffer; // * NEX 3.0 + private m_Option0: UInt32; // * NEX 3.5 + private m_MatchmakeParam: MatchmakeParam; // * NEX 3.6 & revision 1 + private m_StartedTime: DateTime; // * NEX 3.6 & revision 1 + private m_UserPassword: RVString; // * NEX 3.7 & revision 2 + private m_ReferGid: UInt32; // * NEX 3.8 & revision 3 + private m_UserPasswordEnabled: Bool; // * NEX 3.8 & revision 3 + private m_SystemPasswordEnabled: Bool; // * NEX 3.8 & revision 3 + private m_Codeword: RVString; // * NEX 4.0 + + public extractFrom(stream: NEXByteStream): void { + super.extractFrom(stream); + + this.extractHeaderFrom(stream); + + this.m_GameMode.extractFrom(stream); + this.m_Attribs.extractFrom(stream); + this.m_OpenParticipation.extractFrom(stream); + this.m_MatchmakeSystemType.extractFrom(stream); + this.m_ApplicationBuffer.extractFrom(stream); + this.m_ParticipationCount.extractFrom(stream); + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.4.0')) { + this.m_ProgressScore = new UInt8(); + this.m_ProgressScore.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.0.0')) { + this.m_SessionKey = new RVBuffer(); + this.m_SessionKey.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.5.0')) { + this.m_Option0 = new UInt32(); + this.m_Option0.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.6.0')) { + this.m_MatchmakeParam = new MatchmakeParam(); + this.m_StartedTime = new DateTime(); + + this.m_MatchmakeParam.extractFrom(stream); + this.m_StartedTime.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.7.0')) { + this.m_UserPassword = new RVString(); + this.m_UserPassword.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.8.0')) { + this.m_ReferGid = new UInt32(); + this.m_UserPasswordEnabled = new Bool(); + this.m_SystemPasswordEnabled = new Bool(); + + this.m_ReferGid.extractFrom(stream); + this.m_UserPasswordEnabled.extractFrom(stream); + this.m_SystemPasswordEnabled.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) { + this.m_Codeword = new RVString(); + this.m_Codeword.extractFrom(stream); + } + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + const json: Record = { + __parent: super.toJSON(), + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_GameMode: this.m_GameMode, + m_Attribs: this.m_Attribs, + m_OpenParticipation: this.m_OpenParticipation, + m_MatchmakeSystemType: this.m_MatchmakeSystemType, + m_ApplicationBuffer: this.m_ApplicationBuffer, + m_ParticipationCount: this.m_ParticipationCount + } + }; + + if (this.m_ProgressScore !== undefined) { + json.__fields.m_ProgressScore = this.m_ProgressScore; + } + + if (this.m_SessionKey !== undefined) { + json.__fields.m_SessionKey = this.m_SessionKey; + } + + if (this.m_Option0 !== undefined) { + json.__fields.m_Option0 = this.m_Option0; + } + + if (this.m_MatchmakeParam !== undefined) { + json.__fields.m_MatchmakeParam = this.m_MatchmakeParam; + } + + if (this.m_StartedTime !== undefined) { + json.__fields.m_StartedTime = this.m_StartedTime; + } + + if (this.m_UserPassword !== undefined) { + json.__fields.m_UserPassword = this.m_UserPassword; + } + + if (this.m_ReferGid !== undefined) { + json.__fields.m_ReferGid = this.m_ReferGid; + } + + if (this.m_UserPasswordEnabled !== undefined) { + json.__fields.m_UserPasswordEnabled = this.m_UserPasswordEnabled; + } + + if (this.m_SystemPasswordEnabled !== undefined) { + json.__fields.m_SystemPasswordEnabled = this.m_SystemPasswordEnabled; + } + + if (this.m_Codeword !== undefined) { + json.__fields.m_Codeword = this.m_Codeword; + } + + return json; + } +} + +AnyDataHolder.Classes['MatchmakeSession'] = MatchmakeSession; \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/persistent-gathering.ts b/src/nex/protocols/match-making/types/persistent-gathering.ts new file mode 100644 index 0000000..4634af5 --- /dev/null +++ b/src/nex/protocols/match-making/types/persistent-gathering.ts @@ -0,0 +1,63 @@ +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import List from '@/nex/types/list'; +import RVBuffer from '@/nex/types/buffer'; +import DateTime from '@/nex/types/datetime'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import Gathering from '@/nex/protocols/match-making/types/gathering'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class PersistentGathering extends Gathering { + public get typeName(): string { + return 'PersistentGathering'; + } + + private m_CommunityType = new UInt32(); + private m_Password = new RVString(); + private m_Attribs = new List(new UInt32()); + private m_ApplicationBuffer = new RVBuffer(); + private m_ParticipationStartDate = new DateTime(); + private m_ParticipationEndDate = new DateTime(); + private m_MatchmakeSessionCount = new UInt32(); + private m_ParticipationCount = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + super.extractFrom(stream); + + this.extractHeaderFrom(stream); + + this.m_CommunityType.extractFrom(stream); + this.m_Password.extractFrom(stream); + this.m_Attribs.extractFrom(stream); + this.m_ApplicationBuffer.extractFrom(stream); + this.m_ParticipationStartDate.extractFrom(stream); + this.m_ParticipationEndDate.extractFrom(stream); + this.m_MatchmakeSessionCount.extractFrom(stream); + this.m_ParticipationCount.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __parent: super.toJSON(), + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_CommunityType: this.m_CommunityType, + m_Password: this.m_Password, + m_Attribs: this.m_Attribs, + m_ApplicationBuffer: this.m_ApplicationBuffer, + m_ParticipationStartDate: this.m_ParticipationStartDate, + m_ParticipationEndDate: this.m_ParticipationEndDate, + m_MatchmakeSessionCount: this.m_MatchmakeSessionCount, + m_ParticipationCount: this.m_ParticipationCount + } + }; + } +} + +AnyDataHolder.Classes['PersistentGathering'] = PersistentGathering; \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/playing-session.ts b/src/nex/protocols/match-making/types/playing-session.ts new file mode 100644 index 0000000..d8ba112 --- /dev/null +++ b/src/nex/protocols/match-making/types/playing-session.ts @@ -0,0 +1,34 @@ +import Structure from '@/nex/types/structure'; +import PID from '@/nex/types/pid'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class PlayingSession extends Structure { + public readonly typeName = 'PlayingSession'; + + private m_PrincipalId = new PID(); + private m_Gathering = new AnyDataHolder(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_PrincipalId.extractFrom(stream); + this.m_Gathering.extractFrom(stream); + } + + public new(): PlayingSession { + return new PlayingSession(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_PrincipalId: this.m_PrincipalId, + m_Gathering: this.m_Gathering + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/simple-playing-session.ts b/src/nex/protocols/match-making/types/simple-playing-session.ts new file mode 100644 index 0000000..e7c24cc --- /dev/null +++ b/src/nex/protocols/match-making/types/simple-playing-session.ts @@ -0,0 +1,40 @@ +import Structure from '@/nex/types/structure'; +import PID from '@/nex/types/pid'; +import UInt32 from '@/nex/types/uint32'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class SimplePlayingSession extends Structure { + public readonly typeName = 'SimplePlayingSession'; + + private m_PrincipalID = new PID(); + private m_GatheringID = new UInt32(); + private m_GameMode = new UInt32(); + private m_Attribute_0 = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_PrincipalID.extractFrom(stream); + this.m_GatheringID.extractFrom(stream); + this.m_GameMode.extractFrom(stream); + this.m_Attribute_0.extractFrom(stream); + } + + public new(): SimplePlayingSession { + return new SimplePlayingSession(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_PrincipalID: this.m_PrincipalID, + m_GatheringID: this.m_GatheringID, + m_GameMode: this.m_GameMode, + m_Attribute_0: this.m_Attribute_0 + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/index.ts b/src/nex/protocols/matchmake-extension/index.ts new file mode 100644 index 0000000..2af7fd4 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/index.ts @@ -0,0 +1,133 @@ +import RMCMessage from '@/nex/rmc-message'; +import * as Methods from '@/nex/protocols/matchmake-extension/methods'; +import type Packet from '@/types/nex/packet'; + +export default class MatchmakeExtensionProtocol { + static ID = 0x6D; + static Name = 'MatchmakeExtension'; + + static Methods = { + CloseParticipation: 0x1, + OpenParticipation: 0x2, + AutoMatchmake_Postpone: 0x3, + BrowseMatchmakeSession: 0x4, + BrowseMatchmakeSessionWithHostUrls: 0x5, + CreateMatchmakeSession: 0x6, + JoinMatchmakeSession: 0x7, + ModifyCurrentGameAttribute: 0x8, + UpdateNotificationData: 0x9, + GetFriendNotificationData: 0xA, + UpdateApplicationBuffer: 0xB, + UpdateMatchmakeSessionAttribute: 0xC, + GetlstFriendNotificationData: 0xD, + UpdateMatchmakeSession: 0xE, + AutoMatchmakeWithSearchCriteria_Postpone: 0xF, + GetPlayingSession: 0x10, + CreateCommunity: 0x11, + UpdateCommunity: 0x12, + JoinCommunity: 0x13, + FindCommunityByGatheringId: 0x14, + FindOfficialCommunity: 0x15, + FindCommunityByParticipant: 0x16, + UpdatePrivacySetting: 0x17, + GetMyBlackList: 0x18, + AddToBlackList: 0x19, + RemoveFromBlackList: 0x1A, + ClearMyBlackList: 0x1B, + ReportViolation: 0x1C, + IsViolationUser: 0x1D, + JoinMatchmakeSessionEx: 0x1E, + GetSimplePlayingSession: 0x1F, + GetSimpleCommunity: 0x20, + AutoMatchmakeWithGatheringId_Postpone: 0x21, + UpdateProgressScore: 0x22, + DebugNotifyEvent: 0x23, + GenerateMatchmakeSessionSystemPassword: 0x24, + ClearMatchmakeSessionSystemPassword: 0x25, + CreateMatchmakeSessionWithParam: 0x26, + JoinMatchmakeSessionWithParam: 0x27, + AutoMatchmakeWithParam_Postpone: 0x28, + FindMatchmakeSessionByGatheringIdDetail: 0x29, + BrowseMatchmakeSessionNoHolder: 0x2A, + BrowseMatchmakeSessionWithHostUrlsNoHolder: 0x2B, + UpdateMatchmakeSessionPart: 0x2C, + RequestMatchmakeExtension: 0x2D, + WithdrawMatchmakeExtension: 0x2E, + WithdrawMatchmakeExtensionAll: 0x2F, + FindMatchmakeSessionByGatheringId: 0x30, + FindMatchmakeSessionBySingleGatheringId: 0x31, + FindMatchmakeSessionByOwner: 0x32, + FindMatchmakeSessionByParticipant: 0x33, + BrowseMatchmakeSessionNoHolderNoResultRange: 0x34, + BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange: 0x35, + FindCommunityByOwner: 0x36 + }; + + private static handlers: Record any> = { + 0x1: MatchmakeExtensionProtocol.CloseParticipation, + 0x10: MatchmakeExtensionProtocol.GetPlayingSession, + 0x1F: MatchmakeExtensionProtocol.GetSimplePlayingSession, + 0x22: MatchmakeExtensionProtocol.UpdateProgressScore, + 0x28: MatchmakeExtensionProtocol.AutoMatchmakeWithParam_Postpone + }; + + static handlePacket(packet: Packet): void { + if (!packet.message) { + // * This will never happen. Only checked to make TypeScript happy + return; + } + + const methodID = packet.message.methodID; + const handler = MatchmakeExtensionProtocol.handlers[methodID]; + + if (!handler) { + packet.message.methodName = `UnknownMethod_0x${methodID.toString(16).toUpperCase().padStart(2, '0')}`; + return; + } + + const messageDecoder = handler(packet.message); + + packet.message.parameters = new messageDecoder(packet.message); + packet.message.methodName = messageDecoder.Name; + } + + private static CloseParticipation(message: RMCMessage): typeof Methods.CloseParticipation.Request | typeof Methods.CloseParticipation.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.CloseParticipation.Request; + } else { + return Methods.CloseParticipation.Response; + } + } + + private static GetPlayingSession(message: RMCMessage): typeof Methods.GetPlayingSession.Request | typeof Methods.GetPlayingSession.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetPlayingSession.Request; + } else { + return Methods.GetPlayingSession.Response; + } + } + + private static GetSimplePlayingSession(message: RMCMessage): typeof Methods.GetSimplePlayingSession.Request | typeof Methods.GetSimplePlayingSession.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetSimplePlayingSession.Request; + } else { + return Methods.GetSimplePlayingSession.Response; + } + } + + private static UpdateProgressScore(message: RMCMessage): typeof Methods.UpdateProgressScore.Request | typeof Methods.UpdateProgressScore.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateProgressScore.Request; + } else { + return Methods.UpdateProgressScore.Response; + } + } + + private static AutoMatchmakeWithParam_Postpone(message: RMCMessage): typeof Methods.AutoMatchmakeWithParam_Postpone.Request | typeof Methods.AutoMatchmakeWithParam_Postpone.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.AutoMatchmakeWithParam_Postpone.Request; + } else { + return Methods.AutoMatchmakeWithParam_Postpone.Response; + } + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone.ts b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone.ts new file mode 100644 index 0000000..db3535a --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone.ts @@ -0,0 +1,41 @@ +import NEXByteStream from '@/nex/byte-stream'; +import AutoMatchmakeParam from '@/nex/protocols/match-making/types/auto-matchmake-param'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/auto-matchmake-with-param-postpone'; + +export class Request { + public static Name = 'AutoMatchmakeWithParam_Postpone'; + + private autoMatchmakeParam = new AutoMatchmakeParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.autoMatchmakeParam.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + autoMatchmakeParam: this.autoMatchmakeParam + }; + } +} + +export class Response { + public static Name = 'AutoMatchmakeWithParam_Postpone'; + + private joinedMatchmakeSession = new MatchmakeSession(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.joinedMatchmakeSession.extractFrom(stream); + } + + public toJSON(): RMCs.Response { + return { + joinedMatchmakeSession: this.joinedMatchmakeSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/close-participation.ts b/src/nex/protocols/matchmake-extension/methods/close-participation.ts new file mode 100644 index 0000000..5c28589 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/close-participation.ts @@ -0,0 +1,33 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/close-participation'; + +export class Request { + public static Name = 'CloseParticipation'; + + private gid = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + gid: this.gid + }; + } +} + +// * No response data +export class Response { + public static Name = 'CloseParticipation'; + + constructor() {} + + public toJSON(): RMCs.Response { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/get-playing-session.ts b/src/nex/protocols/matchmake-extension/methods/get-playing-session.ts new file mode 100644 index 0000000..bc519b3 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/get-playing-session.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import PlayingSession from '@/nex/protocols/match-making/types/playing-session'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/get-playing-session'; + +export class Request { + public static Name = 'GetPlayingSession'; + + private lstPid = new List(new PID()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstPid.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + lstPid: this.lstPid + }; + } +} + +export class Response { + public static Name = 'GetPlayingSession'; + + private lstPlayingSession = new List(new PlayingSession()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstPlayingSession.extractFrom(stream); + } + + public toJSON(): RMCs.Response { + return { + lstPlayingSession: this.lstPlayingSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/get-simple-playing-session.ts b/src/nex/protocols/matchmake-extension/methods/get-simple-playing-session.ts new file mode 100644 index 0000000..8e482e1 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/get-simple-playing-session.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import Bool from '@/nex/types/bool'; +import SimplePlayingSession from '@/nex/protocols/match-making/types/simple-playing-session'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/get-simple-playing-session'; + +export class Request { + public static Name = 'GetSimplePlayingSession'; + + private lstPrincipalId = new List(new PID()); + private includeLoginUser = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstPrincipalId.extractFrom(stream); + this.includeLoginUser.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + lstPrincipalId: this.lstPrincipalId, + includeLoginUser: this.includeLoginUser + }; + } +} + +export class Response { + public static Name = 'GetSimplePlayingSession'; + + private lstSimplePlayingSession = new List(new SimplePlayingSession()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstSimplePlayingSession.extractFrom(stream); + } + + public toJSON(): RMCs.Response { + return { + lstSimplePlayingSession: this.lstSimplePlayingSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/index.ts b/src/nex/protocols/matchmake-extension/methods/index.ts new file mode 100644 index 0000000..d010873 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/index.ts @@ -0,0 +1,5 @@ +export * as CloseParticipation from '@/nex/protocols/matchmake-extension/methods/close-participation'; +export * as GetPlayingSession from '@/nex/protocols/matchmake-extension/methods/get-playing-session'; +export * as GetSimplePlayingSession from '@/nex/protocols/matchmake-extension/methods/get-simple-playing-session'; +export * as UpdateProgressScore from '@/nex/protocols/matchmake-extension/methods/update-progress-score'; +export * as AutoMatchmakeWithParam_Postpone from '@/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone'; \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/update-progress-score.ts b/src/nex/protocols/matchmake-extension/methods/update-progress-score.ts new file mode 100644 index 0000000..0614a38 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/update-progress-score.ts @@ -0,0 +1,37 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import UInt8 from '@/nex/types/uint8'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/update-progress-score'; + +export class Request { + public static Name = 'UpdateProgressScore'; + + private gid = new UInt32(); + private progressScore = new UInt8(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.progressScore.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + gid: this.gid, + progressScore: this.progressScore + }; + } +} + +// * No response data +export class Response { + public static Name = 'UpdateProgressScore'; + + constructor() {} + + public toJSON(): RMCs.Response { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/notification-events/types/notification-event.ts b/src/nex/protocols/notification-events/types/notification-event.ts index 40ba788..3bc7e10 100644 --- a/src/nex/protocols/notification-events/types/notification-event.ts +++ b/src/nex/protocols/notification-events/types/notification-event.ts @@ -5,7 +5,6 @@ import UInt32 from '@/nex/types/uint32'; import RVString from '@/nex/types/string'; import type NEXByteStream from '@/nex/byte-stream'; - // * ONLY IMPLEMENTS THE 3DS AND WII U VERSION! // * THE SWITCH USES A DIFFERENT STRUCTURE! export default class NotificationEvent extends Structure { diff --git a/src/types/nex/rmcs/matchmake-extension/auto-matchmake-with-param-postpone.ts b/src/types/nex/rmcs/matchmake-extension/auto-matchmake-with-param-postpone.ts new file mode 100644 index 0000000..72e9f8e --- /dev/null +++ b/src/types/nex/rmcs/matchmake-extension/auto-matchmake-with-param-postpone.ts @@ -0,0 +1,10 @@ +import type AutoMatchmakeParam from '@/nex/protocols/match-making/types/auto-matchmake-param'; +import type MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; + +export type Request = { + autoMatchmakeParam: AutoMatchmakeParam; +}; + +export type Response = { + joinedMatchmakeSession: MatchmakeSession; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/matchmake-extension/close-participation.ts b/src/types/nex/rmcs/matchmake-extension/close-participation.ts new file mode 100644 index 0000000..780c3ea --- /dev/null +++ b/src/types/nex/rmcs/matchmake-extension/close-participation.ts @@ -0,0 +1,7 @@ +import type UInt32 from '@/nex/types/uint32'; + +export type Request = { + gid: UInt32; +}; + +export type Response = object; // * No response data \ No newline at end of file diff --git a/src/types/nex/rmcs/matchmake-extension/get-playing-session.ts b/src/types/nex/rmcs/matchmake-extension/get-playing-session.ts new file mode 100644 index 0000000..8b8dd79 --- /dev/null +++ b/src/types/nex/rmcs/matchmake-extension/get-playing-session.ts @@ -0,0 +1,11 @@ +import type List from '@/nex/types/list'; +import type PID from '@/nex/types/pid'; +import type PlayingSession from '@/nex/protocols/match-making/types/playing-session'; + +export type Request = { + lstPid: List; +}; + +export type Response = { + lstPlayingSession: List; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/matchmake-extension/get-simple-playing-session.ts b/src/types/nex/rmcs/matchmake-extension/get-simple-playing-session.ts new file mode 100644 index 0000000..61dbe54 --- /dev/null +++ b/src/types/nex/rmcs/matchmake-extension/get-simple-playing-session.ts @@ -0,0 +1,13 @@ +import type List from '@/nex/types/list'; +import type PID from '@/nex/types/pid'; +import type Bool from '@/nex/types/bool'; +import type SimplePlayingSession from '@/nex/protocols/match-making/types/simple-playing-session'; + +export type Request = { + lstPrincipalId: List; + includeLoginUser: Bool; +}; + +export type Response = { + lstSimplePlayingSession: List; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/matchmake-extension/update-progress-score.ts b/src/types/nex/rmcs/matchmake-extension/update-progress-score.ts new file mode 100644 index 0000000..e28649a --- /dev/null +++ b/src/types/nex/rmcs/matchmake-extension/update-progress-score.ts @@ -0,0 +1,9 @@ +import type UInt32 from '@/nex/types/uint32'; +import type UInt8 from '@/nex/types/uint8'; + +export type Request = { + gid: UInt32; + progressScore: UInt8; +}; + +export type Response = object; // * No response data \ No newline at end of file From 00e504448d731bb2bf203b2abc1418a5c1d6a993 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Mon, 15 Jul 2024 22:36:51 -0400 Subject: [PATCH 49/67] chore: update account settings structure in README --- README.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 1b55577..9c6426c 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,26 @@ # NEX Viewer ### Utility for viewing PRUDP connections and NEX/Rendez-Vous sessions. -## NEX keys +## Settings / Accounts > [!WARNING] > Older versions of NEX Viewer precomputed the Kerberos keys for each password. These precomputed keys are NOT usable in newer versions of NEX Viewer. Password files must now always contain the raw game server password for each PID -In order to decrypt PRUDP packet payloads for the games secure server(s) your game server account credentials must be known by NEX Viewer. populate your credentials file in one of the following locations +In order to decrypt PRUDP packet payloads for the games secure server(s) your game server account credentials must be known by NEX Viewer. To add an account to the settings open one of the following JSON files: -- `%AppData%/NEXViewer/game-server-passwords.txt` (Windows) -- `~/.config/nex-viewer/game-server-passwords.txt` (Linux/MacOS) +- `%AppData%/NEXViewer/settings.json` (Windows) +- `~/.config/nex-viewer/settings.json` (Linux/MacOS) -`game-server-passwords.txt` must be in the following format: +From here add an account entry to the `accounts` array. An account entry takes the following form: -``` -PID:PASSWORD -PID:PASSWORD -PID:PASSWORD -PID:PASSWORD -etc... +```ts +{ + platform: string; // The platform the account is for (W ii U, 3DS, PC, etc.). Unused currently + username: string; // Account username. For NEX accounts this is your account PID as a string + pid: number; // Account unique PID + password: string; // Account password. Must not be hashed. Used to generate the below hashes, and those for non-NEX game servers + password_hash_old: string; // Pre-computed Kerberos key using the old key derivation method + password_hash_new: string; // Pre-computed Kerberos key using the new key derivation method +} ``` > [!CAUTION] From 291efade6be7638d93bc8d2d4289fd2863071d33 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Thu, 8 Aug 2024 11:29:32 -0400 Subject: [PATCH 50/67] feat: add MatchmakeExtension::FindOfficialCommunity --- .../protocols/matchmake-extension/index.ts | 9 ++++ .../methods/find-official-community.ts | 46 +++++++++++++++++++ .../matchmake-extension/methods/index.ts | 1 + 3 files changed, 56 insertions(+) create mode 100644 src/nex/protocols/matchmake-extension/methods/find-official-community.ts diff --git a/src/nex/protocols/matchmake-extension/index.ts b/src/nex/protocols/matchmake-extension/index.ts index 2af7fd4..6e90a0e 100644 --- a/src/nex/protocols/matchmake-extension/index.ts +++ b/src/nex/protocols/matchmake-extension/index.ts @@ -66,6 +66,7 @@ export default class MatchmakeExtensionProtocol { private static handlers: Record any> = { 0x1: MatchmakeExtensionProtocol.CloseParticipation, 0x10: MatchmakeExtensionProtocol.GetPlayingSession, + 0x15: MatchmakeExtensionProtocol.FindOfficialCommunity, 0x1F: MatchmakeExtensionProtocol.GetSimplePlayingSession, 0x22: MatchmakeExtensionProtocol.UpdateProgressScore, 0x28: MatchmakeExtensionProtocol.AutoMatchmakeWithParam_Postpone @@ -107,6 +108,14 @@ export default class MatchmakeExtensionProtocol { } } + private static FindOfficialCommunity(message: RMCMessage): typeof Methods.FindOfficialCommunity.Request | typeof Methods.FindOfficialCommunity.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindOfficialCommunity.Request; + } else { + return Methods.FindOfficialCommunity.Response; + } + } + private static GetSimplePlayingSession(message: RMCMessage): typeof Methods.GetSimplePlayingSession.Request | typeof Methods.GetSimplePlayingSession.Response { if (message.type === RMCMessage.REQUEST) { return Methods.GetSimplePlayingSession.Request; diff --git a/src/nex/protocols/matchmake-extension/methods/find-official-community.ts b/src/nex/protocols/matchmake-extension/methods/find-official-community.ts new file mode 100644 index 0000000..d2197e1 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/find-official-community.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import Bool from '@/nex/types/bool'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import PersistentGathering from '@/nex/protocols/match-making/types/persistent-gathering'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/find-official-community'; + +export class Request { + public static Name = 'FindOfficialCommunity'; + + private isAvailableOnly = new Bool(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.isAvailableOnly.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + isAvailableOnly: this.isAvailableOnly, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'FindOfficialCommunity'; + + private lstCommunity = new List(new PersistentGathering()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstCommunity.extractFrom(stream); + } + + public toJSON(): RMCs.Response { + return { + lstCommunity: this.lstCommunity + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/index.ts b/src/nex/protocols/matchmake-extension/methods/index.ts index d010873..b8f324c 100644 --- a/src/nex/protocols/matchmake-extension/methods/index.ts +++ b/src/nex/protocols/matchmake-extension/methods/index.ts @@ -1,5 +1,6 @@ export * as CloseParticipation from '@/nex/protocols/matchmake-extension/methods/close-participation'; export * as GetPlayingSession from '@/nex/protocols/matchmake-extension/methods/get-playing-session'; +export * as FindOfficialCommunity from '@/nex/protocols/matchmake-extension/methods/find-official-community'; export * as GetSimplePlayingSession from '@/nex/protocols/matchmake-extension/methods/get-simple-playing-session'; export * as UpdateProgressScore from '@/nex/protocols/matchmake-extension/methods/update-progress-score'; export * as AutoMatchmakeWithParam_Postpone from '@/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone'; \ No newline at end of file From 0d5d5effae1c407c007584ec1a2165261dd9d5c5 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Thu, 8 Aug 2024 11:29:59 -0400 Subject: [PATCH 51/67] feat: add FindOfficialCommunity RMC types --- .../matchmake-extension/find-official-community.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/types/nex/rmcs/matchmake-extension/find-official-community.ts diff --git a/src/types/nex/rmcs/matchmake-extension/find-official-community.ts b/src/types/nex/rmcs/matchmake-extension/find-official-community.ts new file mode 100644 index 0000000..873e505 --- /dev/null +++ b/src/types/nex/rmcs/matchmake-extension/find-official-community.ts @@ -0,0 +1,13 @@ +import type Bool from '@/nex/types/bool'; +import type ResultRange from '@/nex/types/result-range'; +import type List from '@/nex/types/list'; +import type PersistentGathering from '@/nex/protocols/match-making/types/persistent-gathering'; + +export type Request = { + isAvailableOnly: Bool; + resultRange: ResultRange; +}; + +export type Response = { + lstCommunity: List; +}; \ No newline at end of file From 4be2ccd97dab3d708f225bb34a3ff9a61ab4fa55 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Thu, 8 Aug 2024 11:30:24 -0400 Subject: [PATCH 52/67] fix: add p2p packet filtering checks --- src/nex/session.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/nex/session.ts b/src/nex/session.ts index 2ae00de..0ba27d0 100644 --- a/src/nex/session.ts +++ b/src/nex/session.ts @@ -12,6 +12,8 @@ import type Frame from '@/types/frame'; import type Packet from '@/types/nex/packet'; import type UDPPacket from '@/types/nex/udp-packet'; +const PIA_MAGIC = Buffer.from([ 0x32, 0xAB, 0x98, 0x64 ]); + function int2ip(int: number): string { return `${int >>> 24}.${int >> 16 & 255}.${int >> 8 & 255}.${int & 255}`; } @@ -97,8 +99,13 @@ export default class Session extends EventEmitter { try { if (this.rawRMCMode) { // * Raw RMC packets only include one packet per frame + // TODO - Can this contain PIA/Net-Z data as well? packets.push(new RawRMCPacket(new ByteStream(frame.data))); } else { + if (frame.data.subarray(0, 4).equals(PIA_MAGIC)) { + return packets; + } + const udpPacket = this.parseUDPPacket(frame.data); if (!udpPacket) { @@ -126,6 +133,18 @@ export default class Session extends EventEmitter { packet = new PRUDPPacketV0(stream); } + // * Try to filter out p2p traffic from both Net-Z and PIA sessions + // TODO - If we ever want to support viewing p2p traffic, remove these checks + if ( + packet.sourceStreamID === packet.destinationStreamID || // * Net-Z packets have the same IDs. NOTE: This MIGHT be possible in regular packets too? + packet.sourceStreamType === 0x1 || // * Source stream type is "DO" + packet.sourceStreamType === 0x5 || // * Source stream type is "NAT" + packet.destinationStreamType === 0x1 || // * Destination stream type is "DO" + packet.destinationStreamType === 0x5 // * Destination stream type is "NAT" + ) { + continue; + } + packet.sourceAddress = udpPacket.source; packet.sourcePort = udpPacket.sourcePort; packet.destinationAddress = udpPacket.destination; From 827d3d9c62ca60f58135df3bf27f1b8fe5e6f1ce Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Thu, 8 Aug 2024 11:48:42 -0400 Subject: [PATCH 53/67] fix: update PIA magic check --- src/nex/session.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/nex/session.ts b/src/nex/session.ts index 0ba27d0..b68e8a4 100644 --- a/src/nex/session.ts +++ b/src/nex/session.ts @@ -102,10 +102,6 @@ export default class Session extends EventEmitter { // TODO - Can this contain PIA/Net-Z data as well? packets.push(new RawRMCPacket(new ByteStream(frame.data))); } else { - if (frame.data.subarray(0, 4).equals(PIA_MAGIC)) { - return packets; - } - const udpPacket = this.parseUDPPacket(frame.data); if (!udpPacket) { @@ -118,7 +114,14 @@ export default class Session extends EventEmitter { while (stream.hasDataLeft()) { let packet: Packet; - const magic = stream.readBytes(0x2); + let magic = stream.readBytes(0x4); + stream.skip(-0x4); // * Skip back to realign the stream position + + if (magic.equals(PIA_MAGIC)) { + return packets; + } + + magic = stream.readBytes(0x2); stream.skip(-0x2); // * Skip back to realign the stream position if (magic.equals(PRUDPPacketV1.Magic)) { @@ -142,7 +145,7 @@ export default class Session extends EventEmitter { packet.destinationStreamType === 0x1 || // * Destination stream type is "DO" packet.destinationStreamType === 0x5 // * Destination stream type is "NAT" ) { - continue; + return packets; } packet.sourceAddress = udpPacket.source; From 933c66cd346498085ef8e2c56aca9b993d88c34e Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Fri, 9 Aug 2024 10:08:24 -0400 Subject: [PATCH 54/67] chore: improve PRUDP packet filtering --- src/nex/prudp-packet.ts | 44 ++------------------------- src/nex/prudp-packetv0.ts | 2 -- src/nex/prudp-packetv1.ts | 2 -- src/nex/session.ts | 64 +++++++++++++++++++++++++++++++++------ 4 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/nex/prudp-packet.ts b/src/nex/prudp-packet.ts index 4c72984..fe15523 100644 --- a/src/nex/prudp-packet.ts +++ b/src/nex/prudp-packet.ts @@ -57,46 +57,6 @@ export default class PRUDPPacket { this.stream = stream; } - protected validateVirtualPorts(): void { - if (this.sourceStreamType === 0 || this.sourceStreamType > 11) { - throw new Error('Invalid source stream type'); - } - - if (this.sourceStreamID === 0) { - throw new Error('Invalid source stream ID'); - } - - if (this.destinationStreamType === 0 || this.destinationStreamType > 11) { - throw new Error('Invalid destination stream type'); - } - - if (this.destinationStreamID === 0) { - throw new Error('Invalid source stream ID'); - } - - if (this.sourceStreamID === this.destinationStreamID) { - // * Likely a Quazal Net-Z packet - // ! NOTE - This WILL catch valid connections if the client uses 14 connections (making the server and client both use port 1) - throw new Error('Source and destination virtual ports are the same'); - } - - if (this.sourceStreamType === 1) { - throw new Error('Source stream type is DO'); - } - - if (this.sourceStreamType === 5) { - throw new Error('Source stream type is NAT'); - } - - if (this.destinationStreamType === 1) { - throw new Error('Destination stream type is DO'); - } - - if (this.destinationStreamType === 5) { - throw new Error('Destination stream type is NAT'); - } - } - private isType(type: number): boolean { return this.type === type; } @@ -230,7 +190,7 @@ export default class PRUDPPacket { return 'Relay'; } - throw new Error(`Unsupported stream type ${streamType}`); + return `UnknownStreamType_${streamType}`; } private serializeType(): string { @@ -254,7 +214,7 @@ export default class PRUDPPacket { return 'USER'; } - throw new Error(`Unsupported packet type ${this.type}`); + return `UnknownPacketType_${this.type}`; } private serializeFlags(): string[] { diff --git a/src/nex/prudp-packetv0.ts b/src/nex/prudp-packetv0.ts index 2965f0b..c61d64c 100644 --- a/src/nex/prudp-packetv0.ts +++ b/src/nex/prudp-packetv0.ts @@ -30,8 +30,6 @@ export default class PRUDPPacketV0 extends PRUDPPacket { this.destinationStreamType = destination >> 4; this.destinationStreamID = destination & 0xF; - this.validateVirtualPorts(); - // TODO - Quazal encoding? How do we tell the decoder the size BEFORE decoding? const typeAndFlags = this.stream.readUInt16LE(); diff --git a/src/nex/prudp-packetv1.ts b/src/nex/prudp-packetv1.ts index 733768c..ecdbfc4 100644 --- a/src/nex/prudp-packetv1.ts +++ b/src/nex/prudp-packetv1.ts @@ -57,8 +57,6 @@ export default class PRUDPPacketV1 extends PRUDPPacket { this.destinationStreamType = destination >> 4; this.destinationStreamID = destination & 0xF; - this.validateVirtualPorts(); - // TODO - Quazal encoding? How do we tell the decoder the size BEFORE decoding? const typeAndFlags = this.stream.readUInt16LE(); diff --git a/src/nex/session.ts b/src/nex/session.ts index b68e8a4..2795e5f 100644 --- a/src/nex/session.ts +++ b/src/nex/session.ts @@ -112,15 +112,16 @@ export default class Session extends EventEmitter { // * Some PRUDP packets are bundled together. Need to split them apart while (stream.hasDataLeft()) { + // TODO - The "return" statements here will exit this loop, potentially losing valid bundled packets later in the stream. Fix this? let packet: Packet; let magic = stream.readBytes(0x4); - stream.skip(-0x4); // * Skip back to realign the stream position if (magic.equals(PIA_MAGIC)) { return packets; } + stream.skip(-0x4); // * Skip back to realign the stream position magic = stream.readBytes(0x2); stream.skip(-0x2); // * Skip back to realign the stream position @@ -136,15 +137,7 @@ export default class Session extends EventEmitter { packet = new PRUDPPacketV0(stream); } - // * Try to filter out p2p traffic from both Net-Z and PIA sessions - // TODO - If we ever want to support viewing p2p traffic, remove these checks - if ( - packet.sourceStreamID === packet.destinationStreamID || // * Net-Z packets have the same IDs. NOTE: This MIGHT be possible in regular packets too? - packet.sourceStreamType === 0x1 || // * Source stream type is "DO" - packet.sourceStreamType === 0x5 || // * Source stream type is "NAT" - packet.destinationStreamType === 0x1 || // * Destination stream type is "DO" - packet.destinationStreamType === 0x5 // * Destination stream type is "NAT" - ) { + if (!this.validatePRUDPPacket(packet)) { return packets; } @@ -163,6 +156,57 @@ export default class Session extends EventEmitter { return packets; } + private validatePRUDPPacket(packet: Packet): boolean { + // * Try to filter out p2p traffic from both Net-Z and PIA sessions + // TODO - If we ever want to support viewing p2p traffic, remove these checks + if (packet.sourceStreamID === packet.destinationStreamID) { + // * Likely a Quazal Net-Z packet + // ! NOTE - This WILL catch valid connections if the client uses 14 connections (making the server and client both use port 1) + return false; + } + + if (packet.sourceStreamType === 1 || packet.destinationStreamType === 1) { + // * Packet uses the "DO" stream type + return false; + } + + if (packet.sourceStreamType === 5 || packet.destinationStreamType === 5) { + // * Packet uses the "NAT" stream type + return false; + } + + if (packet.sourceStreamType === 0 || packet.destinationStreamType === 0) { + // * Likely a Quazal Net-Z packet + return false; + } + + if (packet.sourceStreamID === 0 || packet.destinationStreamID === 0) { + // * Likely a Quazal Net-Z packet + return false; + } + + // * General sanity checks + if (packet.sourceStreamType > 11 || packet.destinationStreamType > 11) { + // * Stream type out of range + return false; + } + + if (packet.sourceStreamType > 11 || packet.destinationStreamType > 11) { + // * Stream type out of range + return false; + } + + if (packet.sourceStreamID !== 1 && packet.destinationStreamID !== 1) { + // * In NEX on the Wii U and 3DS the server stream ID is ALWAYS 1. IF NEITHER are 1, assume invalid + // TODO - THIS IS UNTESTED ON QRV, AND PRUDPLITE USES MORE SERVER STREAM IDS THAN JUST 1. TESTED AND UPDATE FOR PRUDPLITE + return false; + } + + // TODO - PRUDPLite packets can only have stream IDs ≤ 0x1F. Add check for this once PRUDPLite is implemented + + return true; + } + private parseUDPPacket(data: Buffer): UDPPacket | undefined { const stream = new ByteStream(data); From 6b49d49636b940e686dc4b29ade7d3969c8c5955 Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Tue, 7 Jan 2025 16:11:52 +1100 Subject: [PATCH 55/67] feat: Add AutoMatchmakeWithSearchCriteria_Postpone used in YKW2 and others --- .../protocols/matchmake-extension/index.ts | 13 ++++- ...matchmake-with-search-criteria-postpone.ts | 49 +++++++++++++++++++ .../matchmake-extension/methods/index.ts | 3 +- ...matchmake-with-search-criteria-postpone.ts | 14 ++++++ 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-search-criteria-postpone.ts create mode 100644 src/types/nex/rmcs/matchmake-extension/auto-matchmake-with-search-criteria-postpone.ts diff --git a/src/nex/protocols/matchmake-extension/index.ts b/src/nex/protocols/matchmake-extension/index.ts index 6e90a0e..0666bd8 100644 --- a/src/nex/protocols/matchmake-extension/index.ts +++ b/src/nex/protocols/matchmake-extension/index.ts @@ -65,11 +65,12 @@ export default class MatchmakeExtensionProtocol { private static handlers: Record any> = { 0x1: MatchmakeExtensionProtocol.CloseParticipation, + 0x0F: MatchmakeExtensionProtocol.AutoMatchmakeWithSearchCriteria_Postpone, 0x10: MatchmakeExtensionProtocol.GetPlayingSession, 0x15: MatchmakeExtensionProtocol.FindOfficialCommunity, 0x1F: MatchmakeExtensionProtocol.GetSimplePlayingSession, 0x22: MatchmakeExtensionProtocol.UpdateProgressScore, - 0x28: MatchmakeExtensionProtocol.AutoMatchmakeWithParam_Postpone + 0x28: MatchmakeExtensionProtocol.AutoMatchmakeWithParam_Postpone, }; static handlePacket(packet: Packet): void { @@ -139,4 +140,12 @@ export default class MatchmakeExtensionProtocol { return Methods.AutoMatchmakeWithParam_Postpone.Response; } } -} \ No newline at end of file + + private static AutoMatchmakeWithSearchCriteria_Postpone(message: RMCMessage): typeof Methods.AutoMatchmakeWithSearchCriteria_Postpone.Request | typeof Methods.AutoMatchmakeWithSearchCriteria_Postpone.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.AutoMatchmakeWithSearchCriteria_Postpone.Request; + } else { + return Methods.AutoMatchmakeWithSearchCriteria_Postpone.Response; + } + } +} diff --git a/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-search-criteria-postpone.ts b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-search-criteria-postpone.ts new file mode 100644 index 0000000..9002a80 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-search-criteria-postpone.ts @@ -0,0 +1,49 @@ +import NEXByteStream from '@/nex/byte-stream'; +import type RMCMessage from '@/nex/rmc-message'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import List from '@/nex/types/list'; +import MatchmakeSessionSearchCriteria from '@/nex/protocols/match-making/types/matchmake-session-search-criteria'; +import RVString from '@/nex/types/string'; +import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/auto-matchmake-with-search-criteria-postpone'; + +export class Request { + public static Name = 'AutoMatchmakeWithSearchCriteria_Postpone'; + + private criteria = new List(new MatchmakeSessionSearchCriteria()); + private gathering = new AnyDataHolder(); + private message = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.criteria.extractFrom(stream); + this.gathering.extractFrom(stream); + this.message.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + criteria: this.criteria, + gathering: this.gathering, + message: this.message, + }; + } +} + +export class Response { + public static Name = 'AutoMatchmakeWithSearchCriteria_Postpone'; + + private joinedMatchmakeSession = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.joinedMatchmakeSession.extractFrom(stream); + } + + public toJSON(): RMCs.Response { + return { + joinedMatchmakeSession: this.joinedMatchmakeSession + }; + } +} diff --git a/src/nex/protocols/matchmake-extension/methods/index.ts b/src/nex/protocols/matchmake-extension/methods/index.ts index b8f324c..7ae2733 100644 --- a/src/nex/protocols/matchmake-extension/methods/index.ts +++ b/src/nex/protocols/matchmake-extension/methods/index.ts @@ -3,4 +3,5 @@ export * as GetPlayingSession from '@/nex/protocols/matchmake-extension/methods/ export * as FindOfficialCommunity from '@/nex/protocols/matchmake-extension/methods/find-official-community'; export * as GetSimplePlayingSession from '@/nex/protocols/matchmake-extension/methods/get-simple-playing-session'; export * as UpdateProgressScore from '@/nex/protocols/matchmake-extension/methods/update-progress-score'; -export * as AutoMatchmakeWithParam_Postpone from '@/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone'; \ No newline at end of file +export * as AutoMatchmakeWithParam_Postpone from '@/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone'; +export * as AutoMatchmakeWithSearchCriteria_Postpone from '@/nex/protocols/matchmake-extension/methods/auto-matchmake-with-search-criteria-postpone'; diff --git a/src/types/nex/rmcs/matchmake-extension/auto-matchmake-with-search-criteria-postpone.ts b/src/types/nex/rmcs/matchmake-extension/auto-matchmake-with-search-criteria-postpone.ts new file mode 100644 index 0000000..c6cd72d --- /dev/null +++ b/src/types/nex/rmcs/matchmake-extension/auto-matchmake-with-search-criteria-postpone.ts @@ -0,0 +1,14 @@ +import AnyDataHolder from '@/nex/types/any-data-holder'; +import List from '@/nex/types/list'; +import type RVString from '@/nex/types/string'; +import MatchmakeSessionSearchCriteria from '@/nex/protocols/match-making/types/matchmake-session-search-criteria'; + +export type Request = { + criteria: List; + gathering: AnyDataHolder; + message: RVString; +}; + +export type Response = { + joinedMatchmakeSession: AnyDataHolder; +}; From d54ad6eaee88409175a60ee856d77e9fbc9277b7 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Tue, 7 Jan 2025 22:14:39 -0500 Subject: [PATCH 56/67] chore: update PRUDPPacketV1 code styles --- src/nex/prudp-packetv1.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nex/prudp-packetv1.ts b/src/nex/prudp-packetv1.ts index ecdbfc4..b2506f6 100644 --- a/src/nex/prudp-packetv1.ts +++ b/src/nex/prudp-packetv1.ts @@ -14,7 +14,7 @@ export default class PRUDPPacketV1 extends PRUDPPacket { private initialUnreliableSequenceID?: number; private maximumSubstreamID?: number; - static Magic = Buffer.from([0xEA, 0xD0]); + static Magic = Buffer.from([ 0xEA, 0xD0 ]); constructor(stream: ByteStream) { super(stream); @@ -82,17 +82,17 @@ export default class PRUDPPacketV1 extends PRUDPPacket { throw new Error('Invalid PRUDPv1 option ID'); } - if (optionID == 0 || optionID == 1 || optionID == 4) { + if (optionID === 0 || optionID === 1 || optionID === 4) { if (!this.isTypeSyn() && !this.isTypeConnect()) { throw new Error('Invalid PRUDPv1 option ID'); } } - if (optionID == 2 && !this.isTypeData()) { + if (optionID === 2 && !this.isTypeData()) { throw new Error('Invalid PRUDPv1 option ID'); } - if (optionID == 3 && !this.isTypeConnect()) { + if (optionID === 3 && !this.isTypeConnect()) { throw new Error('Invalid PRUDPv1 option ID'); } From 96615600464099ddcb3567b164466213500ba6b6 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Tue, 7 Jan 2025 22:39:39 -0500 Subject: [PATCH 57/67] feat: add Charles dump support and Switch packet support --- package-lock.json | 20 +- package.json | 1 + src/byte-stream.ts | 4 + src/charles-parser.ts | 304 ++++++++++++++++++ src/nex/connection.ts | 12 +- src/nex/protocols/ticket-granting/index.ts | 30 +- .../ticket-granting/methods/index.ts | 4 +- ...ate-and-request-ticket-with-custom-data.ts | 69 ++++ .../methods/validate-and-request-ticket.ts | 62 ++++ src/nex/prudp-packetLite.ts | 145 +++++++++ src/nex/session.ts | 43 ++- src/types/nex/packet.ts | 3 +- ...ate-and-request-ticket-with-custom-data.ts | 20 ++ .../validate-and-request-ticket.ts | 17 + src/types/nex/serialized-packet.ts | 9 +- src/windows/main/menu.ts | 2 +- 16 files changed, 728 insertions(+), 17 deletions(-) create mode 100644 src/charles-parser.ts create mode 100644 src/nex/protocols/ticket-granting/methods/validate-and-request-ticket-with-custom-data.ts create mode 100644 src/nex/protocols/ticket-granting/methods/validate-and-request-ticket.ts create mode 100644 src/nex/prudp-packetLite.ts create mode 100644 src/types/nex/rmcs/ticket-granting/validate-and-request-ticket-with-custom-data.ts create mode 100644 src/types/nex/rmcs/ticket-granting/validate-and-request-ticket.ts diff --git a/package-lock.json b/package-lock.json index 0da5db4..961ec0c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "AGPL-3.0", "dependencies": { + "@pretendonetwork/java.io": "^1.0.0", "@pretendonetwork/yeah": "^1.0.0", "compare-versions": "^6.1.1", "fs-extra": "^11.2.0", @@ -281,6 +282,11 @@ "node": ">=14" } }, + "node_modules/@pretendonetwork/java.io": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@pretendonetwork/java.io/-/java.io-1.0.0.tgz", + "integrity": "sha512-1xpu/EKtucpt4uEhtuYZq0mfcclqbskFcD7ACjMvsUZq2n0hzI0k94Ne3E5iNwJ4ug1qUp9YfvuRG4jQpAby2w==" + }, "node_modules/@pretendonetwork/yeah": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@pretendonetwork/yeah/-/yeah-1.0.0.tgz", @@ -1867,9 +1873,9 @@ } }, "node_modules/elliptic": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", - "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", + "version": "6.5.7", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", + "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", "dev": true, "dependencies": { "bn.js": "^4.11.9", @@ -3785,12 +3791,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { diff --git a/package.json b/package.json index b6bd191..5b36061 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "typescript-eslint": "^7.7.1" }, "dependencies": { + "@pretendonetwork/java.io": "^1.0.0", "@pretendonetwork/yeah": "^1.0.0", "compare-versions": "^6.1.1", "fs-extra": "^11.2.0", diff --git a/src/byte-stream.ts b/src/byte-stream.ts index f5e8b99..f308642 100644 --- a/src/byte-stream.ts +++ b/src/byte-stream.ts @@ -27,6 +27,10 @@ export default class ByteStream { this.offset = offset; } + public peek(): number { + return this.buffer[this.pos()]; + } + public read(len: number): Buffer { const read = this.buffer.subarray(this.pos(), this.pos() + len); this.offset += len; diff --git a/src/charles-parser.ts b/src/charles-parser.ts new file mode 100644 index 0000000..d02a000 --- /dev/null +++ b/src/charles-parser.ts @@ -0,0 +1,304 @@ +import { URL } from 'node:url'; +import { ObjectInputStream } from '@pretendonetwork/java.io'; +import ByteStream from '@/byte-stream'; +import type { + JavaObject, + JavaClassDesc +} from '@pretendonetwork/java.io'; + +export default class CharlesParser { + private buffer: Buffer; + private stream: ByteStream; + private _transactions: CharlesHTTPTransaction[] = []; + + constructor(buffer: Buffer) { + this.buffer = buffer; + this.stream = new ByteStream(this.buffer); + + this.parse(); + } + + private parse(): void { + const ois = new ObjectInputStream(this.stream); + const objects = ois.readAll(); + const session = objects[0]; + const transactionJSONs = this.getTransactionJSONs(session); + + for (const transactionJSON of transactionJSONs) { + const transaction = new CharlesHTTPTransaction(transactionJSON); + this._transactions.push(transaction); + } + } + + // * Extract all "com.xk72.charles.model.Transaction" objects from the session. + // * "com.xk72.charles.model.Transaction" is what stores the true request details. + private getTransactionJSONs(session: JavaObject): JavaObject[] { + const transactions: JavaObject[] = []; + const modelNode = session.description!.info.superClass!; // * These will always exist in this case. + const childrenArrayList = modelNode.classData.values.children.description; + const hosts = childrenArrayList.classData.annotation.splice(1); // * Index 0 is the capacity of the array as a buffer. + + // * Charles "com.xk72.charles.model.ModelNode" classes store the minimal number of + // * children possible. The children of "com.xk72.charles.model.Session" are all + // * "com.xk72.charles.model.Host" classes. If a new host is being requested then + // * a new "com.xk72.charles.model.Host" class instance is created. Otherwise an + // * existing instance is used. This means even if 100 requests were made, but only + // * to the same 2 hosts, only 2 "com.xk72.charles.model.Host" objects will exist here. + // * This also means request data is stored wildly out of order. + for (const host of hosts) { + const path = host.description.info.superClass; // * "com.xk72.charles.model.Host" extends "com.xk72.charles.model.Path". + transactions.push(...this.parsePath(path)); + } + + return transactions.sort((a, b) => { + // * Since transactions are stored out of order, need to reorder them. + const startTime1 = a.description!.classData.values.startTime.description.classData.annotation[0].data.readBigInt64BE(); + const startTime2 = b.description!.classData.values.startTime.description.classData.annotation[0].data.readBigInt64BE(); + + return Number(startTime1) - Number(startTime2); + }); + } + + // * Recursively parse "com.xk72.charles.model.Path" objects to find their transactions. + private parsePath(path: JavaClassDesc): JavaObject[] { + // * A "com.xk72.charles.model.Path" object has 2 points of interest: + // * - It's path value + // * - It's children array + // * Every "com.xk72.charles.model.Path" will hold one portion of the request path along with + // * a "java.util.ArrayList" of child objects. Each child may be either a "com.xk72.charles.model.Path" + // * object or a "com.xk72.charles.model.Transaction" object. If a child is a "com.xk72.charles.model.Transaction" + // * object then that child holds the full request details for a given path. If a child is a + // * "com.xk72.charles.model.Path" object then that child holds another portion of a different request path. + // * + // * For example if there was a request to both "https://account.nintendo.net/v1/api/people/@me/profile" and + // * "https://account.nintendo.net/v1/api/people/@me" then the session structure would look like: + // * + // * com.xk72.charles.model.Session + // * └── children + // * └── com.xk72.charles.model.Host (extends com.xk72.charles.model.Path) + // * └── children + // * └── com.xk72.charles.model.Path + // * ├── value: "v1" + // * └── children + // * └── com.xk72.charles.model.Path + // * ├── value: "api" + // * └── children + // * └── com.xk72.charles.model.Path + // * ├── value: "people" + // * └── children + // * └── com.xk72.charles.model.Path + // * ├── value: "@me" + // * └── children + // * ├── com.xk72.charles.model.Path + // * │ ├── value: "profile" + // * │ └── children + // * │ └── com.xk72.charles.model.Transaction + // * │ └── request data for "/v1/api/people/@me/profile" + // * └── com.xk72.charles.model.Transaction + // * └── request data for "/v1/api/people/@me" + + const transactions: JavaObject[] = []; + const modelNode = path.info.superClass!; // * This will always exist in this case. + const childrenArrayList = modelNode.classData.values.children.description; + const children = childrenArrayList.classData.annotation.splice(1); // * Index 0 is the capacity of the array as a buffer. + + for (const child of children) { + const className = child.description.className.value; + + if (className === 'com.xk72.charles.model.Path') { + transactions.push(...this.parsePath(child.description)); + } else { + transactions.push(child); + } + } + + return transactions; + } + + public *transactions(): Generator { + for (const transaction of this._transactions) { + yield transaction; + } + } +} + +export class CharlesWebSocketMessage { + private _source: 'CLIENT' | 'SERVER'; + private _type: 'BINARY'; + private _data: Buffer; + + // * Public getters + public get source(): 'CLIENT' | 'SERVER' { + return this._source; + } + + public get type(): 'BINARY' { + return this._type; + } + + public get data(): Buffer { + return this._data; + } + + constructor(messageJSON: JavaObject) { + if (!messageJSON.description) { + return; // * This will never happen in this case. + } + + this._source = messageJSON.description.classData.values.source.constant.value; + this._type = messageJSON.description.classData.values.type.constant.value; + this._data = Buffer.from(messageJSON.description.classData.values.content.values); + } +} + +export class CharlesHTTPRequest { + private _method: 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE'; + private _headers: { key: string; value: string }[] = []; + private _body?: Buffer; + + // * Public getters + public get method(): 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' { + return this._method; + } + + public get headers(): { key: string; value: string }[] { + return this._headers; + } + + public get body(): Buffer | undefined { + return this._body; + } + + constructor(transactionJSON: JavaObject) { + if (!transactionJSON.description) { + return; // * This will never happen in this case. + } + + this._method = transactionJSON.description.classData.values.scheme.value; + + for (let i = 1; i < transactionJSON.description.classData.values.requestHeader.description.classData.values.firstLine.description.classData.annotation.length; i++) { + const key = transactionJSON.description.classData.values.requestHeader.description.classData.values.firstLine.description.classData.annotation[i].value; + const value = transactionJSON.description.classData.values.requestHeader.description.classData.annotation[0].description.classData.annotation[i].value; + + this._headers.push({ key, value }); + } + + if (transactionJSON.description.classData.values.requestBody) { + this._body = Buffer.from(transactionJSON.description.classData.values.requestBody.values); + } + } +} + +export class CharlesHTTPResponse { + private _status: number; + private _headers: { key: string; value: string }[] = []; + private _body?: Buffer; + + // * Public getters + public get status(): number { + return this._status; + } + + public get headers(): { key: string; value: string }[] { + return this._headers; + } + + public get body(): Buffer | undefined { + return this._body; + } + + constructor(transactionJSON: JavaObject) { + if (!transactionJSON.description) { + return; // * This will never happen in this case. + } + + this._status = Number(transactionJSON.description.classData.values.responseHeader.description.classData.annotation[1].value.split(' ')[1]); + + for (let i = 1; i < transactionJSON.description.classData.values.responseHeader.description.classData.values.firstLine.description.classData.annotation.length; i++) { + const key = transactionJSON.description.classData.values.responseHeader.description.classData.values.firstLine.description.classData.annotation[i].value; + const value = transactionJSON.description.classData.values.responseHeader.description.classData.annotation[0].description.classData.annotation[i].value; + + this._headers.push({ key, value }); + } + + if (transactionJSON.description.classData.values.responseBody) { + this._body = Buffer.from(transactionJSON.description.classData.values.responseBody.values); + } + } +} + +export class CharlesHTTPTransaction { + private _url: URL; + private _clientLocalPort: number; + private _clientProxyPort: number; + private _serverLocalPort: number; + private _serverRemotePort: number; + private _request: CharlesHTTPRequest; + private _response: CharlesHTTPResponse; + private _websocketMessages: CharlesWebSocketMessage[] = []; + + // * Public getters + public get url(): URL { + return this._url; + } + + public get clientLocalPort(): number { + return this._clientLocalPort; + } + + public get clientProxyPort(): number { + return this._clientProxyPort; + } + + public get serverLocalPort(): number { + return this._serverLocalPort; + } + + public get serverRemotePort(): number { + return this._serverRemotePort; + } + + public get request(): CharlesHTTPRequest { + return this._request; + } + + public get response(): CharlesHTTPResponse { + return this._response; + } + + public get websocketMessages(): CharlesWebSocketMessage[] { + return this._websocketMessages; + } + + constructor(transactionJSON: JavaObject) { + if (!transactionJSON.description) { + return; // * This will never happen in this case. + } + + const protocol = transactionJSON.description.classData.values.protocol.value; + const host = transactionJSON.description.classData.values.host.value; + let path = ''; + + // * If the transaction has an error, this doesn't exist + // TODO - Track these errors + if (transactionJSON.description.classData.values.file) { + // * `file` contains the query string too + path = transactionJSON.description.classData.values.file.value; + } + + this._url = new URL(`${protocol}://${host}${path}`); + this._clientLocalPort = transactionJSON.description.classData.values.clientPort; + this._clientProxyPort = transactionJSON.description.classData.values.clientLocalPort; + this._serverLocalPort = transactionJSON.description.classData.values.remoteLocalPort; + this._serverRemotePort = transactionJSON.description.classData.values.actualPort; + this._request = new CharlesHTTPRequest(transactionJSON); + this._response = new CharlesHTTPResponse(transactionJSON); + + if (transactionJSON.description.classData.values.messages) { + for (const messageJSON of transactionJSON.description.classData.values.messages.description.classData.annotation.splice(1)) { + const message = new CharlesWebSocketMessage(messageJSON); + this._websocketMessages.push(message); + } + } + } +} \ No newline at end of file diff --git a/src/nex/connection.ts b/src/nex/connection.ts index caad54e..c1e32b9 100644 --- a/src/nex/connection.ts +++ b/src/nex/connection.ts @@ -119,7 +119,7 @@ export default class Connection { this.title = title; break; } - } else { + } else if (packet.version === 1) { // TODO - Legacy connection signature const connectionSignature = packet.fromClientToServer ? this.clientConnectionSignature : this.serverConnectionSignature; const expectedSignature = packet.signature; @@ -129,6 +129,14 @@ export default class Connection { this.title = title; break; } + } else if (packet.version === 2) { + const serverAddress = packet.sourceAddress === 'CLIENT' ? packet.destinationAddress : packet.sourceAddress; + const gameServerID = serverAddress.split('-')[0].slice(1); + + if (title.game_server_id === gameServerID) { + this.title = title; + break; + } } } } @@ -217,7 +225,9 @@ export default class Connection { packet.message.methodName = `UnknownMethod_0x${packet.message.methodID.toString(16).toUpperCase().padStart(2, '0')}`; } + // TODO - Skip this for PRUDPLite? This is only really done because payloads are encrypted and we need the key from the ticket, but Switch payloads aren't encrypted if (packet.message.protocolID === TicketGrantingProtocol.ID && !packet.message.error) { + // TODO - Add LoginWithContext/ValidateAndRequestTicketWithParam support here? const methodID = packet.message.methodID; if ( diff --git a/src/nex/protocols/ticket-granting/index.ts b/src/nex/protocols/ticket-granting/index.ts index e5ea73b..0b9c900 100644 --- a/src/nex/protocols/ticket-granting/index.ts +++ b/src/nex/protocols/ticket-granting/index.ts @@ -30,6 +30,12 @@ export default class TicketGrantingProtocol { 0x3: TicketGrantingProtocol.RequestTicket }; + private static handlersSwitch: Record any> = { + 0x1: TicketGrantingProtocol.ValidateAndRequestTicket, + 0x2: TicketGrantingProtocol.ValidateAndRequestTicketWithCustomData, + 0x3: TicketGrantingProtocol.RequestTicket + }; + static handlePacket(packet: Packet): void { if (!packet.message) { // * This will never happen. Only checked to make TypeScript happy @@ -37,9 +43,13 @@ export default class TicketGrantingProtocol { } const methodID = packet.message.methodID; + let handler; - // TODO - Use Switch names when parsing Switch packets - const handler = TicketGrantingProtocol.handlers[methodID]; + if (packet.version === 2) { + handler = TicketGrantingProtocol.handlersSwitch[methodID]; + } else { + handler = TicketGrantingProtocol.handlers[methodID]; + } if (!handler) { packet.message.methodName = `UnknownMethod_0x${methodID.toString(16).toUpperCase().padStart(2, '0')}`; @@ -75,4 +85,20 @@ export default class TicketGrantingProtocol { return Methods.RequestTicket.Response; } } + + private static ValidateAndRequestTicket(message: RMCMessage): typeof Methods.ValidateAndRequestTicket.Request | typeof Methods.ValidateAndRequestTicket.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ValidateAndRequestTicket.Request; + } else { + return Methods.ValidateAndRequestTicket.Response; + } + } + + private static ValidateAndRequestTicketWithCustomData(message: RMCMessage): typeof Methods.ValidateAndRequestTicketWithCustomData.Request | typeof Methods.ValidateAndRequestTicketWithCustomData.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ValidateAndRequestTicketWithCustomData.Request; + } else { + return Methods.ValidateAndRequestTicketWithCustomData.Response; + } + } } \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/index.ts b/src/nex/protocols/ticket-granting/methods/index.ts index aa65097..d22b7cd 100644 --- a/src/nex/protocols/ticket-granting/methods/index.ts +++ b/src/nex/protocols/ticket-granting/methods/index.ts @@ -1,3 +1,5 @@ export * as Login from '@/nex/protocols/ticket-granting/methods/login'; export * as LoginEx from '@/nex/protocols/ticket-granting/methods/login-ex'; -export * as RequestTicket from '@/nex/protocols/ticket-granting/methods/request-ticket'; \ No newline at end of file +export * as RequestTicket from '@/nex/protocols/ticket-granting/methods/request-ticket'; +export * as ValidateAndRequestTicket from '@/nex/protocols/ticket-granting/methods/validate-and-request-ticket'; +export * as ValidateAndRequestTicketWithCustomData from '@/nex/protocols/ticket-granting/methods/validate-and-request-ticket-with-custom-data'; \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/validate-and-request-ticket-with-custom-data.ts b/src/nex/protocols/ticket-granting/methods/validate-and-request-ticket-with-custom-data.ts new file mode 100644 index 0000000..6fb4679 --- /dev/null +++ b/src/nex/protocols/ticket-granting/methods/validate-and-request-ticket-with-custom-data.ts @@ -0,0 +1,69 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RVString from '@/nex/types/string'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import QResult from '@/nex/types/qresult'; +import PID from '@/nex/types/pid'; +import RVBuffer from '@/nex/types/buffer'; +import RVConnectionData from '@/nex/types/rv-connection-data'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/ticket-granting/validate-and-request-ticket-with-custom-data'; + +export class Request { + public static Name = 'ValidateAndRequestTicketWithCustomData'; + + private strUserName = new RVString(); + private oExtraData = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.strUserName.extractFrom(stream); + this.oExtraData.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + strUserName: this.strUserName, + oExtraData: this.oExtraData + }; + } +} + +export class Response { + public static Name = 'ValidateAndRequestTicketWithCustomData'; + + private retval = new QResult(); + private pidPrincipal = new PID(); + private pbufResponse = new RVBuffer(); + private pConnectionData = new RVConnectionData(); + private strReturnMsg = new RVString(); + private pSourceKey = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + + // * Wiki states: + // * "If the username does not exist, the %retval% field is set to RendezVous::InvalidUsername and the other fields are left blank." + // TODO - Is this handled correctly? + if (this.retval.isSuccess()) { + this.pidPrincipal.extractFrom(stream); + this.pbufResponse.extractFrom(stream); + this.pConnectionData.extractFrom(stream); + this.strReturnMsg.extractFrom(stream); + this.pSourceKey.extractFrom(stream); + } + } + + public toJSON(): RMCs.Response { + return { + retval: this.retval, + pidPrincipal: this.pidPrincipal, + pbufResponse: this.pbufResponse, + pConnectionData: this.pConnectionData, + strReturnMsg: this.strReturnMsg, + pSourceKey: this.pSourceKey + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/validate-and-request-ticket.ts b/src/nex/protocols/ticket-granting/methods/validate-and-request-ticket.ts new file mode 100644 index 0000000..42eabe5 --- /dev/null +++ b/src/nex/protocols/ticket-granting/methods/validate-and-request-ticket.ts @@ -0,0 +1,62 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RVString from '@/nex/types/string'; +import QResult from '@/nex/types/qresult'; +import PID from '@/nex/types/pid'; +import RVBuffer from '@/nex/types/buffer'; +import RVConnectionData from '@/nex/types/rv-connection-data'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/ticket-granting/validate-and-request-ticket'; + +export class Request { + public static Name = 'ValidateAndRequestTicket'; + + private strUserName = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.strUserName.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + strUserName: this.strUserName + }; + } +} + +export class Response { + public static Name = 'ValidateAndRequestTicket'; + + private retval = new QResult(); + private pidPrincipal = new PID(); + private pbufResponse = new RVBuffer(); + private pConnectionData = new RVConnectionData(); + private strReturnMsg = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + + // * Wiki states: + // * "If the username does not exist, the %retval% field is set to RendezVous::InvalidUsername and the other fields are left blank." + // TODO - Is this handled correctly? + if (this.retval.isSuccess()) { + this.pidPrincipal.extractFrom(stream); + this.pbufResponse.extractFrom(stream); + this.pConnectionData.extractFrom(stream); + this.strReturnMsg.extractFrom(stream); + } + } + + public toJSON(): RMCs.Response { + return { + retval: this.retval, + pidPrincipal: this.pidPrincipal, + pbufResponse: this.pbufResponse, + pConnectionData: this.pConnectionData, + strReturnMsg: this.strReturnMsg + }; + } +} \ No newline at end of file diff --git a/src/nex/prudp-packetLite.ts b/src/nex/prudp-packetLite.ts new file mode 100644 index 0000000..34dc187 --- /dev/null +++ b/src/nex/prudp-packetLite.ts @@ -0,0 +1,145 @@ +import crypto from 'node:crypto'; +import ByteStream from '@/byte-stream'; +import PRUDPPacket from '@/nex/prudp-packet'; +import type { SerializedPRUDPLitePacket } from '@/types/nex/serialized-packet'; + +export default class PRUDPPacketLite extends PRUDPPacket { + public readonly version = 2; + + private optionsLength: number; + private payloadLength: number; + private supportedFunctions?: Buffer; + private liteSignature?: Buffer; + + static Magic = Buffer.from([ 0x80 ]); + + constructor(stream: ByteStream) { + super(stream); + + this.substreamID = 0; + this.parse(); + } + + private parse(): void { + const magic = this.stream.readBytes(0x1); + + if (!magic.equals(PRUDPPacketLite.Magic)) { + throw new Error('Invalid PRUDPLite magic'); + } + + this.optionsLength = this.stream.readUInt8(); + this.payloadLength = this.stream.readUInt16LE(); + + const streamTypes = this.stream.readUInt8(); + + this.sourceStreamType = streamTypes >> 4; + this.destinationStreamType = streamTypes & 0x0F; + this.sourceStreamID = this.stream.readUInt8(); + this.destinationStreamID = this.stream.readUInt8(); + this.fragmentID = this.stream.readUInt8(); + + const typeAndFlags = this.stream.readUInt16LE(); + + this.flags = typeAndFlags >> 4; + this.type = typeAndFlags & 0xF; + this.sequenceID = this.stream.readUInt16LE(); + + this.parseOptions(); + this.payload = this.stream.readBytes(this.payloadLength); + } + + private parseOptions(): void { + const optionsStream = new ByteStream(this.stream.readBytes(this.optionsLength)); + + while (optionsStream.hasDataLeft()) { + const optionID = optionsStream.readUInt8(); + const optionSize = optionsStream.readUInt8(); + + if (optionID !== 0 && optionID !== 1 && optionID !== 0x80) { + throw new Error('Invalid PRUDPLite option ID'); + } + + if (optionID === 0) { + if (!this.isTypeSyn() && !this.isTypeConnect()) { + throw new Error('Invalid PRUDPLite option ID'); + } + } + + if (optionID === 1) { + if (!this.isTypeSyn()) { + throw new Error('Invalid PRUDPLite option ID'); + } + + if (!this.hasFlagAck()) { + throw new Error('Invalid PRUDPLite option ID'); + } + } + + if (optionID === 0x80) { + if (!this.isTypeConnect()) { + throw new Error('Invalid PRUDPLite option ID'); + } + + if (this.hasFlagAck()) { + throw new Error('Invalid PRUDPLite option ID'); + } + } + + if (optionID === 0) { + if (optionSize !== 4) { + throw new Error('Invalid PRUDPLite option ID'); + } + + this.supportedFunctions = optionsStream.readBytes(optionSize); + } + + if (optionID === 1) { + if (optionSize !== 16) { + throw new Error('Invalid PRUDPLite option ID'); + } + + this.connectionSignature = optionsStream.readBytes(optionSize); + } + + if (optionID === 0x80) { + if (optionSize !== 16) { + throw new Error('Invalid PRUDPLite option ID'); + } + + this.liteSignature = optionsStream.readBytes(optionSize); + } + } + } + + public calculateSignature(accessKey: string, connectionSignature: Buffer): Buffer { + const accessKeyBytes = Buffer.from(accessKey); + + const accessKeySum = accessKeyBytes.reduce((sum, byte) => sum + byte, 0); + const accessKeySumBytes = Buffer.alloc(4); + accessKeySumBytes.writeUInt32LE(accessKeySum, 0); + + const key = crypto.createHash('md5').update(accessKeyBytes).digest(); + const mac = crypto.createHmac('md5', key); + + mac.update(key); + mac.update(connectionSignature); + + return mac.digest(); + } + + public toJSON(): SerializedPRUDPLitePacket { + const serialized = this.serialize() as SerializedPRUDPLitePacket; + + serialized.substream_id = this.substreamID!; + + if (this.supportedFunctions) { + serialized.supported_functions = [...this.supportedFunctions.values()]; + } + + if (this.liteSignature) { + serialized.lite_signature = [...this.liteSignature.values()]; + } + + return serialized; + } +} \ No newline at end of file diff --git a/src/nex/session.ts b/src/nex/session.ts index 2795e5f..b581063 100644 --- a/src/nex/session.ts +++ b/src/nex/session.ts @@ -4,9 +4,11 @@ import fs from 'fs-extra'; import ByteStream from '@/byte-stream'; import PCAPParser from '@/pcap-parser'; import PCAPNGParser from '@/pcapng-parser'; +import CharlesParser from '@/charles-parser'; import Connection from '@/nex/connection'; -import PRUDPPacketV1 from '@/nex/prudp-packetv1'; import PRUDPPacketV0 from '@/nex/prudp-packetv0'; +import PRUDPPacketV1 from '@/nex/prudp-packetv1'; +import PRUDPPacketLite from '@/nex/prudp-packetLite'; import RawRMCPacket from '@/nex/raw-rmc-packet'; import type Frame from '@/types/frame'; import type Packet from '@/types/nex/packet'; @@ -32,10 +34,16 @@ export default class Session extends EventEmitter { public parse(capturePath: string): void { const extension = path.extname(capturePath); - if (extension !== '.pcapng' && extension !== '.pcap') { - throw new Error(`Invalid file type. Got ${extension}, expected .pcapng or .pcap`); + if (extension === '.pcapng' || extension === '.pcap') { + this.parsePCAP(capturePath); + } else if (extension === '.chls') { + this.parseCharles(capturePath); + } else { + throw new Error(`Invalid file type. Got ${extension}, expected .pcapng, .pcap or .chls`); } + } + private parsePCAP(capturePath: string): void { const captureData = fs.readFileSync(capturePath); let parser; @@ -66,6 +74,35 @@ export default class Session extends EventEmitter { this.emit('finished', this.connections); } + private parseCharles(capturePath: string): void { + const captureData = fs.readFileSync(capturePath); + const parser = new CharlesParser(captureData); + + for (const transaction of parser.transactions()) { + for (const message of transaction.websocketMessages) { + const stream = new ByteStream(message.data); + const packet = new PRUDPPacketLite(stream); + + if (message.source === 'SERVER') { + packet.sourceAddress = transaction.url.host; + packet.sourcePort = transaction.serverLocalPort; + packet.destinationAddress = 'CLIENT'; + packet.destinationPort = transaction.clientLocalPort; + } else { + packet.sourceAddress = 'CLIENT'; + packet.sourcePort = transaction.clientLocalPort; + packet.destinationAddress = transaction.url.host; + packet.destinationPort = transaction.serverLocalPort; + } + + this.processPacket(packet); + this.emit('packet', packet); + } + } + + this.emit('finished', this.connections); + } + private handlePacket(frame: Frame, time?: number): void { // * HokakuCTR produces dumps whose payloads are: // * - u8 Revision (1) diff --git a/src/types/nex/packet.ts b/src/types/nex/packet.ts index f1537e7..8b16a97 100644 --- a/src/types/nex/packet.ts +++ b/src/types/nex/packet.ts @@ -1,7 +1,8 @@ import type PRUDPPacketV0 from '@/nex/prudp-packetv0'; import type PRUDPPacketV1 from '@/nex/prudp-packetv1'; +import type PRUDPPacketLite from '@/nex/prudp-packetLite'; import type RawRMCPacket from '@/nex/raw-rmc-packet'; -type Packet = PRUDPPacketV0 | PRUDPPacketV1 | RawRMCPacket; +type Packet = PRUDPPacketV0 | PRUDPPacketV1 | PRUDPPacketLite | RawRMCPacket; export default Packet; \ No newline at end of file diff --git a/src/types/nex/rmcs/ticket-granting/validate-and-request-ticket-with-custom-data.ts b/src/types/nex/rmcs/ticket-granting/validate-and-request-ticket-with-custom-data.ts new file mode 100644 index 0000000..9feca07 --- /dev/null +++ b/src/types/nex/rmcs/ticket-granting/validate-and-request-ticket-with-custom-data.ts @@ -0,0 +1,20 @@ +import type RVString from '@/nex/types/string'; +import type AnyDataHolder from '@/nex/types/any-data-holder'; +import type QResult from '@/nex/types/qresult'; +import type PID from '@/nex/types/pid'; +import type RVBuffer from '@/nex/types/buffer'; +import type RVConnectionData from '@/nex/types/rv-connection-data'; + +export type Request = { + strUserName: RVString; + oExtraData: AnyDataHolder; +}; + +export type Response = { + retval: QResult; + pidPrincipal: PID; + pbufResponse: RVBuffer; + pConnectionData: RVConnectionData; + strReturnMsg: RVString; + pSourceKey: RVString; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/ticket-granting/validate-and-request-ticket.ts b/src/types/nex/rmcs/ticket-granting/validate-and-request-ticket.ts new file mode 100644 index 0000000..b995f59 --- /dev/null +++ b/src/types/nex/rmcs/ticket-granting/validate-and-request-ticket.ts @@ -0,0 +1,17 @@ +import type RVString from '@/nex/types/string'; +import type QResult from '@/nex/types/qresult'; +import type PID from '@/nex/types/pid'; +import type RVBuffer from '@/nex/types/buffer'; +import type RVConnectionData from '@/nex/types/rv-connection-data'; + +export type Request = { + strUserName: RVString; +}; + +export type Response = { + retval: QResult; + pidPrincipal: PID; + pbufResponse: RVBuffer; + pConnectionData: RVConnectionData; + strReturnMsg: RVString; +}; \ No newline at end of file diff --git a/src/types/nex/serialized-packet.ts b/src/types/nex/serialized-packet.ts index 3121e07..c1b8932 100644 --- a/src/types/nex/serialized-packet.ts +++ b/src/types/nex/serialized-packet.ts @@ -38,6 +38,13 @@ export type SerializedPRUDPV1Packet = SerializedPRUDPPacket & { maximum_substream_id?: number; }; -type SerializedPacket = SerializedPRUDPPacket | SerializedPRUDPV0Packet | SerializedPRUDPV1Packet; +export type SerializedPRUDPLitePacket = SerializedPRUDPPacket & { + version: 2; + substream_id: number; + supported_functions?: number[]; + lite_signature?: number[]; +}; + +type SerializedPacket = SerializedPRUDPPacket | SerializedPRUDPV0Packet | SerializedPRUDPV1Packet | SerializedPRUDPLitePacket; export default SerializedPacket; \ No newline at end of file diff --git a/src/windows/main/menu.ts b/src/windows/main/menu.ts index 479a283..b3cb2f5 100644 --- a/src/windows/main/menu.ts +++ b/src/windows/main/menu.ts @@ -66,7 +66,7 @@ export default function createMenu(state: State): Menu { const result = await dialog.showOpenDialog({ properties: ['openFile'], filters: [ - { name: 'Packet Capture', extensions: ['pcapng', 'pcap'] } + { name: 'Packet Capture', extensions: ['pcapng', 'pcap', 'chls'] } ] }); From 80a89d6f1c794a379ae4a9699673a94e05ef4ad0 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Tue, 7 Jan 2025 23:11:35 -0500 Subject: [PATCH 58/67] feat: complete TicketGranting protocol --- src/nex/protocols/ticket-granting/index.ts | 42 ++++++++++++- .../ticket-granting/methods/get-name.ts | 41 +++++++++++++ .../ticket-granting/methods/get-pid.ts | 41 +++++++++++++ .../ticket-granting/methods/index.ts | 4 ++ .../methods/login-with-context.ts | 60 +++++++++++++++++++ .../validate-and-request-ticket-with-param.ts | 41 +++++++++++++ .../types/authentication-info.ts | 49 +++++++++++++++ .../ticket-granting/types/null-data.ts | 33 ++++++++++ .../validate-and-request-ticket-param.ts | 50 ++++++++++++++++ .../validate-and-request-ticket-result.ts | 49 +++++++++++++++ .../nex/rmcs/ticket-granting/get-name.ts | 10 ++++ src/types/nex/rmcs/ticket-granting/get-pid.ts | 10 ++++ .../ticket-granting/login-with-context.ts | 16 +++++ .../validate-and-request-ticket-with-param.ts | 10 ++++ 14 files changed, 454 insertions(+), 2 deletions(-) create mode 100644 src/nex/protocols/ticket-granting/methods/get-name.ts create mode 100644 src/nex/protocols/ticket-granting/methods/get-pid.ts create mode 100644 src/nex/protocols/ticket-granting/methods/login-with-context.ts create mode 100644 src/nex/protocols/ticket-granting/methods/validate-and-request-ticket-with-param.ts create mode 100644 src/nex/protocols/ticket-granting/types/authentication-info.ts create mode 100644 src/nex/protocols/ticket-granting/types/null-data.ts create mode 100644 src/nex/protocols/ticket-granting/types/validate-and-request-ticket-param.ts create mode 100644 src/nex/protocols/ticket-granting/types/validate-and-request-ticket-result.ts create mode 100644 src/types/nex/rmcs/ticket-granting/get-name.ts create mode 100644 src/types/nex/rmcs/ticket-granting/get-pid.ts create mode 100644 src/types/nex/rmcs/ticket-granting/login-with-context.ts create mode 100644 src/types/nex/rmcs/ticket-granting/validate-and-request-ticket-with-param.ts diff --git a/src/nex/protocols/ticket-granting/index.ts b/src/nex/protocols/ticket-granting/index.ts index 0b9c900..138a1d6 100644 --- a/src/nex/protocols/ticket-granting/index.ts +++ b/src/nex/protocols/ticket-granting/index.ts @@ -27,13 +27,19 @@ export default class TicketGrantingProtocol { private static handlers: Record any> = { 0x1: TicketGrantingProtocol.Login, 0x2: TicketGrantingProtocol.LoginEx, - 0x3: TicketGrantingProtocol.RequestTicket + 0x3: TicketGrantingProtocol.RequestTicket, + 0x4: TicketGrantingProtocol.GetPID, + 0x5: TicketGrantingProtocol.GetName, + 0x6: TicketGrantingProtocol.LoginWithContext }; private static handlersSwitch: Record any> = { 0x1: TicketGrantingProtocol.ValidateAndRequestTicket, 0x2: TicketGrantingProtocol.ValidateAndRequestTicketWithCustomData, - 0x3: TicketGrantingProtocol.RequestTicket + 0x3: TicketGrantingProtocol.RequestTicket, + 0x4: TicketGrantingProtocol.GetPID, + 0x5: TicketGrantingProtocol.GetName, + 0x6: TicketGrantingProtocol.ValidateAndRequestTicketWithParam }; static handlePacket(packet: Packet): void { @@ -86,6 +92,22 @@ export default class TicketGrantingProtocol { } } + private static GetPID(message: RMCMessage): typeof Methods.GetPID.Request | typeof Methods.GetPID.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetPID.Request; + } else { + return Methods.GetPID.Response; + } + } + + private static GetName(message: RMCMessage): typeof Methods.GetName.Request | typeof Methods.GetName.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetName.Request; + } else { + return Methods.GetName.Response; + } + } + private static ValidateAndRequestTicket(message: RMCMessage): typeof Methods.ValidateAndRequestTicket.Request | typeof Methods.ValidateAndRequestTicket.Response { if (message.type === RMCMessage.REQUEST) { return Methods.ValidateAndRequestTicket.Request; @@ -101,4 +123,20 @@ export default class TicketGrantingProtocol { return Methods.ValidateAndRequestTicketWithCustomData.Response; } } + + private static LoginWithContext(message: RMCMessage): typeof Methods.LoginWithContext.Request | typeof Methods.LoginWithContext.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.LoginWithContext.Request; + } else { + return Methods.LoginWithContext.Response; + } + } + + private static ValidateAndRequestTicketWithParam(message: RMCMessage): typeof Methods.ValidateAndRequestTicketWithParam.Request | typeof Methods.ValidateAndRequestTicketWithParam.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ValidateAndRequestTicketWithParam.Request; + } else { + return Methods.ValidateAndRequestTicketWithParam.Response; + } + } } \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/get-name.ts b/src/nex/protocols/ticket-granting/methods/get-name.ts new file mode 100644 index 0000000..1173094 --- /dev/null +++ b/src/nex/protocols/ticket-granting/methods/get-name.ts @@ -0,0 +1,41 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RVString from '@/nex/types/string'; +import PID from '@/nex/types/pid'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/ticket-granting/get-name'; + +export class Request { + public static Name = 'GetName'; + + private id = new PID(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.id.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + id: this.id + }; + } +} + +export class Response { + public static Name = 'GetName'; + + private retval = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): RMCs.Response { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/get-pid.ts b/src/nex/protocols/ticket-granting/methods/get-pid.ts new file mode 100644 index 0000000..7a72057 --- /dev/null +++ b/src/nex/protocols/ticket-granting/methods/get-pid.ts @@ -0,0 +1,41 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RVString from '@/nex/types/string'; +import PID from '@/nex/types/pid'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/ticket-granting/get-pid'; + +export class Request { + public static Name = 'GetPID'; + + private strUserName = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.strUserName.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + strUserName: this.strUserName + }; + } +} + +export class Response { + public static Name = 'GetPID'; + + private retval = new PID(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): RMCs.Response { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/index.ts b/src/nex/protocols/ticket-granting/methods/index.ts index d22b7cd..0955ed5 100644 --- a/src/nex/protocols/ticket-granting/methods/index.ts +++ b/src/nex/protocols/ticket-granting/methods/index.ts @@ -1,5 +1,9 @@ export * as Login from '@/nex/protocols/ticket-granting/methods/login'; export * as LoginEx from '@/nex/protocols/ticket-granting/methods/login-ex'; export * as RequestTicket from '@/nex/protocols/ticket-granting/methods/request-ticket'; +export * as GetPID from '@/nex/protocols/ticket-granting/methods/get-pid'; +export * as GetName from '@/nex/protocols/ticket-granting/methods/get-name'; +export * as LoginWithContext from '@/nex/protocols/ticket-granting/methods/login-with-context'; +export * as ValidateAndRequestTicketWithParam from '@/nex/protocols/ticket-granting/methods/validate-and-request-ticket-with-param'; export * as ValidateAndRequestTicket from '@/nex/protocols/ticket-granting/methods/validate-and-request-ticket'; export * as ValidateAndRequestTicketWithCustomData from '@/nex/protocols/ticket-granting/methods/validate-and-request-ticket-with-custom-data'; \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/login-with-context.ts b/src/nex/protocols/ticket-granting/methods/login-with-context.ts new file mode 100644 index 0000000..b243433 --- /dev/null +++ b/src/nex/protocols/ticket-granting/methods/login-with-context.ts @@ -0,0 +1,60 @@ +import NEXByteStream from '@/nex/byte-stream'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import QResult from '@/nex/types/qresult'; +import PID from '@/nex/types/pid'; +import RVBuffer from '@/nex/types/buffer'; +import RVConnectionData from '@/nex/types/rv-connection-data'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/ticket-granting/login-with-context'; + + +export class Request { + public static Name = 'LoginWithContext'; + + private loginData = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.loginData.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + loginData: this.loginData + }; + } +} + +export class Response { + public static Name = 'LoginWithContext'; + + private retval = new QResult(); + private pidPrincipal = new PID(); + private pbufResponse = new RVBuffer(); + private pConnectionData = new RVConnectionData(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + + // * Wiki states: + // * "If the username does not exist, the %retval% field is set to RendezVous::InvalidUsername and the other fields are left blank." + // TODO - Is this handled correctly? + if (this.retval.isSuccess()) { + this.pidPrincipal.extractFrom(stream); + this.pbufResponse.extractFrom(stream); + this.pConnectionData.extractFrom(stream); + } + } + + public toJSON(): RMCs.Response { + return { + retval: this.retval, + pidPrincipal: this.pidPrincipal, + pbufResponse: this.pbufResponse, + pConnectionData: this.pConnectionData + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/methods/validate-and-request-ticket-with-param.ts b/src/nex/protocols/ticket-granting/methods/validate-and-request-ticket-with-param.ts new file mode 100644 index 0000000..9633f49 --- /dev/null +++ b/src/nex/protocols/ticket-granting/methods/validate-and-request-ticket-with-param.ts @@ -0,0 +1,41 @@ +import NEXByteStream from '@/nex/byte-stream'; +import ValidateAndRequestTicketParam from '@/nex/protocols/ticket-granting/types/validate-and-request-ticket-param'; +import ValidateAndRequestTicketResult from '@/nex/protocols/ticket-granting/types/validate-and-request-ticket-result'; +import type RMCMessage from '@/nex/rmc-message'; +import type * as RMCs from '@/types/nex/rmcs/ticket-granting/validate-and-request-ticket-with-param'; + +export class Request { + public static Name = 'ValidateAndRequestTicket'; + + private param = new ValidateAndRequestTicketParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.param.extractFrom(stream); + } + + public toJSON(): RMCs.Request { + return { + param: this.param + }; + } +} + +export class Response { + public static Name = 'ValidateAndRequestTicket'; + + private result = new ValidateAndRequestTicketResult(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.result.extractFrom(stream); + } + + public toJSON(): RMCs.Response { + return { + result: this.result + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/types/authentication-info.ts b/src/nex/protocols/ticket-granting/types/authentication-info.ts new file mode 100644 index 0000000..68bc2a4 --- /dev/null +++ b/src/nex/protocols/ticket-granting/types/authentication-info.ts @@ -0,0 +1,49 @@ +import Data from '@/nex/types/data'; +import RVString from '@/nex/types/string'; +import UInt32 from '@/nex/types/uint32'; +import UInt8 from '@/nex/types/uint8'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class AuthenticationInfo extends Data { + public get typeName(): string { + return 'AuthenticationInfo'; + } + + private m_authToken = new RVString(); + private m_ngsVersion = new UInt32(); + private m_authTokenType = new UInt8(); + private m_serverVersion = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + super.extractFrom(stream); + + this.extractHeaderFrom(stream); + + this.m_authToken.extractFrom(stream); + this.m_ngsVersion.extractFrom(stream); + this.m_authTokenType.extractFrom(stream); + this.m_serverVersion.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __parent: super.toJSON(), + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_authToken: this.m_authToken, + m_ngsVersion: this.m_ngsVersion, + m_authTokenType: this.m_authTokenType, + m_serverVersion: this.m_serverVersion + } + }; + } +} + +AnyDataHolder.Classes['AuthenticationInfo'] = AuthenticationInfo; \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/types/null-data.ts b/src/nex/protocols/ticket-granting/types/null-data.ts new file mode 100644 index 0000000..aaf4a65 --- /dev/null +++ b/src/nex/protocols/ticket-granting/types/null-data.ts @@ -0,0 +1,33 @@ +import Data from '@/nex/types/data'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type NEXByteStream from '@/nex/byte-stream'; + +// TODO - Is this used in places outside of TicketGranting? If so, we need to move it +// * NullData represents an empty object, intended to have no fields +export default class NullData extends Data { + public get typeName(): string { + return 'NullData'; + } + + public extractFrom(stream: NEXByteStream): void { + super.extractFrom(stream); + + this.extractHeaderFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __parent: super.toJSON(), + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: {} + }; + } +} + +AnyDataHolder.Classes['NullData'] = NullData; \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/types/validate-and-request-ticket-param.ts b/src/nex/protocols/ticket-granting/types/validate-and-request-ticket-param.ts new file mode 100644 index 0000000..ffa95c5 --- /dev/null +++ b/src/nex/protocols/ticket-granting/types/validate-and-request-ticket-param.ts @@ -0,0 +1,50 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import Bool from '@/nex/types/bool'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class ValidateAndRequestTicketParam extends Structure { + public readonly typeName = 'ValidateAndRequestTicketParam'; + + private platformType = new UInt32(); + private userName = new RVString(); + private extraData = new AnyDataHolder(); + private ignoreApiVersionCheck = new Bool(); + private apiVersionGeneral = new UInt32(); + private apiVersionCustom = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.platformType.extractFrom(stream); + this.userName.extractFrom(stream); + this.extraData.extractFrom(stream); + this.ignoreApiVersionCheck.extractFrom(stream); + this.apiVersionGeneral.extractFrom(stream); + this.apiVersionCustom.extractFrom(stream); + } + + public new(): ValidateAndRequestTicketParam { + return new ValidateAndRequestTicketParam(); + } + + public toJSON(): Record { + const json: Record = { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + platformType: this.platformType, + userName: this.userName, + extraData: this.extraData, + ignoreApiVersionCheck: this.ignoreApiVersionCheck, + apiVersionGeneral: this.apiVersionGeneral, + apiVersionCustom: this.apiVersionCustom + } + }; + + return json; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ticket-granting/types/validate-and-request-ticket-result.ts b/src/nex/protocols/ticket-granting/types/validate-and-request-ticket-result.ts new file mode 100644 index 0000000..9d1a52f --- /dev/null +++ b/src/nex/protocols/ticket-granting/types/validate-and-request-ticket-result.ts @@ -0,0 +1,49 @@ +import Structure from '@/nex/types/structure'; +import PID from '@/nex/types/pid'; +import RVBuffer from '@/nex/types/buffer'; +import StationURL from '@/nex/types/station-url'; +import DateTime from '@/nex/types/datetime'; +import RVString from '@/nex/types/string'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class ValidateAndRequestTicketResult extends Structure { + public readonly typeName = 'ValidateAndRequestTicketResult'; + + private sourcePid = new PID(); + private bufResponse = new RVBuffer(); + private serviceNodeUrl = new StationURL(); + private currentUtcTime = new DateTime(); + private returnMsg = new RVString(); + private sourceKey = new RVString(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.sourcePid.extractFrom(stream); + this.bufResponse.extractFrom(stream); + this.serviceNodeUrl.extractFrom(stream); + this.currentUtcTime.extractFrom(stream); + this.returnMsg.extractFrom(stream); + this.sourceKey.extractFrom(stream); + } + + public new(): ValidateAndRequestTicketResult { + return new ValidateAndRequestTicketResult(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + sourcePid: this.sourcePid, + bufResponse: this.bufResponse, + serviceNodeUrl: this.serviceNodeUrl, + currentUtcTime: this.currentUtcTime, + returnMsg: this.returnMsg, + sourceKey: this.sourceKey + } + }; + } +} \ No newline at end of file diff --git a/src/types/nex/rmcs/ticket-granting/get-name.ts b/src/types/nex/rmcs/ticket-granting/get-name.ts new file mode 100644 index 0000000..b915bbc --- /dev/null +++ b/src/types/nex/rmcs/ticket-granting/get-name.ts @@ -0,0 +1,10 @@ +import type RVString from '@/nex/types/string'; +import type PID from '@/nex/types/pid'; + +export type Request = { + id: PID; +}; + +export type Response = { + retval: RVString; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/ticket-granting/get-pid.ts b/src/types/nex/rmcs/ticket-granting/get-pid.ts new file mode 100644 index 0000000..3c7eea1 --- /dev/null +++ b/src/types/nex/rmcs/ticket-granting/get-pid.ts @@ -0,0 +1,10 @@ +import type RVString from '@/nex/types/string'; +import type PID from '@/nex/types/pid'; + +export type Request = { + strUserName: RVString; +}; + +export type Response = { + retval: PID; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/ticket-granting/login-with-context.ts b/src/types/nex/rmcs/ticket-granting/login-with-context.ts new file mode 100644 index 0000000..189c70e --- /dev/null +++ b/src/types/nex/rmcs/ticket-granting/login-with-context.ts @@ -0,0 +1,16 @@ +import type AnyDataHolder from '@/nex/types/any-data-holder'; +import type QResult from '@/nex/types/qresult'; +import type PID from '@/nex/types/pid'; +import type RVBuffer from '@/nex/types/buffer'; +import type RVConnectionData from '@/nex/types/rv-connection-data'; + +export type Request = { + loginData: AnyDataHolder; +}; + +export type Response = { + retval: QResult; + pidPrincipal: PID; + pbufResponse: RVBuffer; + pConnectionData: RVConnectionData; +}; \ No newline at end of file diff --git a/src/types/nex/rmcs/ticket-granting/validate-and-request-ticket-with-param.ts b/src/types/nex/rmcs/ticket-granting/validate-and-request-ticket-with-param.ts new file mode 100644 index 0000000..9f32786 --- /dev/null +++ b/src/types/nex/rmcs/ticket-granting/validate-and-request-ticket-with-param.ts @@ -0,0 +1,10 @@ +import type ValidateAndRequestTicketParam from '@/nex/protocols/ticket-granting/types/validate-and-request-ticket-param'; +import type ValidateAndRequestTicketResult from '@/nex/protocols/ticket-granting/types/validate-and-request-ticket-result'; + +export type Request = { + param: ValidateAndRequestTicketParam; +}; + +export type Response = { + result: ValidateAndRequestTicketResult; +}; \ No newline at end of file From 301421cd48d02c11fa47ee4dd30ec09df3fde229 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Tue, 7 Jan 2025 23:29:32 -0500 Subject: [PATCH 59/67] feat: complete MatchMakingExt protocol --- src/nex/protocols/match-making-ext/index.ts | 47 +++++++++++++++++- .../methods/delete-from-deletions.ts | 39 +++++++++++++++ .../methods/get-detailed-participants.ts | 48 +++++++++++++++++++ .../methods/get-gathering-relations.ts | 46 ++++++++++++++++++ .../methods/get-participants-urls.ts | 44 +++++++++++++++++ .../methods/get-participants.ts | 48 +++++++++++++++++++ .../match-making-ext/methods/index.ts | 7 ++- .../match-making/types/gathering-urls.ts | 37 ++++++++++++++ .../match-making/types/participant-details.ts | 43 +++++++++++++++++ 9 files changed, 357 insertions(+), 2 deletions(-) create mode 100644 src/nex/protocols/match-making-ext/methods/delete-from-deletions.ts create mode 100644 src/nex/protocols/match-making-ext/methods/get-detailed-participants.ts create mode 100644 src/nex/protocols/match-making-ext/methods/get-gathering-relations.ts create mode 100644 src/nex/protocols/match-making-ext/methods/get-participants-urls.ts create mode 100644 src/nex/protocols/match-making-ext/methods/get-participants.ts create mode 100644 src/nex/protocols/match-making/types/gathering-urls.ts create mode 100644 src/nex/protocols/match-making/types/participant-details.ts diff --git a/src/nex/protocols/match-making-ext/index.ts b/src/nex/protocols/match-making-ext/index.ts index 3af0f34..cd4cedc 100644 --- a/src/nex/protocols/match-making-ext/index.ts +++ b/src/nex/protocols/match-making-ext/index.ts @@ -16,7 +16,12 @@ export default class MatchMakingExtProtocol { }; private static handlers: Record any> = { - 0x1: MatchMakingExtProtocol.EndParticipation + 0x1: MatchMakingExtProtocol.EndParticipation, + 0x2: MatchMakingExtProtocol.GetParticipants, + 0x3: MatchMakingExtProtocol.GetDetailedParticipants, + 0x4: MatchMakingExtProtocol.GetParticipantsURLs, + 0x5: MatchMakingExtProtocol.GetGatheringRelations, + 0x6: MatchMakingExtProtocol.DeleteFromDeletions, }; static handlePacket(packet: Packet): void { @@ -46,4 +51,44 @@ export default class MatchMakingExtProtocol { return Methods.EndParticipation.Response; } } + + private static GetParticipants(message: RMCMessage): typeof Methods.GetParticipants.Request | typeof Methods.GetParticipants.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetParticipants.Request; + } else { + return Methods.GetParticipants.Response; + } + } + + private static GetDetailedParticipants(message: RMCMessage): typeof Methods.GetDetailedParticipants.Request | typeof Methods.GetDetailedParticipants.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetDetailedParticipants.Request; + } else { + return Methods.GetDetailedParticipants.Response; + } + } + + private static GetParticipantsURLs(message: RMCMessage): typeof Methods.GetParticipantsURLs.Request | typeof Methods.GetParticipantsURLs.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetParticipantsURLs.Request; + } else { + return Methods.GetParticipantsURLs.Response; + } + } + + private static GetGatheringRelations(message: RMCMessage): typeof Methods.GetGatheringRelations.Request | typeof Methods.GetGatheringRelations.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetGatheringRelations.Request; + } else { + return Methods.GetGatheringRelations.Response; + } + } + + private static DeleteFromDeletions(message: RMCMessage): typeof Methods.DeleteFromDeletions.Request | typeof Methods.DeleteFromDeletions.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.DeleteFromDeletions.Request; + } else { + return Methods.DeleteFromDeletions.Response; + } + } } \ No newline at end of file diff --git a/src/nex/protocols/match-making-ext/methods/delete-from-deletions.ts b/src/nex/protocols/match-making-ext/methods/delete-from-deletions.ts new file mode 100644 index 0000000..e75cbe5 --- /dev/null +++ b/src/nex/protocols/match-making-ext/methods/delete-from-deletions.ts @@ -0,0 +1,39 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt32 from '@/nex/types/uint32'; +import PID from '@/nex/types/pid'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'DeleteFromDeletions'; + + private lstDeletions = new List(new UInt32()); + private pid = new PID(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstDeletions.extractFrom(stream); + this.pid.extractFrom(stream); + } + + public toJSON(): any { + return { + lstDeletions: this.lstDeletions, + pid: this.pid + }; + } +} + +// * No response data +export class Response { + public static Name = 'DeleteFromDeletions'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making-ext/methods/get-detailed-participants.ts b/src/nex/protocols/match-making-ext/methods/get-detailed-participants.ts new file mode 100644 index 0000000..b1399a5 --- /dev/null +++ b/src/nex/protocols/match-making-ext/methods/get-detailed-participants.ts @@ -0,0 +1,48 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import List from '@/nex/types/list'; +import ParticipantDetails from '@/nex/protocols/match-making/types/participant-details'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetDetailedParticipants'; + + private idGathering = new List(new UInt32()); + private bOnlyActive = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.bOnlyActive.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + bOnlyActive: this.bOnlyActive + }; + } +} + +// * No response data +export class Response { + public static Name = 'GetDetailedParticipants'; + + private lstParticipants = new List(new ParticipantDetails()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstParticipants.extractFrom(stream); + } + + public toJSON(): any { + return { + lstParticipants: this.lstParticipants + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making-ext/methods/get-gathering-relations.ts b/src/nex/protocols/match-making-ext/methods/get-gathering-relations.ts new file mode 100644 index 0000000..19c6090 --- /dev/null +++ b/src/nex/protocols/match-making-ext/methods/get-gathering-relations.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetGatheringRelations'; + + private id = new UInt32(); + private descr = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.id.extractFrom(stream); + this.descr.extractFrom(stream); + } + + public toJSON(): any { + return { + id: this.id, + descr: this.descr + }; + } +} + +// * No response data +export class Response { + public static Name = 'GetGatheringRelations'; + + private retval = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making-ext/methods/get-participants-urls.ts b/src/nex/protocols/match-making-ext/methods/get-participants-urls.ts new file mode 100644 index 0000000..6b4b91c --- /dev/null +++ b/src/nex/protocols/match-making-ext/methods/get-participants-urls.ts @@ -0,0 +1,44 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt32 from '@/nex/types/uint32'; +import GatheringURLs from '@/nex/protocols/match-making/types/gathering-urls'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetParticipantsURLs'; + + private lstGatherings = new List(new UInt32()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGatherings.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGatherings: this.lstGatherings + }; + } +} + +// * No response data +export class Response { + public static Name = 'GetParticipantsURLs'; + + private lstGatheringURLs = new List(new GatheringURLs()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGatheringURLs.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGatheringURLs: this.lstGatheringURLs + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making-ext/methods/get-participants.ts b/src/nex/protocols/match-making-ext/methods/get-participants.ts new file mode 100644 index 0000000..1fe5a0b --- /dev/null +++ b/src/nex/protocols/match-making-ext/methods/get-participants.ts @@ -0,0 +1,48 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetParticipants'; + + private idGathering = new List(new UInt32()); + private bOnlyActive = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.bOnlyActive.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + bOnlyActive: this.bOnlyActive + }; + } +} + +// * No response data +export class Response { + public static Name = 'GetParticipants'; + + private lstParticipants = new List(new PID()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstParticipants.extractFrom(stream); + } + + public toJSON(): any { + return { + lstParticipants: this.lstParticipants + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making-ext/methods/index.ts b/src/nex/protocols/match-making-ext/methods/index.ts index 923f3be..b6d7d74 100644 --- a/src/nex/protocols/match-making-ext/methods/index.ts +++ b/src/nex/protocols/match-making-ext/methods/index.ts @@ -1 +1,6 @@ -export * as EndParticipation from '@/nex/protocols/match-making-ext/methods/end-participation'; \ No newline at end of file +export * as EndParticipation from '@/nex/protocols/match-making-ext/methods/end-participation'; +export * as GetParticipants from '@/nex/protocols/match-making-ext/methods/get-participants'; +export * as GetDetailedParticipants from '@/nex/protocols/match-making-ext/methods/get-detailed-participants'; +export * as GetParticipantsURLs from '@/nex/protocols/match-making-ext/methods/get-participants-urls'; +export * as GetGatheringRelations from '@/nex/protocols/match-making-ext/methods/get-gathering-relations'; +export * as DeleteFromDeletions from '@/nex/protocols/match-making-ext/methods/delete-from-deletions'; \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/gathering-urls.ts b/src/nex/protocols/match-making/types/gathering-urls.ts new file mode 100644 index 0000000..9a535f3 --- /dev/null +++ b/src/nex/protocols/match-making/types/gathering-urls.ts @@ -0,0 +1,37 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class GatheringURLs extends Structure { + public get typeName(): string { + return 'Gathering'; + } + + private m_gid = new UInt32(); + private m_lstStationURLs = new List(new StationURL); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_gid.extractFrom(stream); + this.m_lstStationURLs.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_gid: this.m_gid, + m_lstStationURLs: this.m_lstStationURLs + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/participant-details.ts b/src/nex/protocols/match-making/types/participant-details.ts new file mode 100644 index 0000000..86ec580 --- /dev/null +++ b/src/nex/protocols/match-making/types/participant-details.ts @@ -0,0 +1,43 @@ +import Structure from '@/nex/types/structure'; +import PID from '@/nex/types/pid'; +import RVString from '@/nex/types/string'; +import UInt16 from '@/nex/types/uint16'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class ParticipantDetails extends Structure { + public get typeName(): string { + return 'ParticipantDetails'; + } + + private m_idParticipant = new PID(); + private m_strName = new RVString(); + private m_strMessage = new RVString(); + private m_uiParticipants = new UInt16(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_idParticipant.extractFrom(stream); + this.m_strName.extractFrom(stream); + this.m_strMessage.extractFrom(stream); + this.m_uiParticipants.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_idParticipant: this.m_idParticipant, + m_strName: this.m_strName, + m_strMessage: this.m_strMessage, + m_uiParticipants: this.m_uiParticipants + } + }; + } +} \ No newline at end of file From 9ab8acb867c1b925651301559d1c3c93aecc0330 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Tue, 7 Jan 2025 23:37:53 -0500 Subject: [PATCH 60/67] chore: remove dangling comma in MatchMakingExt --- src/nex/protocols/match-making-ext/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nex/protocols/match-making-ext/index.ts b/src/nex/protocols/match-making-ext/index.ts index cd4cedc..a84ea43 100644 --- a/src/nex/protocols/match-making-ext/index.ts +++ b/src/nex/protocols/match-making-ext/index.ts @@ -21,7 +21,7 @@ export default class MatchMakingExtProtocol { 0x3: MatchMakingExtProtocol.GetDetailedParticipants, 0x4: MatchMakingExtProtocol.GetParticipantsURLs, 0x5: MatchMakingExtProtocol.GetGatheringRelations, - 0x6: MatchMakingExtProtocol.DeleteFromDeletions, + 0x6: MatchMakingExtProtocol.DeleteFromDeletions }; static handlePacket(packet: Packet): void { From 26d5954e159cec0edd025d2577e4bd3dd79d7cc1 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Wed, 8 Jan 2025 00:03:31 -0500 Subject: [PATCH 61/67] chore: npm audit fix --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 961ec0c..aee5e6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1539,9 +1539,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -1873,9 +1873,9 @@ } }, "node_modules/elliptic": { - "version": "6.5.7", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", - "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", "dev": true, "dependencies": { "bn.js": "^4.11.9", From babaf6133f18f0f020bc2d38d74e087ac3bc5571 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Wed, 8 Jan 2025 02:38:53 -0500 Subject: [PATCH 62/67] feat: complete MatchMaking protocol --- src/nex/protocols/match-making/index.ts | 423 +++++++++++++++++- .../match-making/methods/accept-invitation.ts | 46 ++ .../match-making/methods/add-participants.ts | 51 +++ .../match-making/methods/cancel-invitation.ts | 51 +++ .../methods/cancel-participation.ts | 46 ++ .../methods/decline-invitation.ts | 46 ++ .../methods/delete-from-deletions.ts | 43 ++ .../match-making/methods/delete-gathering.ts | 42 ++ .../methods/find-by-description-like.ts | 47 ++ .../methods/find-by-description-regex.ts | 47 ++ .../methods/find-by-description.ts | 47 ++ .../match-making/methods/find-by-id.ts | 43 ++ .../match-making/methods/find-by-owner.ts | 47 ++ .../methods/find-by-participants.ts | 43 ++ .../match-making/methods/find-by-single-id.ts | 46 ++ .../match-making/methods/find-by-sql-query.ts | 47 ++ .../match-making/methods/find-by-type.ts | 47 ++ .../match-making/methods/find-invitations.ts | 43 ++ .../methods/get-detailed-participants.ts | 43 ++ .../methods/get-invitations-received.ts | 35 ++ .../methods/get-invitations-sent.ts | 43 ++ .../methods/get-participants-urls.ts | 43 ++ .../match-making/methods/get-participants.ts | 43 ++ .../methods/get-pending-deletions.ts | 51 +++ .../match-making/methods/get-session-url.ts | 46 ++ .../match-making/methods/get-session-urls.ts | 7 +- .../match-making/methods/get-state.ts | 45 ++ .../match-making/methods/get-stats.ts | 55 +++ .../protocols/match-making/methods/index.ts | 44 +- .../protocols/match-making/methods/invite.ts | 51 +++ .../match-making/methods/launch-session.ts | 46 ++ .../methods/migrate-gathering-ownership-v1.ts | 47 ++ .../methods/migrate-gathering-ownership.ts | 43 ++ .../match-making/methods/participate.ts | 46 ++ .../methods/register-gathering.ts | 42 ++ .../methods/register-local-url.ts | 38 ++ .../methods/register-local-urls.ts | 39 ++ .../match-making/methods/report-stats.ts | 47 ++ .../match-making/methods/set-state.ts | 45 ++ .../methods/unregister-gathering.ts | 42 ++ .../methods/unregister-gatherings.ts | 43 ++ .../methods/update-gathering-ownership.ts | 45 ++ .../match-making/methods/update-gathering.ts | 42 ++ .../methods/update-session-host-v1.ts | 34 ++ .../methods/update-session-host.ts | 7 +- .../methods/update-session-url.ts | 46 ++ .../types/create-matchmake-session-param.ts | 50 +++ .../match-making/types/deletion-entry.ts | 37 ++ ...-matchmake-session-by-participant-param.ts | 39 ++ ...matchmake-session-by-participant-result.ts | 34 ++ .../match-making/types/gathering-stats.ts | 39 ++ .../match-making/types/gathering-urls.ts | 4 +- .../match-making/types/invitation.ts | 37 ++ .../types/join-matchmake-session-param.ts | 66 +++ .../matchmake-session-search-criteria.ts | 4 +- .../match-making/types/participant-details.ts | 4 +- .../match-making/types/simple-community.ts | 33 ++ .../types/update-matchmake-session-param.ts | 86 ++++ 58 files changed, 2779 insertions(+), 17 deletions(-) create mode 100644 src/nex/protocols/match-making/methods/accept-invitation.ts create mode 100644 src/nex/protocols/match-making/methods/add-participants.ts create mode 100644 src/nex/protocols/match-making/methods/cancel-invitation.ts create mode 100644 src/nex/protocols/match-making/methods/cancel-participation.ts create mode 100644 src/nex/protocols/match-making/methods/decline-invitation.ts create mode 100644 src/nex/protocols/match-making/methods/delete-from-deletions.ts create mode 100644 src/nex/protocols/match-making/methods/delete-gathering.ts create mode 100644 src/nex/protocols/match-making/methods/find-by-description-like.ts create mode 100644 src/nex/protocols/match-making/methods/find-by-description-regex.ts create mode 100644 src/nex/protocols/match-making/methods/find-by-description.ts create mode 100644 src/nex/protocols/match-making/methods/find-by-id.ts create mode 100644 src/nex/protocols/match-making/methods/find-by-owner.ts create mode 100644 src/nex/protocols/match-making/methods/find-by-participants.ts create mode 100644 src/nex/protocols/match-making/methods/find-by-single-id.ts create mode 100644 src/nex/protocols/match-making/methods/find-by-sql-query.ts create mode 100644 src/nex/protocols/match-making/methods/find-by-type.ts create mode 100644 src/nex/protocols/match-making/methods/find-invitations.ts create mode 100644 src/nex/protocols/match-making/methods/get-detailed-participants.ts create mode 100644 src/nex/protocols/match-making/methods/get-invitations-received.ts create mode 100644 src/nex/protocols/match-making/methods/get-invitations-sent.ts create mode 100644 src/nex/protocols/match-making/methods/get-participants-urls.ts create mode 100644 src/nex/protocols/match-making/methods/get-participants.ts create mode 100644 src/nex/protocols/match-making/methods/get-pending-deletions.ts create mode 100644 src/nex/protocols/match-making/methods/get-session-url.ts create mode 100644 src/nex/protocols/match-making/methods/get-state.ts create mode 100644 src/nex/protocols/match-making/methods/get-stats.ts create mode 100644 src/nex/protocols/match-making/methods/invite.ts create mode 100644 src/nex/protocols/match-making/methods/launch-session.ts create mode 100644 src/nex/protocols/match-making/methods/migrate-gathering-ownership-v1.ts create mode 100644 src/nex/protocols/match-making/methods/migrate-gathering-ownership.ts create mode 100644 src/nex/protocols/match-making/methods/participate.ts create mode 100644 src/nex/protocols/match-making/methods/register-gathering.ts create mode 100644 src/nex/protocols/match-making/methods/register-local-url.ts create mode 100644 src/nex/protocols/match-making/methods/register-local-urls.ts create mode 100644 src/nex/protocols/match-making/methods/report-stats.ts create mode 100644 src/nex/protocols/match-making/methods/set-state.ts create mode 100644 src/nex/protocols/match-making/methods/unregister-gathering.ts create mode 100644 src/nex/protocols/match-making/methods/unregister-gatherings.ts create mode 100644 src/nex/protocols/match-making/methods/update-gathering-ownership.ts create mode 100644 src/nex/protocols/match-making/methods/update-gathering.ts create mode 100644 src/nex/protocols/match-making/methods/update-session-host-v1.ts create mode 100644 src/nex/protocols/match-making/methods/update-session-url.ts create mode 100644 src/nex/protocols/match-making/types/create-matchmake-session-param.ts create mode 100644 src/nex/protocols/match-making/types/deletion-entry.ts create mode 100644 src/nex/protocols/match-making/types/find-matchmake-session-by-participant-param.ts create mode 100644 src/nex/protocols/match-making/types/find-matchmake-session-by-participant-result.ts create mode 100644 src/nex/protocols/match-making/types/gathering-stats.ts create mode 100644 src/nex/protocols/match-making/types/invitation.ts create mode 100644 src/nex/protocols/match-making/types/join-matchmake-session-param.ts create mode 100644 src/nex/protocols/match-making/types/simple-community.ts create mode 100644 src/nex/protocols/match-making/types/update-matchmake-session-param.ts diff --git a/src/nex/protocols/match-making/index.ts b/src/nex/protocols/match-making/index.ts index 1dcf155..b353859 100644 --- a/src/nex/protocols/match-making/index.ts +++ b/src/nex/protocols/match-making/index.ts @@ -54,8 +54,50 @@ export default class MatchMakingProtocol { }; private static handlers: Record any> = { + 0x01: MatchMakingProtocol.RegisterGathering, + 0x02: MatchMakingProtocol.UnregisterGathering, + 0x03: MatchMakingProtocol.UnregisterGatherings, + 0x04: MatchMakingProtocol.UpdateGathering, + 0x05: MatchMakingProtocol.Invite, + 0x06: MatchMakingProtocol.AcceptInvitation, + 0x07: MatchMakingProtocol.DeclineInvitation, + 0x08: MatchMakingProtocol.CancelInvitation, + 0x09: MatchMakingProtocol.GetInvitationsSent, + 0x0A: MatchMakingProtocol.GetInvitationsReceived, + 0x0B: MatchMakingProtocol.Participate, + 0x0C: MatchMakingProtocol.CancelParticipation, + 0x0D: MatchMakingProtocol.GetParticipants, + 0x0E: MatchMakingProtocol.AddParticipants, + 0x0F: MatchMakingProtocol.GetDetailedParticipants, + 0x10: MatchMakingProtocol.GetParticipantsURLs, + 0x11: MatchMakingProtocol.FindByType, + 0x12: MatchMakingProtocol.FindByDescription, + 0x13: MatchMakingProtocol.FindByDescriptionRegex, + 0x14: MatchMakingProtocol.FindByID, + 0x15: MatchMakingProtocol.FindBySingleID, + 0x16: MatchMakingProtocol.FindByOwner, + 0x17: MatchMakingProtocol.FindByParticipants, + 0x18: MatchMakingProtocol.FindInvitations, + 0x19: MatchMakingProtocol.FindBySQLQuery, + 0x1A: MatchMakingProtocol.LaunchSession, + 0x1B: MatchMakingProtocol.UpdateSessionURL, + 0x1C: MatchMakingProtocol.GetSessionURL, + 0x1D: MatchMakingProtocol.GetState, + 0x1E: MatchMakingProtocol.SetState, + 0x1F: MatchMakingProtocol.ReportStats, + 0x20: MatchMakingProtocol.GetStats, + 0x21: MatchMakingProtocol.DeleteGathering, + 0x22: MatchMakingProtocol.GetPendingDeletions, + 0x23: MatchMakingProtocol.DeleteFromDeletions, + 0x24: MatchMakingProtocol.MigrateGatheringOwnershipV1, + 0x25: MatchMakingProtocol.FindByDescriptionLike, + 0x26: MatchMakingProtocol.RegisterLocalURL, + 0x27: MatchMakingProtocol.RegisterLocalURLs, + 0x28: MatchMakingProtocol.UpdateSessionHostV1, 0x29: MatchMakingProtocol.GetSessionURLs, - 0x2A: MatchMakingProtocol.UpdateSessionHost + 0x2A: MatchMakingProtocol.UpdateSessionHost, + 0x2B: MatchMakingProtocol.UpdateGatheringOwnership, + 0x2C: MatchMakingProtocol.MigrateGatheringOwnership }; static handlePacket(packet: Packet): void { @@ -78,6 +120,366 @@ export default class MatchMakingProtocol { packet.message.methodName = messageDecoder.Name; } + private static RegisterGathering(message: RMCMessage): typeof Methods.RegisterGathering.Request | typeof Methods.RegisterGathering.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.RegisterGathering.Request; + } else { + return Methods.RegisterGathering.Response; + } + } + + + private static UnregisterGathering(message: RMCMessage): typeof Methods.UnregisterGathering.Request | typeof Methods.UnregisterGathering.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UnregisterGathering.Request; + } else { + return Methods.UnregisterGathering.Response; + } + } + + + private static UnregisterGatherings(message: RMCMessage): typeof Methods.UnregisterGatherings.Request | typeof Methods.UnregisterGatherings.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UnregisterGatherings.Request; + } else { + return Methods.UnregisterGatherings.Response; + } + } + + + private static UpdateGathering(message: RMCMessage): typeof Methods.UpdateGathering.Request | typeof Methods.UpdateGathering.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateGathering.Request; + } else { + return Methods.UpdateGathering.Response; + } + } + + + private static Invite(message: RMCMessage): typeof Methods.Invite.Request | typeof Methods.Invite.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.Invite.Request; + } else { + return Methods.Invite.Response; + } + } + + + private static AcceptInvitation(message: RMCMessage): typeof Methods.AcceptInvitation.Request | typeof Methods.AcceptInvitation.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.AcceptInvitation.Request; + } else { + return Methods.AcceptInvitation.Response; + } + } + + + private static DeclineInvitation(message: RMCMessage): typeof Methods.DeclineInvitation.Request | typeof Methods.DeclineInvitation.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.DeclineInvitation.Request; + } else { + return Methods.DeclineInvitation.Response; + } + } + + + private static CancelInvitation(message: RMCMessage): typeof Methods.CancelInvitation.Request | typeof Methods.CancelInvitation.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.CancelInvitation.Request; + } else { + return Methods.CancelInvitation.Response; + } + } + + + private static GetInvitationsSent(message: RMCMessage): typeof Methods.GetInvitationsSent.Request | typeof Methods.GetInvitationsSent.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetInvitationsSent.Request; + } else { + return Methods.GetInvitationsSent.Response; + } + } + + + private static GetInvitationsReceived(message: RMCMessage): typeof Methods.GetInvitationsReceived.Request | typeof Methods.GetInvitationsReceived.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetInvitationsReceived.Request; + } else { + return Methods.GetInvitationsReceived.Response; + } + } + + + private static Participate(message: RMCMessage): typeof Methods.Participate.Request | typeof Methods.Participate.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.Participate.Request; + } else { + return Methods.Participate.Response; + } + } + + + private static CancelParticipation(message: RMCMessage): typeof Methods.CancelParticipation.Request | typeof Methods.CancelParticipation.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.CancelParticipation.Request; + } else { + return Methods.CancelParticipation.Response; + } + } + + + private static GetParticipants(message: RMCMessage): typeof Methods.GetParticipants.Request | typeof Methods.GetParticipants.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetParticipants.Request; + } else { + return Methods.GetParticipants.Response; + } + } + + + private static AddParticipants(message: RMCMessage): typeof Methods.AddParticipants.Request | typeof Methods.AddParticipants.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.AddParticipants.Request; + } else { + return Methods.AddParticipants.Response; + } + } + + + private static GetDetailedParticipants(message: RMCMessage): typeof Methods.GetDetailedParticipants.Request | typeof Methods.GetDetailedParticipants.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetDetailedParticipants.Request; + } else { + return Methods.GetDetailedParticipants.Response; + } + } + + + private static GetParticipantsURLs(message: RMCMessage): typeof Methods.GetParticipantsURLs.Request | typeof Methods.GetParticipantsURLs.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetParticipantsURLs.Request; + } else { + return Methods.GetParticipantsURLs.Response; + } + } + + + private static FindByType(message: RMCMessage): typeof Methods.FindByType.Request | typeof Methods.FindByType.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindByType.Request; + } else { + return Methods.FindByType.Response; + } + } + + + private static FindByDescription(message: RMCMessage): typeof Methods.FindByDescription.Request | typeof Methods.FindByDescription.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindByDescription.Request; + } else { + return Methods.FindByDescription.Response; + } + } + + + private static FindByDescriptionRegex(message: RMCMessage): typeof Methods.FindByDescriptionRegex.Request | typeof Methods.FindByDescriptionRegex.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindByDescriptionRegex.Request; + } else { + return Methods.FindByDescriptionRegex.Response; + } + } + + + private static FindByID(message: RMCMessage): typeof Methods.FindByID.Request | typeof Methods.FindByID.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindByID.Request; + } else { + return Methods.FindByID.Response; + } + } + + + private static FindBySingleID(message: RMCMessage): typeof Methods.FindBySingleID.Request | typeof Methods.FindBySingleID.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindBySingleID.Request; + } else { + return Methods.FindBySingleID.Response; + } + } + + + private static FindByOwner(message: RMCMessage): typeof Methods.FindByOwner.Request | typeof Methods.FindByOwner.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindByOwner.Request; + } else { + return Methods.FindByOwner.Response; + } + } + + + private static FindByParticipants(message: RMCMessage): typeof Methods.FindByParticipants.Request | typeof Methods.FindByParticipants.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindByParticipants.Request; + } else { + return Methods.FindByParticipants.Response; + } + } + + + private static FindInvitations(message: RMCMessage): typeof Methods.FindInvitations.Request | typeof Methods.FindInvitations.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindInvitations.Request; + } else { + return Methods.FindInvitations.Response; + } + } + + + private static FindBySQLQuery(message: RMCMessage): typeof Methods.FindBySQLQuery.Request | typeof Methods.FindBySQLQuery.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindBySQLQuery.Request; + } else { + return Methods.FindBySQLQuery.Response; + } + } + + + private static LaunchSession(message: RMCMessage): typeof Methods.LaunchSession.Request | typeof Methods.LaunchSession.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.LaunchSession.Request; + } else { + return Methods.LaunchSession.Response; + } + } + + + private static UpdateSessionURL(message: RMCMessage): typeof Methods.UpdateSessionURL.Request | typeof Methods.UpdateSessionURL.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateSessionURL.Request; + } else { + return Methods.UpdateSessionURL.Response; + } + } + + + private static GetSessionURL(message: RMCMessage): typeof Methods.GetSessionURL.Request | typeof Methods.GetSessionURL.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetSessionURL.Request; + } else { + return Methods.GetSessionURL.Response; + } + } + + + private static GetState(message: RMCMessage): typeof Methods.GetState.Request | typeof Methods.GetState.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetState.Request; + } else { + return Methods.GetState.Response; + } + } + + + private static SetState(message: RMCMessage): typeof Methods.SetState.Request | typeof Methods.SetState.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.SetState.Request; + } else { + return Methods.SetState.Response; + } + } + + + private static ReportStats(message: RMCMessage): typeof Methods.ReportStats.Request | typeof Methods.ReportStats.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ReportStats.Request; + } else { + return Methods.ReportStats.Response; + } + } + + + private static GetStats(message: RMCMessage): typeof Methods.GetStats.Request | typeof Methods.GetStats.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetStats.Request; + } else { + return Methods.GetStats.Response; + } + } + + + private static DeleteGathering(message: RMCMessage): typeof Methods.DeleteGathering.Request | typeof Methods.DeleteGathering.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.DeleteGathering.Request; + } else { + return Methods.DeleteGathering.Response; + } + } + + + private static GetPendingDeletions(message: RMCMessage): typeof Methods.GetPendingDeletions.Request | typeof Methods.GetPendingDeletions.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetPendingDeletions.Request; + } else { + return Methods.GetPendingDeletions.Response; + } + } + + + private static DeleteFromDeletions(message: RMCMessage): typeof Methods.DeleteFromDeletions.Request | typeof Methods.DeleteFromDeletions.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.DeleteFromDeletions.Request; + } else { + return Methods.DeleteFromDeletions.Response; + } + } + + + private static MigrateGatheringOwnershipV1(message: RMCMessage): typeof Methods.MigrateGatheringOwnershipV1.Request | typeof Methods.MigrateGatheringOwnershipV1.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.MigrateGatheringOwnershipV1.Request; + } else { + return Methods.MigrateGatheringOwnershipV1.Response; + } + } + + + private static FindByDescriptionLike(message: RMCMessage): typeof Methods.FindByDescriptionLike.Request | typeof Methods.FindByDescriptionLike.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindByDescriptionLike.Request; + } else { + return Methods.FindByDescriptionLike.Response; + } + } + + + private static RegisterLocalURL(message: RMCMessage): typeof Methods.RegisterLocalURL.Request | typeof Methods.RegisterLocalURL.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.RegisterLocalURL.Request; + } else { + return Methods.RegisterLocalURL.Response; + } + } + + + private static RegisterLocalURLs(message: RMCMessage): typeof Methods.RegisterLocalURLs.Request | typeof Methods.RegisterLocalURLs.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.RegisterLocalURLs.Request; + } else { + return Methods.RegisterLocalURLs.Response; + } + } + + + private static UpdateSessionHostV1(message: RMCMessage): typeof Methods.UpdateSessionHostV1.Request | typeof Methods.UpdateSessionHostV1.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateSessionHostV1.Request; + } else { + return Methods.UpdateSessionHostV1.Response; + } + } + + private static GetSessionURLs(message: RMCMessage): typeof Methods.GetSessionURLs.Request | typeof Methods.GetSessionURLs.Response { if (message.type === RMCMessage.REQUEST) { return Methods.GetSessionURLs.Request; @@ -86,6 +488,7 @@ export default class MatchMakingProtocol { } } + private static UpdateSessionHost(message: RMCMessage): typeof Methods.UpdateSessionHost.Request | typeof Methods.UpdateSessionHost.Response { if (message.type === RMCMessage.REQUEST) { return Methods.UpdateSessionHost.Request; @@ -93,4 +496,22 @@ export default class MatchMakingProtocol { return Methods.UpdateSessionHost.Response; } } + + + private static UpdateGatheringOwnership(message: RMCMessage): typeof Methods.UpdateGatheringOwnership.Request | typeof Methods.UpdateGatheringOwnership.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateGatheringOwnership.Request; + } else { + return Methods.UpdateGatheringOwnership.Response; + } + } + + + private static MigrateGatheringOwnership(message: RMCMessage): typeof Methods.MigrateGatheringOwnership.Request | typeof Methods.MigrateGatheringOwnership.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.MigrateGatheringOwnership.Request; + } else { + return Methods.MigrateGatheringOwnership.Response; + } + } } \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/accept-invitation.ts b/src/nex/protocols/match-making/methods/accept-invitation.ts new file mode 100644 index 0000000..efd5430 --- /dev/null +++ b/src/nex/protocols/match-making/methods/accept-invitation.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'AcceptInvitation'; + + private idGathering = new UInt32(); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'AcceptInvitation'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/add-participants.ts b/src/nex/protocols/match-making/methods/add-participants.ts new file mode 100644 index 0000000..9e70153 --- /dev/null +++ b/src/nex/protocols/match-making/methods/add-participants.ts @@ -0,0 +1,51 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'AddParticipants'; + + private idGathering = new UInt32(); + private lstParticipants = new List(new PID()); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.lstParticipants.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + lstParticipants: this.lstParticipants, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'AddParticipants'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/cancel-invitation.ts b/src/nex/protocols/match-making/methods/cancel-invitation.ts new file mode 100644 index 0000000..41b56b5 --- /dev/null +++ b/src/nex/protocols/match-making/methods/cancel-invitation.ts @@ -0,0 +1,51 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'CancelInvitation'; + + private idGathering = new UInt32(); + private lstPrincipals = new List(new PID()); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.lstPrincipals.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + lstPrincipals: this.lstPrincipals, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'CancelInvitation'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/cancel-participation.ts b/src/nex/protocols/match-making/methods/cancel-participation.ts new file mode 100644 index 0000000..8e5abc3 --- /dev/null +++ b/src/nex/protocols/match-making/methods/cancel-participation.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'CancelParticipation'; + + private idGathering = new UInt32(); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'CancelParticipation'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/decline-invitation.ts b/src/nex/protocols/match-making/methods/decline-invitation.ts new file mode 100644 index 0000000..612bc3b --- /dev/null +++ b/src/nex/protocols/match-making/methods/decline-invitation.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'DeclineInvitation'; + + private idGathering = new UInt32(); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'DeclineInvitation'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/delete-from-deletions.ts b/src/nex/protocols/match-making/methods/delete-from-deletions.ts new file mode 100644 index 0000000..0fa62cd --- /dev/null +++ b/src/nex/protocols/match-making/methods/delete-from-deletions.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'DeleteFromDeletions'; + + private lstDeletions = new List(new UInt32()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstDeletions.extractFrom(stream); + } + + public toJSON(): any { + return { + lstDeletions: this.lstDeletions + }; + } +} + +export class Response { + public static Name = 'DeleteFromDeletions'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/delete-gathering.ts b/src/nex/protocols/match-making/methods/delete-gathering.ts new file mode 100644 index 0000000..757d65f --- /dev/null +++ b/src/nex/protocols/match-making/methods/delete-gathering.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'DeleteGathering'; + + private gid = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid + }; + } +} + +export class Response { + public static Name = 'DeleteGathering'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/find-by-description-like.ts b/src/nex/protocols/match-making/methods/find-by-description-like.ts new file mode 100644 index 0000000..d5051ab --- /dev/null +++ b/src/nex/protocols/match-making/methods/find-by-description-like.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RVString from '@/nex/types/string'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindByDescriptionLike'; + + private strDescriptionLike = new RVString(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.strDescriptionLike.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + strDescriptionLike: this.strDescriptionLike, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'FindByDescriptionLike'; + + private lstGathering = new List(new AnyDataHolder()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGathering: this.lstGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/find-by-description-regex.ts b/src/nex/protocols/match-making/methods/find-by-description-regex.ts new file mode 100644 index 0000000..5edcbd3 --- /dev/null +++ b/src/nex/protocols/match-making/methods/find-by-description-regex.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RVString from '@/nex/types/string'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindByDescriptionRegex'; + + private strDescriptionRegex = new RVString(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.strDescriptionRegex.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + strDescriptionRegex: this.strDescriptionRegex, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'FindByDescriptionRegex'; + + private lstGathering = new List(new AnyDataHolder()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGathering: this.lstGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/find-by-description.ts b/src/nex/protocols/match-making/methods/find-by-description.ts new file mode 100644 index 0000000..6355428 --- /dev/null +++ b/src/nex/protocols/match-making/methods/find-by-description.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RVString from '@/nex/types/string'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindByDescription'; + + private strDescription = new RVString(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.strDescription.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + strDescription: this.strDescription, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'FindByDescription'; + + private lstGathering = new List(new AnyDataHolder()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGathering: this.lstGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/find-by-id.ts b/src/nex/protocols/match-making/methods/find-by-id.ts new file mode 100644 index 0000000..d988eab --- /dev/null +++ b/src/nex/protocols/match-making/methods/find-by-id.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt32 from '@/nex/types/uint32'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindByID'; + + private lstID = new List(new UInt32()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstID.extractFrom(stream); + } + + public toJSON(): any { + return { + lstID: this.lstID + }; + } +} + +export class Response { + public static Name = 'FindByID'; + + private lstGathering = new List(new AnyDataHolder()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGathering: this.lstGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/find-by-owner.ts b/src/nex/protocols/match-making/methods/find-by-owner.ts new file mode 100644 index 0000000..d218e81 --- /dev/null +++ b/src/nex/protocols/match-making/methods/find-by-owner.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import PID from '@/nex/types/pid'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindByOwner'; + + private id = new PID(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.id.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + id: this.id, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'FindByOwner'; + + private lstGathering = new List(new AnyDataHolder()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGathering: this.lstGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/find-by-participants.ts b/src/nex/protocols/match-making/methods/find-by-participants.ts new file mode 100644 index 0000000..2fc198d --- /dev/null +++ b/src/nex/protocols/match-making/methods/find-by-participants.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindByParticipants'; + + private pid = new List(new PID()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pid.extractFrom(stream); + } + + public toJSON(): any { + return { + pid: this.pid + }; + } +} + +export class Response { + public static Name = 'FindByParticipants'; + + private lstGathering = new List(new AnyDataHolder()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGathering: this.lstGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/find-by-single-id.ts b/src/nex/protocols/match-making/methods/find-by-single-id.ts new file mode 100644 index 0000000..060dd3f --- /dev/null +++ b/src/nex/protocols/match-making/methods/find-by-single-id.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindBySingleID'; + + private id = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.id.extractFrom(stream); + } + + public toJSON(): any { + return { + id: this.id + }; + } +} + +export class Response { + public static Name = 'FindBySingleID'; + + private bResult = new Bool(); + private pGathering = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.bResult.extractFrom(stream); + this.pGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + bResult: this.bResult, + pGathering: this.pGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/find-by-sql-query.ts b/src/nex/protocols/match-making/methods/find-by-sql-query.ts new file mode 100644 index 0000000..e996848 --- /dev/null +++ b/src/nex/protocols/match-making/methods/find-by-sql-query.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RVString from '@/nex/types/string'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindBySQLQuery'; + + private strQuery = new RVString(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.strQuery.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + strQuery: this.strQuery, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'FindBySQLQuery'; + + private lstGathering = new List(new AnyDataHolder()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGathering: this.lstGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/find-by-type.ts b/src/nex/protocols/match-making/methods/find-by-type.ts new file mode 100644 index 0000000..88aed99 --- /dev/null +++ b/src/nex/protocols/match-making/methods/find-by-type.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RVString from '@/nex/types/string'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindByType'; + + private strType = new RVString(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.strType.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + strType: this.strType, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'FindByType'; + + private lstGathering = new List(new AnyDataHolder()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGathering: this.lstGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/find-invitations.ts b/src/nex/protocols/match-making/methods/find-invitations.ts new file mode 100644 index 0000000..762f747 --- /dev/null +++ b/src/nex/protocols/match-making/methods/find-invitations.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindInvitations'; + + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'FindInvitations'; + + private lstGathering = new List(new AnyDataHolder()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGathering: this.lstGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/get-detailed-participants.ts b/src/nex/protocols/match-making/methods/get-detailed-participants.ts new file mode 100644 index 0000000..049a79f --- /dev/null +++ b/src/nex/protocols/match-making/methods/get-detailed-participants.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import ParticipantDetails from '@/nex/protocols/match-making/types/participant-details'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetDetailedParticipants'; + + private idGathering = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering + }; + } +} + +export class Response { + public static Name = 'GetDetailedParticipants'; + + private lstParticipants = new List(new ParticipantDetails()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstParticipants.extractFrom(stream); + } + + public toJSON(): any { + return { + lstParticipants: this.lstParticipants + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/get-invitations-received.ts b/src/nex/protocols/match-making/methods/get-invitations-received.ts new file mode 100644 index 0000000..cff1891 --- /dev/null +++ b/src/nex/protocols/match-making/methods/get-invitations-received.ts @@ -0,0 +1,35 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import Invitation from '@/nex/protocols/match-making/types/invitation'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +// * No request data +export class Request { + public static Name = 'GetInvitationsReceived'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} + +export class Response { + public static Name = 'GetInvitationsReceived'; + + private lstInvitations = new List(new Invitation()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstInvitations.extractFrom(stream); + } + + public toJSON(): any { + return { + lstInvitations: this.lstInvitations + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/get-invitations-sent.ts b/src/nex/protocols/match-making/methods/get-invitations-sent.ts new file mode 100644 index 0000000..d971230 --- /dev/null +++ b/src/nex/protocols/match-making/methods/get-invitations-sent.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import Invitation from '@/nex/protocols/match-making/types/invitation'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetInvitationsSent'; + + private idGathering = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering + }; + } +} + +export class Response { + public static Name = 'GetInvitationsSent'; + + private lstInvitations = new List(new Invitation()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstInvitations.extractFrom(stream); + } + + public toJSON(): any { + return { + lstInvitations: this.lstInvitations + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/get-participants-urls.ts b/src/nex/protocols/match-making/methods/get-participants-urls.ts new file mode 100644 index 0000000..addd4ea --- /dev/null +++ b/src/nex/protocols/match-making/methods/get-participants-urls.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetParticipantsURLs'; + + private idGathering = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering + }; + } +} + +export class Response { + public static Name = 'GetParticipantsURLs'; + + private lstStationURL = new List(new StationURL()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstStationURL.extractFrom(stream); + } + + public toJSON(): any { + return { + lstStationURL: this.lstStationURL + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/get-participants.ts b/src/nex/protocols/match-making/methods/get-participants.ts new file mode 100644 index 0000000..d29ad12 --- /dev/null +++ b/src/nex/protocols/match-making/methods/get-participants.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetParticipants'; + + private idGathering = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering + }; + } +} + +export class Response { + public static Name = 'GetParticipants'; + + private lstParticipants = new List(new PID()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstParticipants.extractFrom(stream); + } + + public toJSON(): any { + return { + lstParticipants: this.lstParticipants + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/get-pending-deletions.ts b/src/nex/protocols/match-making/methods/get-pending-deletions.ts new file mode 100644 index 0000000..c1a6528 --- /dev/null +++ b/src/nex/protocols/match-making/methods/get-pending-deletions.ts @@ -0,0 +1,51 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import ResultRange from '@/nex/types/result-range'; +import Bool from '@/nex/types/bool'; +import List from '@/nex/types/list'; +import DeletionEntry from '@/nex/protocols/match-making/types/deletion-entry'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetPendingDeletions'; + + private uiReason = new UInt32(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.uiReason.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + uiReason: this.uiReason, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'GetPendingDeletions'; + + private retval = new Bool(); + private lstDeletions = new List(new DeletionEntry()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + this.lstDeletions.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval, + lstDeletions: this.lstDeletions + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/get-session-url.ts b/src/nex/protocols/match-making/methods/get-session-url.ts new file mode 100644 index 0000000..756401d --- /dev/null +++ b/src/nex/protocols/match-making/methods/get-session-url.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import RVString from '@/nex/types/string'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetSessionURL'; + + private idGathering = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering + }; + } +} + +export class Response { + public static Name = 'GetSessionURL'; + + private retval = new Bool(); + private strURL = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + this.strURL.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval, + strURL: this.strURL + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/get-session-urls.ts b/src/nex/protocols/match-making/methods/get-session-urls.ts index 68d679f..75c2294 100644 --- a/src/nex/protocols/match-making/methods/get-session-urls.ts +++ b/src/nex/protocols/match-making/methods/get-session-urls.ts @@ -3,7 +3,8 @@ import UInt32 from '@/nex/types/uint32'; import List from '@/nex/types/list'; import StationURL from '@/nex/types/station-url'; import type RMCMessage from '@/nex/rmc-message'; -import type * as RMCs from '@/types/nex/rmcs/match-making/get-session-urls'; + +// TODO - Add strict types for toJSON methods export class Request { public static Name = 'GetSessionURLs'; @@ -16,7 +17,7 @@ export class Request { this.gid.extractFrom(stream); } - public toJSON(): RMCs.Request { + public toJSON(): any { return { gid: this.gid }; @@ -34,7 +35,7 @@ export class Response { this.lstURLs.extractFrom(stream); } - public toJSON(): RMCs.Response { + public toJSON(): any { return { lstURLs: this.lstURLs }; diff --git a/src/nex/protocols/match-making/methods/get-state.ts b/src/nex/protocols/match-making/methods/get-state.ts new file mode 100644 index 0000000..31d7eb2 --- /dev/null +++ b/src/nex/protocols/match-making/methods/get-state.ts @@ -0,0 +1,45 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetState'; + + private idGathering = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering + }; + } +} + +export class Response { + public static Name = 'GetState'; + + private retval = new Bool(); + private uiState = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + this.uiState.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval, + uiState: this.uiState + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/get-stats.ts b/src/nex/protocols/match-making/methods/get-stats.ts new file mode 100644 index 0000000..4aa156c --- /dev/null +++ b/src/nex/protocols/match-making/methods/get-stats.ts @@ -0,0 +1,55 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import UInt8 from '@/nex/types/uint8'; +import Bool from '@/nex/types/bool'; +import GatheringStats from '@/nex/protocols/match-making/types/gathering-stats'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetStats'; + + private idGathering = new UInt32(); + private lstParticipants = new List(new PID()); + private lstColumns = new List(new UInt8()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.lstParticipants.extractFrom(stream); + this.lstColumns.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + lstParticipants: this.lstParticipants, + lstColumns: this.lstColumns + }; + } +} + +export class Response { + public static Name = 'GetStats'; + + private retval = new Bool(); + private plstStats = new List(new GatheringStats()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + this.plstStats.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval, + plstStats: this.plstStats + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/index.ts b/src/nex/protocols/match-making/methods/index.ts index 74874e5..6f88da4 100644 --- a/src/nex/protocols/match-making/methods/index.ts +++ b/src/nex/protocols/match-making/methods/index.ts @@ -1,2 +1,44 @@ +export * as RegisterGathering from '@/nex/protocols/match-making/methods/register-gathering'; +export * as UnregisterGathering from '@/nex/protocols/match-making/methods/unregister-gathering'; +export * as UnregisterGatherings from '@/nex/protocols/match-making/methods/unregister-gatherings'; +export * as UpdateGathering from '@/nex/protocols/match-making/methods/update-gathering'; +export * as Invite from '@/nex/protocols/match-making/methods/invite'; +export * as AcceptInvitation from '@/nex/protocols/match-making/methods/accept-invitation'; +export * as DeclineInvitation from '@/nex/protocols/match-making/methods/decline-invitation'; +export * as CancelInvitation from '@/nex/protocols/match-making/methods/cancel-invitation'; +export * as GetInvitationsSent from '@/nex/protocols/match-making/methods/get-invitations-sent'; +export * as GetInvitationsReceived from '@/nex/protocols/match-making/methods/get-invitations-received'; +export * as Participate from '@/nex/protocols/match-making/methods/participate'; +export * as CancelParticipation from '@/nex/protocols/match-making/methods/cancel-participation'; +export * as GetParticipants from '@/nex/protocols/match-making/methods/get-participants'; +export * as AddParticipants from '@/nex/protocols/match-making/methods/add-participants'; +export * as GetDetailedParticipants from '@/nex/protocols/match-making/methods/get-detailed-participants'; +export * as GetParticipantsURLs from '@/nex/protocols/match-making/methods/get-participants-urls'; +export * as FindByType from '@/nex/protocols/match-making/methods/find-by-type'; +export * as FindByDescription from '@/nex/protocols/match-making/methods/find-by-description'; +export * as FindByDescriptionRegex from '@/nex/protocols/match-making/methods/find-by-description-regex'; +export * as FindByID from '@/nex/protocols/match-making/methods/find-by-id'; +export * as FindBySingleID from '@/nex/protocols/match-making/methods/find-by-single-id'; +export * as FindByOwner from '@/nex/protocols/match-making/methods/find-by-owner'; +export * as FindByParticipants from '@/nex/protocols/match-making/methods/find-by-participants'; +export * as FindInvitations from '@/nex/protocols/match-making/methods/find-invitations'; +export * as FindBySQLQuery from '@/nex/protocols/match-making/methods/find-by-sql-query'; +export * as LaunchSession from '@/nex/protocols/match-making/methods/launch-session'; +export * as UpdateSessionURL from '@/nex/protocols/match-making/methods/update-session-url'; +export * as GetSessionURL from '@/nex/protocols/match-making/methods/get-session-url'; +export * as GetState from '@/nex/protocols/match-making/methods/get-state'; +export * as SetState from '@/nex/protocols/match-making/methods/set-state'; +export * as ReportStats from '@/nex/protocols/match-making/methods/report-stats'; +export * as GetStats from '@/nex/protocols/match-making/methods/get-stats'; +export * as DeleteGathering from '@/nex/protocols/match-making/methods/delete-gathering'; +export * as GetPendingDeletions from '@/nex/protocols/match-making/methods/get-pending-deletions'; +export * as DeleteFromDeletions from '@/nex/protocols/match-making/methods/delete-from-deletions'; +export * as MigrateGatheringOwnershipV1 from '@/nex/protocols/match-making/methods/migrate-gathering-ownership-v1'; +export * as FindByDescriptionLike from '@/nex/protocols/match-making/methods/find-by-description-like'; +export * as RegisterLocalURL from '@/nex/protocols/match-making/methods/register-local-url'; +export * as RegisterLocalURLs from '@/nex/protocols/match-making/methods/register-local-urls'; +export * as UpdateSessionHostV1 from '@/nex/protocols/match-making/methods/update-session-host-v1'; export * as GetSessionURLs from '@/nex/protocols/match-making/methods/get-session-urls'; -export * as UpdateSessionHost from '@/nex/protocols/match-making/methods/update-session-host'; \ No newline at end of file +export * as UpdateSessionHost from '@/nex/protocols/match-making/methods/update-session-host'; +export * as UpdateGatheringOwnership from '@/nex/protocols/match-making/methods/update-gathering-ownership'; +export * as MigrateGatheringOwnership from '@/nex/protocols/match-making/methods/migrate-gathering-ownership'; \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/invite.ts b/src/nex/protocols/match-making/methods/invite.ts new file mode 100644 index 0000000..ba854b5 --- /dev/null +++ b/src/nex/protocols/match-making/methods/invite.ts @@ -0,0 +1,51 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'Invite'; + + private idGathering = new UInt32(); + private lstPrincipals = new List(new PID()); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.lstPrincipals.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + lstPrincipals: this.lstPrincipals, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'Invite'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/launch-session.ts b/src/nex/protocols/match-making/methods/launch-session.ts new file mode 100644 index 0000000..d79e004 --- /dev/null +++ b/src/nex/protocols/match-making/methods/launch-session.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'LaunchSession'; + + private idGathering = new UInt32(); + private strURL = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.strURL.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + strURL: this.strURL + }; + } +} + +export class Response { + public static Name = 'LaunchSession'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/migrate-gathering-ownership-v1.ts b/src/nex/protocols/match-making/methods/migrate-gathering-ownership-v1.ts new file mode 100644 index 0000000..340f6ba --- /dev/null +++ b/src/nex/protocols/match-making/methods/migrate-gathering-ownership-v1.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'MigrateGatheringOwnershipV1'; + + private gid = new UInt32(); + private lstPotentialNewOwnersID = new List(new PID()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.lstPotentialNewOwnersID.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid, + lstPotentialNewOwnersID: this.lstPotentialNewOwnersID + }; + } +} + +export class Response { + public static Name = 'MigrateGatheringOwnershipV1'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/migrate-gathering-ownership.ts b/src/nex/protocols/match-making/methods/migrate-gathering-ownership.ts new file mode 100644 index 0000000..414ce6e --- /dev/null +++ b/src/nex/protocols/match-making/methods/migrate-gathering-ownership.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'MigrateGatheringOwnership'; + + private gid = new UInt32(); + private lstPotentialNewOwnersID = new List(new PID()); + private participantsOnly = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.lstPotentialNewOwnersID.extractFrom(stream); + this.participantsOnly.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid, + lstPotentialNewOwnersID: this.lstPotentialNewOwnersID, + participantsOnly: this.participantsOnly + }; + } +} + +// * No response data +export class Response { + public static Name = 'MigrateGatheringOwnership'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/participate.ts b/src/nex/protocols/match-making/methods/participate.ts new file mode 100644 index 0000000..cc1122d --- /dev/null +++ b/src/nex/protocols/match-making/methods/participate.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'Participate'; + + private idGathering = new UInt32(); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'Participate'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/register-gathering.ts b/src/nex/protocols/match-making/methods/register-gathering.ts new file mode 100644 index 0000000..a789eaa --- /dev/null +++ b/src/nex/protocols/match-making/methods/register-gathering.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'RegisterGathering'; + + private anyGathering = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.anyGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + anyGathering: this.anyGathering + }; + } +} + +export class Response { + public static Name = 'RegisterGathering'; + + private retval = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/register-local-url.ts b/src/nex/protocols/match-making/methods/register-local-url.ts new file mode 100644 index 0000000..6c5a2db --- /dev/null +++ b/src/nex/protocols/match-making/methods/register-local-url.ts @@ -0,0 +1,38 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import StationURL from '@/nex/types/station-url'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'RegisterLocalURL'; + + private gid = new UInt32(); + private url = new StationURL(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.url.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid, + url: this.url + }; + } +} + +// * No response data +export class Response { + public static Name = 'RegisterLocalURL'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/register-local-urls.ts b/src/nex/protocols/match-making/methods/register-local-urls.ts new file mode 100644 index 0000000..cb1f9d4 --- /dev/null +++ b/src/nex/protocols/match-making/methods/register-local-urls.ts @@ -0,0 +1,39 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import StationURL from '@/nex/types/station-url'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'RegisterLocalURLs'; + + private gid = new UInt32(); + private lstUrls = new List(new StationURL()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.lstUrls.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid, + lstUrls: this.lstUrls + }; + } +} + +// * No response data +export class Response { + public static Name = 'RegisterLocalURLs'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/report-stats.ts b/src/nex/protocols/match-making/methods/report-stats.ts new file mode 100644 index 0000000..b08d1b3 --- /dev/null +++ b/src/nex/protocols/match-making/methods/report-stats.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import GatheringStats from '@/nex/protocols/match-making/types/gathering-stats'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'ReportStats'; + + private idGathering = new UInt32(); + private lstStats = new List(new GatheringStats()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.lstStats.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + lstStats: this.lstStats + }; + } +} + +export class Response { + public static Name = 'ReportStats'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/set-state.ts b/src/nex/protocols/match-making/methods/set-state.ts new file mode 100644 index 0000000..0483ae3 --- /dev/null +++ b/src/nex/protocols/match-making/methods/set-state.ts @@ -0,0 +1,45 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'SetState'; + + private idGathering = new UInt32(); + private uiNewState = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.uiNewState.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + uiNewState: this.uiNewState + }; + } +} + +export class Response { + public static Name = 'SetState'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/unregister-gathering.ts b/src/nex/protocols/match-making/methods/unregister-gathering.ts new file mode 100644 index 0000000..9706e4a --- /dev/null +++ b/src/nex/protocols/match-making/methods/unregister-gathering.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UnregisterGathering'; + + private idGathering = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering + }; + } +} + +export class Response { + public static Name = 'UnregisterGathering'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/unregister-gatherings.ts b/src/nex/protocols/match-making/methods/unregister-gatherings.ts new file mode 100644 index 0000000..fc608fa --- /dev/null +++ b/src/nex/protocols/match-making/methods/unregister-gatherings.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UnregisterGatherings'; + + private lstGatherings = new List(new UInt32()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGatherings.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGatherings: this.lstGatherings + }; + } +} + +export class Response { + public static Name = 'UnregisterGatherings'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/update-gathering-ownership.ts b/src/nex/protocols/match-making/methods/update-gathering-ownership.ts new file mode 100644 index 0000000..5b5eed1 --- /dev/null +++ b/src/nex/protocols/match-making/methods/update-gathering-ownership.ts @@ -0,0 +1,45 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UpdateGatheringOwnership'; + + private gid = new UInt32(); + private participantsOnly = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.participantsOnly.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid, + participantsOnly: this.participantsOnly + }; + } +} + +export class Response { + public static Name = 'UpdateGatheringOwnership'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/update-gathering.ts b/src/nex/protocols/match-making/methods/update-gathering.ts new file mode 100644 index 0000000..654fd3c --- /dev/null +++ b/src/nex/protocols/match-making/methods/update-gathering.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UpdateGathering'; + + private anyGathering = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.anyGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + anyGathering: this.anyGathering + }; + } +} + +export class Response { + public static Name = 'UpdateGathering'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/update-session-host-v1.ts b/src/nex/protocols/match-making/methods/update-session-host-v1.ts new file mode 100644 index 0000000..5efdab8 --- /dev/null +++ b/src/nex/protocols/match-making/methods/update-session-host-v1.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UpdateSessionHostV1'; + + private gid = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid + }; + } +} + +// * No response data +export class Response { + public static Name = 'UpdateSessionHostV1'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/update-session-host.ts b/src/nex/protocols/match-making/methods/update-session-host.ts index 737f410..93d064e 100644 --- a/src/nex/protocols/match-making/methods/update-session-host.ts +++ b/src/nex/protocols/match-making/methods/update-session-host.ts @@ -2,7 +2,8 @@ import NEXByteStream from '@/nex/byte-stream'; import UInt32 from '@/nex/types/uint32'; import Bool from '@/nex/types/bool'; import type RMCMessage from '@/nex/rmc-message'; -import type * as RMCs from '@/types/nex/rmcs/match-making/update-session-host'; + +// TODO - Add strict types for toJSON methods export class Request { public static Name = 'UpdateSessionHost'; @@ -17,7 +18,7 @@ export class Request { this.isMigrateOwner.extractFrom(stream); } - public toJSON(): RMCs.Response { + public toJSON(): any { return { gid: this.gid, isMigrateOwner: this.isMigrateOwner @@ -31,7 +32,7 @@ export class Response { constructor() {} - public toJSON(): RMCs.Response { + public toJSON(): any { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/match-making/methods/update-session-url.ts b/src/nex/protocols/match-making/methods/update-session-url.ts new file mode 100644 index 0000000..cef7f68 --- /dev/null +++ b/src/nex/protocols/match-making/methods/update-session-url.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UpdateSessionURL'; + + private idGathering = new UInt32(); + private strURL = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.idGathering.extractFrom(stream); + this.strURL.extractFrom(stream); + } + + public toJSON(): any { + return { + idGathering: this.idGathering, + strURL: this.strURL + }; + } +} + +export class Response { + public static Name = 'UpdateSessionURL'; + + private retval = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.retval.extractFrom(stream); + } + + public toJSON(): any { + return { + retval: this.retval + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/create-matchmake-session-param.ts b/src/nex/protocols/match-making/types/create-matchmake-session-param.ts new file mode 100644 index 0000000..065452e --- /dev/null +++ b/src/nex/protocols/match-making/types/create-matchmake-session-param.ts @@ -0,0 +1,50 @@ +import Structure from '@/nex/types/structure'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import UInt16 from '@/nex/types/uint16'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class CreateMatchmakeSessionParam extends Structure { + public readonly typeName = 'CreateMatchmakeSessionParam'; + + private sourceMatchmakeSession = new MatchmakeSession(); + private additionalParticipants = new List(new PID()); + private gidForParticipationCheck = new UInt32(); + private createMatchmakeSessionOption = new UInt32(); + private joinMessage = new RVString(); + private participationCount = new UInt16(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.sourceMatchmakeSession.extractFrom(stream); + this.additionalParticipants.extractFrom(stream); + this.gidForParticipationCheck.extractFrom(stream); + this.createMatchmakeSessionOption.extractFrom(stream); + this.joinMessage.extractFrom(stream); + this.participationCount.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + sourceMatchmakeSession: this.sourceMatchmakeSession, + additionalParticipants: this.additionalParticipants, + gidForParticipationCheck: this.gidForParticipationCheck, + createMatchmakeSessionOption: this.createMatchmakeSessionOption, + joinMessage: this.joinMessage, + participationCount: this.participationCount + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/deletion-entry.ts b/src/nex/protocols/match-making/types/deletion-entry.ts new file mode 100644 index 0000000..c87dc92 --- /dev/null +++ b/src/nex/protocols/match-making/types/deletion-entry.ts @@ -0,0 +1,37 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import PID from '@/nex/types/pid'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class DeletionEntry extends Structure { + public readonly typeName = 'DeletionEntry'; + + private m_idGathering = new UInt32(); + private m_pid = new PID(); + private m_uiReason = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_idGathering.extractFrom(stream); + this.m_pid.extractFrom(stream); + this.m_uiReason.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_idGathering: this.m_idGathering, + m_pid: this.m_pid, + m_uiReason: this.m_uiReason + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/find-matchmake-session-by-participant-param.ts b/src/nex/protocols/match-making/types/find-matchmake-session-by-participant-param.ts new file mode 100644 index 0000000..2dcaadb --- /dev/null +++ b/src/nex/protocols/match-making/types/find-matchmake-session-by-participant-param.ts @@ -0,0 +1,39 @@ +import Structure from '@/nex/types/structure'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import UInt32 from '@/nex/types/uint32'; +import MatchmakeBlockListParam from '@/nex/protocols/match-making/types/matchmake-block-list-param'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class FindMatchmakeSessionByParticipantParam extends Structure { + public readonly typeName = 'FindMatchmakeSessionByParticipantParam'; + + private m_principalIdList = new List(new PID()); + private m_resultOptions = new UInt32(); + private m_blockListParam = new MatchmakeBlockListParam(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_principalIdList.extractFrom(stream); + this.m_resultOptions.extractFrom(stream); + this.m_blockListParam.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_principalIdList: this.m_principalIdList, + m_resultOptions: this.m_resultOptions, + m_blockListParam: this.m_blockListParam + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/find-matchmake-session-by-participant-result.ts b/src/nex/protocols/match-making/types/find-matchmake-session-by-participant-result.ts new file mode 100644 index 0000000..1e56931 --- /dev/null +++ b/src/nex/protocols/match-making/types/find-matchmake-session-by-participant-result.ts @@ -0,0 +1,34 @@ +import Structure from '@/nex/types/structure'; +import PID from '@/nex/types/pid'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class FindMatchmakeSessionByParticipantResult extends Structure { + public readonly typeName = 'FindMatchmakeSessionByParticipantResult'; + + private m_principalId = new PID(); + private m_session = new MatchmakeSession(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_principalId.extractFrom(stream); + this.m_session.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_principalId: this.m_principalId, + m_session: this.m_session + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/gathering-stats.ts b/src/nex/protocols/match-making/types/gathering-stats.ts new file mode 100644 index 0000000..cef6e46 --- /dev/null +++ b/src/nex/protocols/match-making/types/gathering-stats.ts @@ -0,0 +1,39 @@ +import Structure from '@/nex/types/structure'; +import PID from '@/nex/types/pid'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import Float from '@/nex/types/float'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class GatheringStats extends Structure { + public readonly typeName = 'GatheringStats'; + + private m_pidParticipant = new PID(); + private m_uiFlags = new UInt32(); + private m_lstValues = new List(new Float()); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_pidParticipant.extractFrom(stream); + this.m_uiFlags.extractFrom(stream); + this.m_lstValues.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_pidParticipant: this.m_pidParticipant, + m_uiFlags: this.m_uiFlags, + m_lstValues: this.m_lstValues + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/gathering-urls.ts b/src/nex/protocols/match-making/types/gathering-urls.ts index 9a535f3..0c0c40a 100644 --- a/src/nex/protocols/match-making/types/gathering-urls.ts +++ b/src/nex/protocols/match-making/types/gathering-urls.ts @@ -5,9 +5,7 @@ import StationURL from '@/nex/types/station-url'; import type NEXByteStream from '@/nex/byte-stream'; export default class GatheringURLs extends Structure { - public get typeName(): string { - return 'Gathering'; - } + public readonly typeName = 'GatheringURLs'; private m_gid = new UInt32(); private m_lstStationURLs = new List(new StationURL); diff --git a/src/nex/protocols/match-making/types/invitation.ts b/src/nex/protocols/match-making/types/invitation.ts new file mode 100644 index 0000000..a93dac8 --- /dev/null +++ b/src/nex/protocols/match-making/types/invitation.ts @@ -0,0 +1,37 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class GatheringStats extends Structure { + public readonly typeName = 'GatheringStats'; + + private m_idGathering = new UInt32(); + private m_idGuest = new UInt32(); + private m_strMessage = new RVString(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_idGathering.extractFrom(stream); + this.m_idGuest.extractFrom(stream); + this.m_strMessage.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_idGathering: this.m_idGathering, + m_idGuest: this.m_idGuest, + m_strMessage: this.m_strMessage + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/join-matchmake-session-param.ts b/src/nex/protocols/match-making/types/join-matchmake-session-param.ts new file mode 100644 index 0000000..4bf6388 --- /dev/null +++ b/src/nex/protocols/match-making/types/join-matchmake-session-param.ts @@ -0,0 +1,66 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import UInt8 from '@/nex/types/uint8'; +import RVString from '@/nex/types/string'; +import UInt16 from '@/nex/types/uint16'; +import MatchmakeBlockListParam from '@/nex/protocols/match-making/types/matchmake-block-list-param'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class JoinMatchmakeSessionParam extends Structure { + public readonly typeName = 'JoinMatchmakeSessionParam'; + + private gid = new UInt32(); + private additionalParticipants = new List(new PID()); + private gidForParticipationCheck = new UInt32(); + private joinMatchmakeSessionOption = new UInt32(); + private joinMatchmakeSessionBehavior = new UInt8(); + private strUserPassword = new RVString(); + private strSystemPassword = new RVString(); + private joinMessage = new RVString(); + private participationCount = new UInt16(); + private extraParticipants = new UInt16(); + private blockListParam = new MatchmakeBlockListParam(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.gid.extractFrom(stream); + this.additionalParticipants.extractFrom(stream); + this.gidForParticipationCheck.extractFrom(stream); + this.joinMatchmakeSessionOption.extractFrom(stream); + this.joinMatchmakeSessionBehavior.extractFrom(stream); + this.strUserPassword.extractFrom(stream); + this.strSystemPassword.extractFrom(stream); + this.joinMessage.extractFrom(stream); + this.participationCount.extractFrom(stream); + this.extraParticipants.extractFrom(stream); + this.blockListParam.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + gid: this.gid, + additionalParticipants: this.additionalParticipants, + gidForParticipationCheck: this.gidForParticipationCheck, + joinMatchmakeSessionOption: this.joinMatchmakeSessionOption, + joinMatchmakeSessionBehavior: this.joinMatchmakeSessionBehavior, + strUserPassword: this.strUserPassword, + strSystemPassword: this.strSystemPassword, + joinMessage: this.joinMessage, + participationCount: this.participationCount, + extraParticipants: this.extraParticipants, + blockListParam: this.blockListParam + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/matchmake-session-search-criteria.ts b/src/nex/protocols/match-making/types/matchmake-session-search-criteria.ts index 012e29e..6ed4ecd 100644 --- a/src/nex/protocols/match-making/types/matchmake-session-search-criteria.ts +++ b/src/nex/protocols/match-making/types/matchmake-session-search-criteria.ts @@ -10,9 +10,7 @@ import MatchmakeParam from '@/nex/protocols/match-making/types/matchmake-param'; import type NEXByteStream from '@/nex/byte-stream'; export default class MatchmakeSessionSearchCriteria extends Structure { - public get typeName(): string { - return 'MatchmakeSessionSearchCriteria'; - } + public readonly typeName = 'MatchmakeSessionSearchCriteria'; private m_Attribs = new List(new RVString()); private m_GameMode = new RVString(); diff --git a/src/nex/protocols/match-making/types/participant-details.ts b/src/nex/protocols/match-making/types/participant-details.ts index 86ec580..4c21a8a 100644 --- a/src/nex/protocols/match-making/types/participant-details.ts +++ b/src/nex/protocols/match-making/types/participant-details.ts @@ -5,9 +5,7 @@ import UInt16 from '@/nex/types/uint16'; import type NEXByteStream from '@/nex/byte-stream'; export default class ParticipantDetails extends Structure { - public get typeName(): string { - return 'ParticipantDetails'; - } + public readonly typeName = 'ParticipantDetails'; private m_idParticipant = new PID(); private m_strName = new RVString(); diff --git a/src/nex/protocols/match-making/types/simple-community.ts b/src/nex/protocols/match-making/types/simple-community.ts new file mode 100644 index 0000000..7e82adc --- /dev/null +++ b/src/nex/protocols/match-making/types/simple-community.ts @@ -0,0 +1,33 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class SimpleCommunity extends Structure { + public readonly typeName = 'SimpleCommunity'; + + private m_GatheringID = new UInt32(); + private m_MatchmakeSessionCount = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.m_GatheringID.extractFrom(stream); + this.m_MatchmakeSessionCount.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + m_GatheringID: this.m_GatheringID, + m_MatchmakeSessionCount: this.m_MatchmakeSessionCount + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/match-making/types/update-matchmake-session-param.ts b/src/nex/protocols/match-making/types/update-matchmake-session-param.ts new file mode 100644 index 0000000..f8b7b6c --- /dev/null +++ b/src/nex/protocols/match-making/types/update-matchmake-session-param.ts @@ -0,0 +1,86 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import Bool from '@/nex/types/bool'; +import RVBuffer from '@/nex/types/buffer'; +import UInt8 from '@/nex/types/uint8'; +import DateTime from '@/nex/types/datetime'; +import RVString from '@/nex/types/string'; +import UInt16 from '@/nex/types/uint16'; +import MatchmakeParam from '@/nex/protocols/match-making/types/matchmake-param'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class UpdateMatchmakeSessionParam extends Structure { + public readonly typeName = 'UpdateMatchmakeSessionParam'; + + private gid = new UInt32(); + private modificationFlag = new UInt32(); + private attributes = new List(new UInt32()); + private openParticipation = new Bool(); + private applicationBuffer = new RVBuffer(); + private progressScore = new UInt8(); + private matchmakeParam = new MatchmakeParam(); + private startedTime = new DateTime(); + private userPassword = new RVString(); + private gameMode = new UInt32(); + private description = new RVString(); + private minParticipants = new UInt16(); + private maxParticipants = new UInt16(); + private matchmakeSystemType = new UInt32(); + private participationPolicy = new UInt32(); + private policyArgument = new UInt32(); + private codeword = new RVString(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.gid.extractFrom(stream); + this.modificationFlag.extractFrom(stream); + this.attributes.extractFrom(stream); + this.openParticipation.extractFrom(stream); + this.applicationBuffer.extractFrom(stream); + this.progressScore.extractFrom(stream); + this.matchmakeParam.extractFrom(stream); + this.startedTime.extractFrom(stream); + this.userPassword.extractFrom(stream); + this.gameMode.extractFrom(stream); + this.description.extractFrom(stream); + this.minParticipants.extractFrom(stream); + this.maxParticipants.extractFrom(stream); + this.matchmakeSystemType.extractFrom(stream); + this.participationPolicy.extractFrom(stream); + this.policyArgument.extractFrom(stream); + this.codeword.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): Record { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + gid: this.gid, + modificationFlag: this.modificationFlag, + attributes: this.attributes, + openParticipation: this.openParticipation, + applicationBuffer: this.applicationBuffer, + progressScore: this.progressScore, + matchmakeParam: this.matchmakeParam, + startedTime: this.startedTime, + userPassword: this.userPassword, + gameMode: this.gameMode, + description: this.description, + minParticipants: this.minParticipants, + maxParticipants: this.maxParticipants, + matchmakeSystemType: this.matchmakeSystemType, + participationPolicy: this.participationPolicy, + policyArgument: this.policyArgument, + codeword: this.codeword + } + }; + } +} \ No newline at end of file From 6b1140b81df31ea8039ae23856cc51b862cb21ee Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Wed, 8 Jan 2025 03:29:00 -0500 Subject: [PATCH 63/67] feat: complete MatchmakeExtension protocol --- .../protocols/matchmake-extension/index.ts | 474 +++++++++++++++++- .../methods/add-to-black-list.ts | 35 ++ .../methods/auto-matchmake-postpone.ts | 45 ++ ...to-matchmake-with-gathering-id-postpone.ts | 50 ++ .../auto-matchmake-with-param-postpone.ts | 7 +- ...matchmake-with-search-criteria-postpone.ts | 37 +- ...hmake-session-no-holder-no-result-range.ts | 43 ++ .../browse-matchmake-session-no-holder.ts | 47 ++ ...ith-host-urls-no-holder-no-result-range.ts | 47 ++ ...chmake-session-with-host-urls-no-holder.ts | 51 ++ ...browse-matchmake-session-with-host-urls.ts | 51 ++ .../methods/browse-matchmake-session.ts | 47 ++ ...clear-matchmake-session-system-password.ts | 34 ++ .../methods/clear-my-black-list.ts | 23 + .../methods/close-participation.ts | 7 +- .../methods/create-community.ts | 46 ++ .../create-matchmake-session-with-param.ts | 42 ++ .../methods/create-matchmake-session.ts | 73 +++ .../methods/debug-notify-event.ts | 52 ++ .../methods/find-community-by-gathering-id.ts | 43 ++ .../methods/find-community-by-participant.ts | 47 ++ ...atchmake-session-by-gathering-id-detail.ts | 42 ++ .../find-matchmake-session-by-gathering-id.ts | 43 ++ .../find-matchmake-session-by-owner.ts | 47 ++ .../find-matchmake-session-by-participant.ts | 43 ++ ...atchmake-session-by-single-gathering-id.ts | 42 ++ .../methods/find-official-community.ts | 7 +- ...erate-matchmake-session-system-password.ts | 42 ++ .../methods/get-friend-notification-data.ts | 43 ++ .../get-lst-friend-notification-data.ts | 43 ++ .../methods/get-my-black-list.ts | 35 ++ .../methods/get-playing-session.ts | 7 +- .../methods/get-simple-community.ts | 43 ++ .../methods/get-simple-playing-session.ts | 7 +- .../matchmake-extension/methods/index.ts | 48 +- .../methods/is-violation-user.ts | 38 ++ .../methods/join-community.ts | 41 ++ .../methods/join-matchmake-session-ex.ts | 64 +++ .../join-matchmake-session-with-param.ts | 42 ++ .../methods/join-matchmake-session.ts | 56 +++ .../methods/modify-current-game-attribute.ts | 40 ++ .../methods/open-participation.ts | 34 ++ .../methods/remove-from-black-list.ts | 35 ++ .../methods/report-violation.ts | 42 ++ .../methods/request-matchmaking.ts | 42 ++ .../methods/update-application-buffer.ts | 38 ++ .../methods/update-community.ts | 34 ++ .../update-matchmake-session-attribute.ts | 38 ++ .../methods/update-matchmake-session-part.ts | 34 ++ .../methods/update-matchmake-session.ts | 34 ++ .../methods/update-notification-data.ts | 55 ++ .../methods/update-privacy-setting.ts | 37 ++ .../methods/update-progress-score.ts | 7 +- .../methods/withdraw-matchmaking-all.ts | 23 + .../methods/withdraw-matchmaking.ts | 34 ++ 55 files changed, 2520 insertions(+), 41 deletions(-) create mode 100644 src/nex/protocols/matchmake-extension/methods/add-to-black-list.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/auto-matchmake-postpone.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-gathering-id-postpone.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-no-holder-no-result-range.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-no-holder.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls-no-holder-no-result-range.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls-no-holder.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/browse-matchmake-session.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/clear-matchmake-session-system-password.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/clear-my-black-list.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/create-community.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/create-matchmake-session-with-param.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/create-matchmake-session.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/debug-notify-event.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/find-community-by-gathering-id.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/find-community-by-participant.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-gathering-id-detail.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-gathering-id.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-owner.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-participant.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-single-gathering-id.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/generate-matchmake-session-system-password.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/get-friend-notification-data.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/get-lst-friend-notification-data.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/get-my-black-list.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/get-simple-community.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/is-violation-user.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/join-community.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/join-matchmake-session-ex.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/join-matchmake-session-with-param.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/join-matchmake-session.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/modify-current-game-attribute.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/open-participation.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/remove-from-black-list.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/report-violation.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/request-matchmaking.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/update-application-buffer.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/update-community.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/update-matchmake-session-attribute.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/update-matchmake-session-part.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/update-matchmake-session.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/update-notification-data.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/update-privacy-setting.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/withdraw-matchmaking-all.ts create mode 100644 src/nex/protocols/matchmake-extension/methods/withdraw-matchmaking.ts diff --git a/src/nex/protocols/matchmake-extension/index.ts b/src/nex/protocols/matchmake-extension/index.ts index 0666bd8..a3187a6 100644 --- a/src/nex/protocols/matchmake-extension/index.ts +++ b/src/nex/protocols/matchmake-extension/index.ts @@ -64,13 +64,59 @@ export default class MatchmakeExtensionProtocol { }; private static handlers: Record any> = { - 0x1: MatchmakeExtensionProtocol.CloseParticipation, + 0x01: MatchmakeExtensionProtocol.CloseParticipation, + 0x02: MatchmakeExtensionProtocol.OpenParticipation, + 0x03: MatchmakeExtensionProtocol.AutoMatchmake_Postpone, + 0x04: MatchmakeExtensionProtocol.BrowseMatchmakeSession, + 0x05: MatchmakeExtensionProtocol.BrowseMatchmakeSessionWithHostUrls, + 0x06: MatchmakeExtensionProtocol.CreateMatchmakeSession, + 0x07: MatchmakeExtensionProtocol.JoinMatchmakeSession, + 0x08: MatchmakeExtensionProtocol.ModifyCurrentGameAttribute, + 0x09: MatchmakeExtensionProtocol.UpdateNotificationData, + 0x0A: MatchmakeExtensionProtocol.GetFriendNotificationData, + 0x0B: MatchmakeExtensionProtocol.UpdateApplicationBuffer, + 0x0C: MatchmakeExtensionProtocol.UpdateMatchmakeSessionAttribute, + 0x0D: MatchmakeExtensionProtocol.GetlstFriendNotificationData, + 0x0E: MatchmakeExtensionProtocol.UpdateMatchmakeSession, 0x0F: MatchmakeExtensionProtocol.AutoMatchmakeWithSearchCriteria_Postpone, 0x10: MatchmakeExtensionProtocol.GetPlayingSession, + 0x11: MatchmakeExtensionProtocol.CreateCommunity, + 0x12: MatchmakeExtensionProtocol.UpdateCommunity, + 0x13: MatchmakeExtensionProtocol.JoinCommunity, + 0x14: MatchmakeExtensionProtocol.FindCommunityByGatheringId, 0x15: MatchmakeExtensionProtocol.FindOfficialCommunity, + 0x16: MatchmakeExtensionProtocol.FindCommunityByParticipant, + 0x17: MatchmakeExtensionProtocol.UpdatePrivacySetting, + 0x18: MatchmakeExtensionProtocol.GetMyBlackList, + 0x19: MatchmakeExtensionProtocol.AddToBlackList, + 0x1A: MatchmakeExtensionProtocol.RemoveFromBlackList, + 0x1B: MatchmakeExtensionProtocol.ClearMyBlackList, + 0x1C: MatchmakeExtensionProtocol.ReportViolation, + 0x1D: MatchmakeExtensionProtocol.IsViolationUser, + 0x1E: MatchmakeExtensionProtocol.JoinMatchmakeSessionEx, 0x1F: MatchmakeExtensionProtocol.GetSimplePlayingSession, + 0x20: MatchmakeExtensionProtocol.GetSimpleCommunity, + 0x21: MatchmakeExtensionProtocol.AutoMatchmakeWithGatheringId_Postpone, 0x22: MatchmakeExtensionProtocol.UpdateProgressScore, + 0x23: MatchmakeExtensionProtocol.DebugNotifyEvent, + 0x24: MatchmakeExtensionProtocol.GenerateMatchmakeSessionSystemPassword, + 0x25: MatchmakeExtensionProtocol.ClearMatchmakeSessionSystemPassword, + 0x26: MatchmakeExtensionProtocol.CreateMatchmakeSessionWithParam, + 0x27: MatchmakeExtensionProtocol.JoinMatchmakeSessionWithParam, 0x28: MatchmakeExtensionProtocol.AutoMatchmakeWithParam_Postpone, + 0x29: MatchmakeExtensionProtocol.FindMatchmakeSessionByGatheringIdDetail, + 0x2A: MatchmakeExtensionProtocol.BrowseMatchmakeSessionNoHolder, + 0x2B: MatchmakeExtensionProtocol.BrowseMatchmakeSessionWithHostUrlsNoHolder, + 0x2C: MatchmakeExtensionProtocol.UpdateMatchmakeSessionPart, + 0x2D: MatchmakeExtensionProtocol.RequestMatchmaking, + 0x2E: MatchmakeExtensionProtocol.WithdrawMatchmaking, + 0x2F: MatchmakeExtensionProtocol.WithdrawMatchmakingAll, + 0x30: MatchmakeExtensionProtocol.FindMatchmakeSessionByGatheringId, + 0x31: MatchmakeExtensionProtocol.FindMatchmakeSessionBySingleGatheringId, + 0x32: MatchmakeExtensionProtocol.FindMatchmakeSessionByOwner, + 0x33: MatchmakeExtensionProtocol.FindMatchmakeSessionByParticipant, + 0x34: MatchmakeExtensionProtocol.BrowseMatchmakeSessionNoHolderNoResultRange, + 0x35: MatchmakeExtensionProtocol.BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange }; static handlePacket(packet: Packet): void { @@ -101,6 +147,133 @@ export default class MatchmakeExtensionProtocol { } } + + private static OpenParticipation(message: RMCMessage): typeof Methods.OpenParticipation.Request | typeof Methods.OpenParticipation.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.OpenParticipation.Request; + } else { + return Methods.OpenParticipation.Response; + } + } + + + private static AutoMatchmake_Postpone(message: RMCMessage): typeof Methods.AutoMatchmake_Postpone.Request | typeof Methods.AutoMatchmake_Postpone.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.AutoMatchmake_Postpone.Request; + } else { + return Methods.AutoMatchmake_Postpone.Response; + } + } + + + private static BrowseMatchmakeSession(message: RMCMessage): typeof Methods.BrowseMatchmakeSession.Request | typeof Methods.BrowseMatchmakeSession.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.BrowseMatchmakeSession.Request; + } else { + return Methods.BrowseMatchmakeSession.Response; + } + } + + + private static BrowseMatchmakeSessionWithHostUrls(message: RMCMessage): typeof Methods.BrowseMatchmakeSessionWithHostUrls.Request | typeof Methods.BrowseMatchmakeSessionWithHostUrls.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.BrowseMatchmakeSessionWithHostUrls.Request; + } else { + return Methods.BrowseMatchmakeSessionWithHostUrls.Response; + } + } + + + private static CreateMatchmakeSession(message: RMCMessage): typeof Methods.CreateMatchmakeSession.Request | typeof Methods.CreateMatchmakeSession.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.CreateMatchmakeSession.Request; + } else { + return Methods.CreateMatchmakeSession.Response; + } + } + + + private static JoinMatchmakeSession(message: RMCMessage): typeof Methods.JoinMatchmakeSession.Request | typeof Methods.JoinMatchmakeSession.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.JoinMatchmakeSession.Request; + } else { + return Methods.JoinMatchmakeSession.Response; + } + } + + + private static ModifyCurrentGameAttribute(message: RMCMessage): typeof Methods.ModifyCurrentGameAttribute.Request | typeof Methods.ModifyCurrentGameAttribute.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ModifyCurrentGameAttribute.Request; + } else { + return Methods.ModifyCurrentGameAttribute.Response; + } + } + + + private static UpdateNotificationData(message: RMCMessage): typeof Methods.UpdateNotificationData.Request | typeof Methods.UpdateNotificationData.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateNotificationData.Request; + } else { + return Methods.UpdateNotificationData.Response; + } + } + + + private static GetFriendNotificationData(message: RMCMessage): typeof Methods.GetFriendNotificationData.Request | typeof Methods.GetFriendNotificationData.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetFriendNotificationData.Request; + } else { + return Methods.GetFriendNotificationData.Response; + } + } + + + private static UpdateApplicationBuffer(message: RMCMessage): typeof Methods.UpdateApplicationBuffer.Request | typeof Methods.UpdateApplicationBuffer.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateApplicationBuffer.Request; + } else { + return Methods.UpdateApplicationBuffer.Response; + } + } + + + private static UpdateMatchmakeSessionAttribute(message: RMCMessage): typeof Methods.UpdateMatchmakeSessionAttribute.Request | typeof Methods.UpdateMatchmakeSessionAttribute.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateMatchmakeSessionAttribute.Request; + } else { + return Methods.UpdateMatchmakeSessionAttribute.Response; + } + } + + + private static GetlstFriendNotificationData(message: RMCMessage): typeof Methods.GetlstFriendNotificationData.Request | typeof Methods.GetlstFriendNotificationData.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetlstFriendNotificationData.Request; + } else { + return Methods.GetlstFriendNotificationData.Response; + } + } + + + private static UpdateMatchmakeSession(message: RMCMessage): typeof Methods.UpdateMatchmakeSession.Request | typeof Methods.UpdateMatchmakeSession.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateMatchmakeSession.Request; + } else { + return Methods.UpdateMatchmakeSession.Response; + } + } + + + private static AutoMatchmakeWithSearchCriteria_Postpone(message: RMCMessage): typeof Methods.AutoMatchmakeWithSearchCriteria_Postpone.Request | typeof Methods.AutoMatchmakeWithSearchCriteria_Postpone.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.AutoMatchmakeWithSearchCriteria_Postpone.Request; + } else { + return Methods.AutoMatchmakeWithSearchCriteria_Postpone.Response; + } + } + + private static GetPlayingSession(message: RMCMessage): typeof Methods.GetPlayingSession.Request | typeof Methods.GetPlayingSession.Response { if (message.type === RMCMessage.REQUEST) { return Methods.GetPlayingSession.Request; @@ -109,6 +282,43 @@ export default class MatchmakeExtensionProtocol { } } + + private static CreateCommunity(message: RMCMessage): typeof Methods.CreateCommunity.Request | typeof Methods.CreateCommunity.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.CreateCommunity.Request; + } else { + return Methods.CreateCommunity.Response; + } + } + + + private static UpdateCommunity(message: RMCMessage): typeof Methods.UpdateCommunity.Request | typeof Methods.UpdateCommunity.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateCommunity.Request; + } else { + return Methods.UpdateCommunity.Response; + } + } + + + private static JoinCommunity(message: RMCMessage): typeof Methods.JoinCommunity.Request | typeof Methods.JoinCommunity.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.JoinCommunity.Request; + } else { + return Methods.JoinCommunity.Response; + } + } + + + private static FindCommunityByGatheringId(message: RMCMessage): typeof Methods.FindCommunityByGatheringId.Request | typeof Methods.FindCommunityByGatheringId.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindCommunityByGatheringId.Request; + } else { + return Methods.FindCommunityByGatheringId.Response; + } + } + + private static FindOfficialCommunity(message: RMCMessage): typeof Methods.FindOfficialCommunity.Request | typeof Methods.FindOfficialCommunity.Response { if (message.type === RMCMessage.REQUEST) { return Methods.FindOfficialCommunity.Request; @@ -117,6 +327,88 @@ export default class MatchmakeExtensionProtocol { } } + + private static FindCommunityByParticipant(message: RMCMessage): typeof Methods.FindCommunityByParticipant.Request | typeof Methods.FindCommunityByParticipant.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindCommunityByParticipant.Request; + } else { + return Methods.FindCommunityByParticipant.Response; + } + } + + + private static UpdatePrivacySetting(message: RMCMessage): typeof Methods.UpdatePrivacySetting.Request | typeof Methods.UpdatePrivacySetting.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdatePrivacySetting.Request; + } else { + return Methods.UpdatePrivacySetting.Response; + } + } + + + private static GetMyBlackList(message: RMCMessage): typeof Methods.GetMyBlackList.Request | typeof Methods.GetMyBlackList.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetMyBlackList.Request; + } else { + return Methods.GetMyBlackList.Response; + } + } + + + private static AddToBlackList(message: RMCMessage): typeof Methods.AddToBlackList.Request | typeof Methods.AddToBlackList.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.AddToBlackList.Request; + } else { + return Methods.AddToBlackList.Response; + } + } + + + private static RemoveFromBlackList(message: RMCMessage): typeof Methods.RemoveFromBlackList.Request | typeof Methods.RemoveFromBlackList.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.RemoveFromBlackList.Request; + } else { + return Methods.RemoveFromBlackList.Response; + } + } + + + private static ClearMyBlackList(message: RMCMessage): typeof Methods.ClearMyBlackList.Request | typeof Methods.ClearMyBlackList.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ClearMyBlackList.Request; + } else { + return Methods.ClearMyBlackList.Response; + } + } + + + private static ReportViolation(message: RMCMessage): typeof Methods.ReportViolation.Request | typeof Methods.ReportViolation.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ReportViolation.Request; + } else { + return Methods.ReportViolation.Response; + } + } + + + private static IsViolationUser(message: RMCMessage): typeof Methods.IsViolationUser.Request | typeof Methods.IsViolationUser.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.IsViolationUser.Request; + } else { + return Methods.IsViolationUser.Response; + } + } + + + private static JoinMatchmakeSessionEx(message: RMCMessage): typeof Methods.JoinMatchmakeSessionEx.Request | typeof Methods.JoinMatchmakeSessionEx.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.JoinMatchmakeSessionEx.Request; + } else { + return Methods.JoinMatchmakeSessionEx.Response; + } + } + + private static GetSimplePlayingSession(message: RMCMessage): typeof Methods.GetSimplePlayingSession.Request | typeof Methods.GetSimplePlayingSession.Response { if (message.type === RMCMessage.REQUEST) { return Methods.GetSimplePlayingSession.Request; @@ -125,6 +417,25 @@ export default class MatchmakeExtensionProtocol { } } + + private static GetSimpleCommunity(message: RMCMessage): typeof Methods.GetSimpleCommunity.Request | typeof Methods.GetSimpleCommunity.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetSimpleCommunity.Request; + } else { + return Methods.GetSimpleCommunity.Response; + } + } + + + private static AutoMatchmakeWithGatheringId_Postpone(message: RMCMessage): typeof Methods.AutoMatchmakeWithGatheringId_Postpone.Request | typeof Methods.AutoMatchmakeWithGatheringId_Postpone.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.AutoMatchmakeWithGatheringId_Postpone.Request; + } else { + return Methods.AutoMatchmakeWithGatheringId_Postpone.Response; + } + } + + private static UpdateProgressScore(message: RMCMessage): typeof Methods.UpdateProgressScore.Request | typeof Methods.UpdateProgressScore.Response { if (message.type === RMCMessage.REQUEST) { return Methods.UpdateProgressScore.Request; @@ -133,6 +444,52 @@ export default class MatchmakeExtensionProtocol { } } + + private static DebugNotifyEvent(message: RMCMessage): typeof Methods.DebugNotifyEvent.Request | typeof Methods.DebugNotifyEvent.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.DebugNotifyEvent.Request; + } else { + return Methods.DebugNotifyEvent.Response; + } + } + + + private static GenerateMatchmakeSessionSystemPassword(message: RMCMessage): typeof Methods.GenerateMatchmakeSessionSystemPassword.Request | typeof Methods.GenerateMatchmakeSessionSystemPassword.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GenerateMatchmakeSessionSystemPassword.Request; + } else { + return Methods.GenerateMatchmakeSessionSystemPassword.Response; + } + } + + + private static ClearMatchmakeSessionSystemPassword(message: RMCMessage): typeof Methods.ClearMatchmakeSessionSystemPassword.Request | typeof Methods.ClearMatchmakeSessionSystemPassword.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ClearMatchmakeSessionSystemPassword.Request; + } else { + return Methods.ClearMatchmakeSessionSystemPassword.Response; + } + } + + + private static CreateMatchmakeSessionWithParam(message: RMCMessage): typeof Methods.CreateMatchmakeSessionWithParam.Request | typeof Methods.CreateMatchmakeSessionWithParam.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.CreateMatchmakeSessionWithParam.Request; + } else { + return Methods.CreateMatchmakeSessionWithParam.Response; + } + } + + + private static JoinMatchmakeSessionWithParam(message: RMCMessage): typeof Methods.JoinMatchmakeSessionWithParam.Request | typeof Methods.JoinMatchmakeSessionWithParam.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.JoinMatchmakeSessionWithParam.Request; + } else { + return Methods.JoinMatchmakeSessionWithParam.Response; + } + } + + private static AutoMatchmakeWithParam_Postpone(message: RMCMessage): typeof Methods.AutoMatchmakeWithParam_Postpone.Request | typeof Methods.AutoMatchmakeWithParam_Postpone.Response { if (message.type === RMCMessage.REQUEST) { return Methods.AutoMatchmakeWithParam_Postpone.Request; @@ -141,11 +498,120 @@ export default class MatchmakeExtensionProtocol { } } - private static AutoMatchmakeWithSearchCriteria_Postpone(message: RMCMessage): typeof Methods.AutoMatchmakeWithSearchCriteria_Postpone.Request | typeof Methods.AutoMatchmakeWithSearchCriteria_Postpone.Response { + + private static FindMatchmakeSessionByGatheringIdDetail(message: RMCMessage): typeof Methods.FindMatchmakeSessionByGatheringIdDetail.Request | typeof Methods.FindMatchmakeSessionByGatheringIdDetail.Response { if (message.type === RMCMessage.REQUEST) { - return Methods.AutoMatchmakeWithSearchCriteria_Postpone.Request; + return Methods.FindMatchmakeSessionByGatheringIdDetail.Request; } else { - return Methods.AutoMatchmakeWithSearchCriteria_Postpone.Response; + return Methods.FindMatchmakeSessionByGatheringIdDetail.Response; + } + } + + + private static BrowseMatchmakeSessionNoHolder(message: RMCMessage): typeof Methods.BrowseMatchmakeSessionNoHolder.Request | typeof Methods.BrowseMatchmakeSessionNoHolder.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.BrowseMatchmakeSessionNoHolder.Request; + } else { + return Methods.BrowseMatchmakeSessionNoHolder.Response; + } + } + + + private static BrowseMatchmakeSessionWithHostUrlsNoHolder(message: RMCMessage): typeof Methods.BrowseMatchmakeSessionWithHostUrlsNoHolder.Request | typeof Methods.BrowseMatchmakeSessionWithHostUrlsNoHolder.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.BrowseMatchmakeSessionWithHostUrlsNoHolder.Request; + } else { + return Methods.BrowseMatchmakeSessionWithHostUrlsNoHolder.Response; + } + } + + + private static UpdateMatchmakeSessionPart(message: RMCMessage): typeof Methods.UpdateMatchmakeSessionPart.Request | typeof Methods.UpdateMatchmakeSessionPart.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UpdateMatchmakeSessionPart.Request; + } else { + return Methods.UpdateMatchmakeSessionPart.Response; + } + } + + + private static RequestMatchmaking(message: RMCMessage): typeof Methods.RequestMatchmaking.Request | typeof Methods.RequestMatchmaking.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.RequestMatchmaking.Request; + } else { + return Methods.RequestMatchmaking.Response; + } + } + + + private static WithdrawMatchmaking(message: RMCMessage): typeof Methods.WithdrawMatchmaking.Request | typeof Methods.WithdrawMatchmaking.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.WithdrawMatchmaking.Request; + } else { + return Methods.WithdrawMatchmaking.Response; + } + } + + + private static WithdrawMatchmakingAll(message: RMCMessage): typeof Methods.WithdrawMatchmakingAll.Request | typeof Methods.WithdrawMatchmakingAll.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.WithdrawMatchmakingAll.Request; + } else { + return Methods.WithdrawMatchmakingAll.Response; + } + } + + + private static FindMatchmakeSessionByGatheringId(message: RMCMessage): typeof Methods.FindMatchmakeSessionByGatheringId.Request | typeof Methods.FindMatchmakeSessionByGatheringId.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindMatchmakeSessionByGatheringId.Request; + } else { + return Methods.FindMatchmakeSessionByGatheringId.Response; + } + } + + + private static FindMatchmakeSessionBySingleGatheringId(message: RMCMessage): typeof Methods.FindMatchmakeSessionBySingleGatheringId.Request | typeof Methods.FindMatchmakeSessionBySingleGatheringId.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindMatchmakeSessionBySingleGatheringId.Request; + } else { + return Methods.FindMatchmakeSessionBySingleGatheringId.Response; + } + } + + + private static FindMatchmakeSessionByOwner(message: RMCMessage): typeof Methods.FindMatchmakeSessionByOwner.Request | typeof Methods.FindMatchmakeSessionByOwner.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindMatchmakeSessionByOwner.Request; + } else { + return Methods.FindMatchmakeSessionByOwner.Response; + } + } + + + private static FindMatchmakeSessionByParticipant(message: RMCMessage): typeof Methods.FindMatchmakeSessionByParticipant.Request | typeof Methods.FindMatchmakeSessionByParticipant.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.FindMatchmakeSessionByParticipant.Request; + } else { + return Methods.FindMatchmakeSessionByParticipant.Response; + } + } + + + private static BrowseMatchmakeSessionNoHolderNoResultRange(message: RMCMessage): typeof Methods.BrowseMatchmakeSessionNoHolderNoResultRange.Request | typeof Methods.BrowseMatchmakeSessionNoHolderNoResultRange.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.BrowseMatchmakeSessionNoHolderNoResultRange.Request; + } else { + return Methods.BrowseMatchmakeSessionNoHolderNoResultRange.Response; + } + } + + + private static BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange(message: RMCMessage): typeof Methods.BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange.Request | typeof Methods.BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange.Request; + } else { + return Methods.BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange.Response; } } } diff --git a/src/nex/protocols/matchmake-extension/methods/add-to-black-list.ts b/src/nex/protocols/matchmake-extension/methods/add-to-black-list.ts new file mode 100644 index 0000000..5978a8b --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/add-to-black-list.ts @@ -0,0 +1,35 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'AddToBlackList'; + + private lstPrincipalId = new List(new PID()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstPrincipalId.extractFrom(stream); + } + + public toJSON(): any { + return { + lstPrincipalId: this.lstPrincipalId + }; + } +} + +// * No response data +export class Response { + public static Name = 'AddToBlackList'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/auto-matchmake-postpone.ts b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-postpone.ts new file mode 100644 index 0000000..0f916a8 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-postpone.ts @@ -0,0 +1,45 @@ +import NEXByteStream from '@/nex/byte-stream'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import RVString from '@/nex/types/string'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'AutoMatchmake_Postpone'; + + private anyGathering = new AnyDataHolder(); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.anyGathering.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): any { + return { + anyGathering: this.anyGathering, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'AutoMatchmake_Postpone'; + + private joinedGathering = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.joinedGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + joinedGathering: this.joinedGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-gathering-id-postpone.ts b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-gathering-id-postpone.ts new file mode 100644 index 0000000..5a8d3c2 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-gathering-id-postpone.ts @@ -0,0 +1,50 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt32 from '@/nex/types/uint32'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import RVString from '@/nex/types/string'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'AutoMatchmakeWithGatheringId_Postpone'; + + private lstGid = new List(new UInt32()); + private anyGathering = new AnyDataHolder(); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGid.extractFrom(stream); + this.anyGathering.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGid: this.lstGid, + anyGathering: this.anyGathering, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'AutoMatchmakeWithGatheringId_Postpone'; + + private joinedGathering = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.joinedGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + joinedGathering: this.joinedGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone.ts b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone.ts index db3535a..c66cb16 100644 --- a/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone.ts +++ b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone.ts @@ -2,7 +2,8 @@ import NEXByteStream from '@/nex/byte-stream'; import AutoMatchmakeParam from '@/nex/protocols/match-making/types/auto-matchmake-param'; import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; import type RMCMessage from '@/nex/rmc-message'; -import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/auto-matchmake-with-param-postpone'; + +// TODO - Add strict types for toJSON methods export class Request { public static Name = 'AutoMatchmakeWithParam_Postpone'; @@ -15,7 +16,7 @@ export class Request { this.autoMatchmakeParam.extractFrom(stream); } - public toJSON(): RMCs.Request { + public toJSON(): any { return { autoMatchmakeParam: this.autoMatchmakeParam }; @@ -33,7 +34,7 @@ export class Response { this.joinedMatchmakeSession.extractFrom(stream); } - public toJSON(): RMCs.Response { + public toJSON(): any { return { joinedMatchmakeSession: this.joinedMatchmakeSession }; diff --git a/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-search-criteria-postpone.ts b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-search-criteria-postpone.ts index 9002a80..de1b34b 100644 --- a/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-search-criteria-postpone.ts +++ b/src/nex/protocols/matchmake-extension/methods/auto-matchmake-with-search-criteria-postpone.ts @@ -1,31 +1,32 @@ import NEXByteStream from '@/nex/byte-stream'; -import type RMCMessage from '@/nex/rmc-message'; -import AnyDataHolder from '@/nex/types/any-data-holder'; import List from '@/nex/types/list'; import MatchmakeSessionSearchCriteria from '@/nex/protocols/match-making/types/matchmake-session-search-criteria'; +import AnyDataHolder from '@/nex/types/any-data-holder'; import RVString from '@/nex/types/string'; -import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/auto-matchmake-with-search-criteria-postpone'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods export class Request { public static Name = 'AutoMatchmakeWithSearchCriteria_Postpone'; - private criteria = new List(new MatchmakeSessionSearchCriteria()); - private gathering = new AnyDataHolder(); - private message = new RVString(); + private lstSearchCriteria = new List(new MatchmakeSessionSearchCriteria()); + private anyGathering = new AnyDataHolder(); + private strMessage = new RVString(); constructor(message: RMCMessage) { const stream = new NEXByteStream(message.parametersData!, message.connection.title); - this.criteria.extractFrom(stream); - this.gathering.extractFrom(stream); - this.message.extractFrom(stream); + this.lstSearchCriteria.extractFrom(stream); + this.anyGathering.extractFrom(stream); + this.strMessage.extractFrom(stream); } - public toJSON(): RMCs.Request { + public toJSON(): any { return { - criteria: this.criteria, - gathering: this.gathering, - message: this.message, + lstSearchCriteria: this.lstSearchCriteria, + anyGathering: this.anyGathering, + strMessage: this.strMessage }; } } @@ -33,17 +34,17 @@ export class Request { export class Response { public static Name = 'AutoMatchmakeWithSearchCriteria_Postpone'; - private joinedMatchmakeSession = new AnyDataHolder(); + private joinedGathering = new AnyDataHolder(); constructor(message: RMCMessage) { const stream = new NEXByteStream(message.parametersData!, message.connection.title); - this.joinedMatchmakeSession.extractFrom(stream); + this.joinedGathering.extractFrom(stream); } - public toJSON(): RMCs.Response { + public toJSON(): any { return { - joinedMatchmakeSession: this.joinedMatchmakeSession + joinedGathering: this.joinedGathering }; } -} +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-no-holder-no-result-range.ts b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-no-holder-no-result-range.ts new file mode 100644 index 0000000..5330ef5 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-no-holder-no-result-range.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeSessionSearchCriteria from '@/nex/protocols/match-making/types/matchmake-session-search-criteria'; +import List from '@/nex/types/list'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'BrowseMatchmakeSessionNoHolderNoResultRange'; + + private searchCriteria = new MatchmakeSessionSearchCriteria(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.searchCriteria.extractFrom(stream); + } + + public toJSON(): any { + return { + searchCriteria: this.searchCriteria + }; + } +} + +export class Response { + public static Name = 'BrowseMatchmakeSessionNoHolderNoResultRange'; + + private lstMatchmakeSession = new List(new MatchmakeSession()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstMatchmakeSession.extractFrom(stream); + } + + public toJSON(): any { + return { + lstMatchmakeSession: this.lstMatchmakeSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-no-holder.ts b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-no-holder.ts new file mode 100644 index 0000000..b482ecf --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-no-holder.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeSessionSearchCriteria from '@/nex/protocols/match-making/types/matchmake-session-search-criteria'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'BrowseMatchmakeSessionNoHolder'; + + private searchCriteria = new MatchmakeSessionSearchCriteria(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.searchCriteria.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + searchCriteria: this.searchCriteria, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'BrowseMatchmakeSessionNoHolder'; + + private lstMatchmakeSession = new List(new MatchmakeSession()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstMatchmakeSession.extractFrom(stream); + } + + public toJSON(): any { + return { + lstMatchmakeSession: this.lstMatchmakeSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls-no-holder-no-result-range.ts b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls-no-holder-no-result-range.ts new file mode 100644 index 0000000..dc5022f --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls-no-holder-no-result-range.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeSessionSearchCriteria from '@/nex/protocols/match-making/types/matchmake-session-search-criteria'; +import List from '@/nex/types/list'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import GatheringURLs from '@/nex/protocols/match-making/types/gathering-urls'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange'; + + private searchCriteria = new MatchmakeSessionSearchCriteria(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.searchCriteria.extractFrom(stream); + } + + public toJSON(): any { + return { + searchCriteria: this.searchCriteria + }; + } +} + +export class Response { + public static Name = 'BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange'; + + private lstMatchmakeSession = new List(new MatchmakeSession()); + private lstGatheringUrls = new List(new GatheringURLs()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstMatchmakeSession.extractFrom(stream); + this.lstGatheringUrls.extractFrom(stream); + } + + public toJSON(): any { + return { + lstMatchmakeSession: this.lstMatchmakeSession, + lstGatheringUrls: this.lstGatheringUrls + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls-no-holder.ts b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls-no-holder.ts new file mode 100644 index 0000000..952f4a9 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls-no-holder.ts @@ -0,0 +1,51 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeSessionSearchCriteria from '@/nex/protocols/match-making/types/matchmake-session-search-criteria'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import GatheringURLs from '@/nex/protocols/match-making/types/gathering-urls'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'BrowseMatchmakeSessionWithHostUrlsNoHolder'; + + private searchCriteria = new MatchmakeSessionSearchCriteria(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.searchCriteria.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + searchCriteria: this.searchCriteria, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'BrowseMatchmakeSessionWithHostUrlsNoHolder'; + + private lstMatchmakeSession = new List(new MatchmakeSession()); + private lstGatheringUrls = new List(new GatheringURLs()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstMatchmakeSession.extractFrom(stream); + this.lstGatheringUrls.extractFrom(stream); + } + + public toJSON(): any { + return { + lstMatchmakeSession: this.lstMatchmakeSession, + lstGatheringUrls: this.lstGatheringUrls + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls.ts b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls.ts new file mode 100644 index 0000000..23a24d3 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls.ts @@ -0,0 +1,51 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeSessionSearchCriteria from '@/nex/protocols/match-making/types/matchmake-session-search-criteria'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import GatheringURLs from '@/nex/protocols/match-making/types/gathering-urls'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'BrowseMatchmakeSessionWithHostUrls'; + + private searchCriteria = new MatchmakeSessionSearchCriteria(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.searchCriteria.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + searchCriteria: this.searchCriteria, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'BrowseMatchmakeSessionWithHostUrls'; + + private lstGathering = new List(new AnyDataHolder()); + private lstGatheringUrls = new List(new GatheringURLs()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGathering.extractFrom(stream); + this.lstGatheringUrls.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGathering: this.lstGathering, + lstGatheringUrls: this.lstGatheringUrls + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session.ts b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session.ts new file mode 100644 index 0000000..aa43816 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/browse-matchmake-session.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeSessionSearchCriteria from '@/nex/protocols/match-making/types/matchmake-session-search-criteria'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'BrowseMatchmakeSession'; + + private searchCriteria = new MatchmakeSessionSearchCriteria(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.searchCriteria.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + searchCriteria: this.searchCriteria, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'BrowseMatchmakeSession'; + + private lstGathering = new List(new AnyDataHolder()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGathering: this.lstGathering + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/clear-matchmake-session-system-password.ts b/src/nex/protocols/matchmake-extension/methods/clear-matchmake-session-system-password.ts new file mode 100644 index 0000000..0c6393c --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/clear-matchmake-session-system-password.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'ClearMatchmakeSessionSystemPassword'; + + private gid = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid + }; + } +} + +// * No response data +export class Response { + public static Name = 'ClearMatchmakeSessionSystemPassword'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/clear-my-black-list.ts b/src/nex/protocols/matchmake-extension/methods/clear-my-black-list.ts new file mode 100644 index 0000000..ab39c50 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/clear-my-black-list.ts @@ -0,0 +1,23 @@ +// TODO - Add strict types for toJSON methods + +// * No request data +export class Request { + public static Name = 'ClearMyBlackList'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} + +// * No response data +export class Response { + public static Name = 'ClearMyBlackList'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/close-participation.ts b/src/nex/protocols/matchmake-extension/methods/close-participation.ts index 5c28589..dc1d60b 100644 --- a/src/nex/protocols/matchmake-extension/methods/close-participation.ts +++ b/src/nex/protocols/matchmake-extension/methods/close-participation.ts @@ -1,7 +1,8 @@ import NEXByteStream from '@/nex/byte-stream'; import UInt32 from '@/nex/types/uint32'; import type RMCMessage from '@/nex/rmc-message'; -import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/close-participation'; + +// TODO - Add strict types for toJSON methods export class Request { public static Name = 'CloseParticipation'; @@ -14,7 +15,7 @@ export class Request { this.gid.extractFrom(stream); } - public toJSON(): RMCs.Request { + public toJSON(): any { return { gid: this.gid }; @@ -27,7 +28,7 @@ export class Response { constructor() {} - public toJSON(): RMCs.Response { + public toJSON(): any { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/create-community.ts b/src/nex/protocols/matchmake-extension/methods/create-community.ts new file mode 100644 index 0000000..3afde72 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/create-community.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import PersistentGathering from '@/nex/protocols/match-making/types/persistent-gathering'; +import RVString from '@/nex/types/string'; +import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'CreateCommunity'; + + private community = new PersistentGathering(); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.community.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): any { + return { + community: this.community, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'CreateCommunity'; + + private gid = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/create-matchmake-session-with-param.ts b/src/nex/protocols/matchmake-extension/methods/create-matchmake-session-with-param.ts new file mode 100644 index 0000000..c85901b --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/create-matchmake-session-with-param.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import CreateMatchmakeSessionParam from '@/nex/protocols/match-making/types/create-matchmake-session-param'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'CreateMatchmakeSessionWithParam'; + + private createMatchmakeSessionParam = new CreateMatchmakeSessionParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.createMatchmakeSessionParam.extractFrom(stream); + } + + public toJSON(): any { + return { + createMatchmakeSessionParam: this.createMatchmakeSessionParam + }; + } +} + +export class Response { + public static Name = 'CreateMatchmakeSessionWithParam'; + + private joinedMatchmakeSession = new MatchmakeSession(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.joinedMatchmakeSession.extractFrom(stream); + } + + public toJSON(): any { + return { + joinedMatchmakeSession: this.joinedMatchmakeSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/create-matchmake-session.ts b/src/nex/protocols/matchmake-extension/methods/create-matchmake-session.ts new file mode 100644 index 0000000..d361b55 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/create-matchmake-session.ts @@ -0,0 +1,73 @@ +import semver from 'compare-versions'; +import NEXByteStream from '@/nex/byte-stream'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import RVString from '@/nex/types/string'; +import UInt16 from '@/nex/types/uint16'; +import UInt32 from '@/nex/types/uint32'; +import RVBuffer from '@/nex/types/buffer'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'CreateMatchmakeSession'; + + private anyGathering = new AnyDataHolder(); + private strMessage = new RVString(); + private participationCount: UInt16; + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.anyGathering.extractFrom(stream); + this.strMessage.extractFrom(stream); + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.4.0')) { + this.participationCount = new UInt16(); + this.participationCount.extractFrom(stream); + } + } + + public toJSON(): any { + const json: Record = { + anyGathering: this.anyGathering, + strMessage: this.strMessage + }; + + if (this.participationCount !== undefined) { + json.participationCount = this.participationCount; + } + + return json; + } +} + +export class Response { + public static Name = 'CreateMatchmakeSession'; + + private gid = new UInt32(); + private sessionKey: RVBuffer; + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.0.0')) { + this.sessionKey = new RVBuffer(); + this.sessionKey.extractFrom(stream); + } + } + + public toJSON(): any { + const json: Record = { + gid: this.gid + }; + + if (this.sessionKey !== undefined) { + json.sessionKey = this.sessionKey; + } + + return json; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/debug-notify-event.ts b/src/nex/protocols/matchmake-extension/methods/debug-notify-event.ts new file mode 100644 index 0000000..a46a549 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/debug-notify-event.ts @@ -0,0 +1,52 @@ +import NEXByteStream from '@/nex/byte-stream'; +import PID from '@/nex/types/pid'; +import UInt32 from '@/nex/types/uint32'; +import UInt64 from '@/nex/types/uint64'; +import RVString from '@/nex/types/string'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'DebugNotifyEvent'; + + private pid = new PID(); + private mainType = new UInt32(); + private subType = new UInt32(); + private param1 = new UInt64(); + private param2 = new UInt64(); + private stringParam = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pid.extractFrom(stream); + this.mainType.extractFrom(stream); + this.subType.extractFrom(stream); + this.param1.extractFrom(stream); + this.param2.extractFrom(stream); + this.stringParam.extractFrom(stream); + } + + public toJSON(): any { + return { + pid: this.pid, + mainType: this.mainType, + subType: this.subType, + param1: this.param1, + param2: this.param2, + stringParam: this.stringParam + }; + } +} + +// * No response data +export class Response { + public static Name = 'DebugNotifyEvent'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/find-community-by-gathering-id.ts b/src/nex/protocols/matchmake-extension/methods/find-community-by-gathering-id.ts new file mode 100644 index 0000000..388e90b --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/find-community-by-gathering-id.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt32 from '@/nex/types/uint32'; +import PersistentGathering from '@/nex/protocols/match-making/types/persistent-gathering'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindCommunityByGatheringId'; + + private lstGid = new List(new UInt32()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGid.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGid: this.lstGid + }; + } +} + +export class Response { + public static Name = 'FindCommunityByGatheringId'; + + private lstCommunity = new List(new PersistentGathering()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstCommunity.extractFrom(stream); + } + + public toJSON(): any { + return { + lstCommunity: this.lstCommunity + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/find-community-by-participant.ts b/src/nex/protocols/matchmake-extension/methods/find-community-by-participant.ts new file mode 100644 index 0000000..ec890a4 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/find-community-by-participant.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import PID from '@/nex/types/pid'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import PersistentGathering from '@/nex/protocols/match-making/types/persistent-gathering'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindCommunityByParticipant'; + + private pid = new PID(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pid.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + pid: this.pid, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'FindCommunityByParticipant'; + + private lstCommunity = new List(new PersistentGathering()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstCommunity.extractFrom(stream); + } + + public toJSON(): any { + return { + lstCommunity: this.lstCommunity + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-gathering-id-detail.ts b/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-gathering-id-detail.ts new file mode 100644 index 0000000..60a6f38 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-gathering-id-detail.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindMatchmakeSessionByGatheringIdDetail'; + + private gid = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid + }; + } +} + +export class Response { + public static Name = 'FindMatchmakeSessionByGatheringIdDetail'; + + private matchmakeSession = new MatchmakeSession(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.matchmakeSession.extractFrom(stream); + } + + public toJSON(): any { + return { + matchmakeSession: this.matchmakeSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-gathering-id.ts b/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-gathering-id.ts new file mode 100644 index 0000000..d3b1c00 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-gathering-id.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt32 from '@/nex/types/uint32'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindMatchmakeSessionByGatheringId'; + + private lstGid = new List(new UInt32()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstGid.extractFrom(stream); + } + + public toJSON(): any { + return { + lstGid: this.lstGid + }; + } +} + +export class Response { + public static Name = 'FindMatchmakeSessionByGatheringId'; + + private lstMatchmakeSession = new List(new MatchmakeSession()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstMatchmakeSession.extractFrom(stream); + } + + public toJSON(): any { + return { + lstMatchmakeSession: this.lstMatchmakeSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-owner.ts b/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-owner.ts new file mode 100644 index 0000000..4541097 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-owner.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import PID from '@/nex/types/pid'; +import ResultRange from '@/nex/types/result-range'; +import List from '@/nex/types/list'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindMatchmakeSessionByOwner'; + + private id = new PID(); + private resultRange = new ResultRange(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.id.extractFrom(stream); + this.resultRange.extractFrom(stream); + } + + public toJSON(): any { + return { + id: this.id, + resultRange: this.resultRange + }; + } +} + +export class Response { + public static Name = 'FindMatchmakeSessionByOwner'; + + private lstMatchmakeSession = new List(new MatchmakeSession()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstMatchmakeSession.extractFrom(stream); + } + + public toJSON(): any { + return { + lstMatchmakeSession: this.lstMatchmakeSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-participant.ts b/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-participant.ts new file mode 100644 index 0000000..886978e --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-participant.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import FindMatchmakeSessionByParticipantParam from '@/nex/protocols/match-making/types/find-matchmake-session-by-participant-param'; +import List from '@/nex/types/list'; +import FindMatchmakeSessionByParticipantResult from '@/nex/protocols/match-making/types/find-matchmake-session-by-participant-result'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindMatchmakeSessionByParticipant'; + + private param = new FindMatchmakeSessionByParticipantParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.param.extractFrom(stream); + } + + public toJSON(): any { + return { + param: this.param + }; + } +} + +export class Response { + public static Name = 'FindMatchmakeSessionByParticipant'; + + private lstSession = new List(new FindMatchmakeSessionByParticipantResult()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstSession.extractFrom(stream); + } + + public toJSON(): any { + return { + lstSession: this.lstSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-single-gathering-id.ts b/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-single-gathering-id.ts new file mode 100644 index 0000000..334526f --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-single-gathering-id.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'FindMatchmakeSessionBySingleGatheringId'; + + private gid = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid + }; + } +} + +export class Response { + public static Name = 'FindMatchmakeSessionBySingleGatheringId'; + + private matchmakeSession = new MatchmakeSession(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.matchmakeSession.extractFrom(stream); + } + + public toJSON(): any { + return { + matchmakeSession: this.matchmakeSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/find-official-community.ts b/src/nex/protocols/matchmake-extension/methods/find-official-community.ts index d2197e1..3a42d93 100644 --- a/src/nex/protocols/matchmake-extension/methods/find-official-community.ts +++ b/src/nex/protocols/matchmake-extension/methods/find-official-community.ts @@ -4,7 +4,8 @@ import ResultRange from '@/nex/types/result-range'; import List from '@/nex/types/list'; import PersistentGathering from '@/nex/protocols/match-making/types/persistent-gathering'; import type RMCMessage from '@/nex/rmc-message'; -import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/find-official-community'; + +// TODO - Add strict types for toJSON methods export class Request { public static Name = 'FindOfficialCommunity'; @@ -19,7 +20,7 @@ export class Request { this.resultRange.extractFrom(stream); } - public toJSON(): RMCs.Request { + public toJSON(): any { return { isAvailableOnly: this.isAvailableOnly, resultRange: this.resultRange @@ -38,7 +39,7 @@ export class Response { this.lstCommunity.extractFrom(stream); } - public toJSON(): RMCs.Response { + public toJSON(): any { return { lstCommunity: this.lstCommunity }; diff --git a/src/nex/protocols/matchmake-extension/methods/generate-matchmake-session-system-password.ts b/src/nex/protocols/matchmake-extension/methods/generate-matchmake-session-system-password.ts new file mode 100644 index 0000000..8f2fb33 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/generate-matchmake-session-system-password.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GenerateMatchmakeSessionSystemPassword'; + + private gid = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid + }; + } +} + +export class Response { + public static Name = 'GenerateMatchmakeSessionSystemPassword'; + + private password = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.password.extractFrom(stream); + } + + public toJSON(): any { + return { + password: this.password + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/get-friend-notification-data.ts b/src/nex/protocols/matchmake-extension/methods/get-friend-notification-data.ts new file mode 100644 index 0000000..fe7f2ab --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/get-friend-notification-data.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import Int32 from '@/nex/types/int32'; +import List from '@/nex/types/list'; +import NotificationEvent from '@/nex/protocols/notification-events/types/notification-event'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetFriendNotificationData'; + + private uiType = new Int32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.uiType.extractFrom(stream); + } + + public toJSON(): any { + return { + uiType: this.uiType + }; + } +} + +export class Response { + public static Name = 'GetFriendNotificationData'; + + private dataList = new List(new NotificationEvent()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.dataList.extractFrom(stream); + } + + public toJSON(): any { + return { + dataList: this.dataList + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/get-lst-friend-notification-data.ts b/src/nex/protocols/matchmake-extension/methods/get-lst-friend-notification-data.ts new file mode 100644 index 0000000..c33e113 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/get-lst-friend-notification-data.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt32 from '@/nex/types/uint32'; +import NotificationEvent from '@/nex/protocols/notification-events/types/notification-event'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetlstFriendNotificationData'; + + private lstTypes = new List(new UInt32()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstTypes.extractFrom(stream); + } + + public toJSON(): any { + return { + lstTypes: this.lstTypes + }; + } +} + +export class Response { + public static Name = 'GetlstFriendNotificationData'; + + private dataList = new List(new NotificationEvent()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.dataList.extractFrom(stream); + } + + public toJSON(): any { + return { + dataList: this.dataList + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/get-my-black-list.ts b/src/nex/protocols/matchmake-extension/methods/get-my-black-list.ts new file mode 100644 index 0000000..af33db5 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/get-my-black-list.ts @@ -0,0 +1,35 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +// * No request data +export class Request { + public static Name = 'GetMyBlackList'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} + +export class Response { + public static Name = 'GetMyBlackList'; + + private lstPrincipalId = new List(new PID()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstPrincipalId.extractFrom(stream); + } + + public toJSON(): any { + return { + lstPrincipalId: this.lstPrincipalId + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/get-playing-session.ts b/src/nex/protocols/matchmake-extension/methods/get-playing-session.ts index bc519b3..cf3ecf6 100644 --- a/src/nex/protocols/matchmake-extension/methods/get-playing-session.ts +++ b/src/nex/protocols/matchmake-extension/methods/get-playing-session.ts @@ -3,7 +3,8 @@ import List from '@/nex/types/list'; import PID from '@/nex/types/pid'; import PlayingSession from '@/nex/protocols/match-making/types/playing-session'; import type RMCMessage from '@/nex/rmc-message'; -import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/get-playing-session'; + +// TODO - Add strict types for toJSON methods export class Request { public static Name = 'GetPlayingSession'; @@ -16,7 +17,7 @@ export class Request { this.lstPid.extractFrom(stream); } - public toJSON(): RMCs.Request { + public toJSON(): any { return { lstPid: this.lstPid }; @@ -34,7 +35,7 @@ export class Response { this.lstPlayingSession.extractFrom(stream); } - public toJSON(): RMCs.Response { + public toJSON(): any { return { lstPlayingSession: this.lstPlayingSession }; diff --git a/src/nex/protocols/matchmake-extension/methods/get-simple-community.ts b/src/nex/protocols/matchmake-extension/methods/get-simple-community.ts new file mode 100644 index 0000000..c4e5702 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/get-simple-community.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt32 from '@/nex/types/uint32'; +import SimpleCommunity from '@/nex/protocols/match-making/types/simple-community'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetSimpleCommunity'; + + private gatheringIdList = new List(new UInt32()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gatheringIdList.extractFrom(stream); + } + + public toJSON(): any { + return { + gatheringIdList: this.gatheringIdList + }; + } +} + +export class Response { + public static Name = 'GetSimpleCommunity'; + + private lstSimpleCommunityList = new List(new SimpleCommunity()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstSimpleCommunityList.extractFrom(stream); + } + + public toJSON(): any { + return { + lstSimpleCommunityList: this.lstSimpleCommunityList + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/get-simple-playing-session.ts b/src/nex/protocols/matchmake-extension/methods/get-simple-playing-session.ts index 8e482e1..0b0033b 100644 --- a/src/nex/protocols/matchmake-extension/methods/get-simple-playing-session.ts +++ b/src/nex/protocols/matchmake-extension/methods/get-simple-playing-session.ts @@ -4,7 +4,8 @@ import PID from '@/nex/types/pid'; import Bool from '@/nex/types/bool'; import SimplePlayingSession from '@/nex/protocols/match-making/types/simple-playing-session'; import type RMCMessage from '@/nex/rmc-message'; -import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/get-simple-playing-session'; + +// TODO - Add strict types for toJSON methods export class Request { public static Name = 'GetSimplePlayingSession'; @@ -19,7 +20,7 @@ export class Request { this.includeLoginUser.extractFrom(stream); } - public toJSON(): RMCs.Request { + public toJSON(): any { return { lstPrincipalId: this.lstPrincipalId, includeLoginUser: this.includeLoginUser @@ -38,7 +39,7 @@ export class Response { this.lstSimplePlayingSession.extractFrom(stream); } - public toJSON(): RMCs.Response { + public toJSON(): any { return { lstSimplePlayingSession: this.lstSimplePlayingSession }; diff --git a/src/nex/protocols/matchmake-extension/methods/index.ts b/src/nex/protocols/matchmake-extension/methods/index.ts index 7ae2733..e74de6c 100644 --- a/src/nex/protocols/matchmake-extension/methods/index.ts +++ b/src/nex/protocols/matchmake-extension/methods/index.ts @@ -1,7 +1,53 @@ export * as CloseParticipation from '@/nex/protocols/matchmake-extension/methods/close-participation'; +export * as OpenParticipation from '@/nex/protocols/matchmake-extension/methods/open-participation'; +export * as AutoMatchmake_Postpone from '@/nex/protocols/matchmake-extension/methods/auto-matchmake-postpone'; +export * as BrowseMatchmakeSession from '@/nex/protocols/matchmake-extension/methods/browse-matchmake-session'; +export * as BrowseMatchmakeSessionWithHostUrls from '@/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls'; +export * as CreateMatchmakeSession from '@/nex/protocols/matchmake-extension/methods/create-matchmake-session'; +export * as JoinMatchmakeSession from '@/nex/protocols/matchmake-extension/methods/join-matchmake-session'; +export * as ModifyCurrentGameAttribute from '@/nex/protocols/matchmake-extension/methods/modify-current-game-attribute'; +export * as UpdateNotificationData from '@/nex/protocols/matchmake-extension/methods/update-notification-data'; +export * as GetFriendNotificationData from '@/nex/protocols/matchmake-extension/methods/get-friend-notification-data'; +export * as UpdateApplicationBuffer from '@/nex/protocols/matchmake-extension/methods/update-application-buffer'; +export * as UpdateMatchmakeSessionAttribute from '@/nex/protocols/matchmake-extension/methods/update-matchmake-session-attribute'; +export * as GetlstFriendNotificationData from '@/nex/protocols/matchmake-extension/methods/get-lst-friend-notification-data'; +export * as UpdateMatchmakeSession from '@/nex/protocols/matchmake-extension/methods/update-matchmake-session'; +export * as AutoMatchmakeWithSearchCriteria_Postpone from '@/nex/protocols/matchmake-extension/methods/auto-matchmake-with-search-criteria-postpone'; export * as GetPlayingSession from '@/nex/protocols/matchmake-extension/methods/get-playing-session'; +export * as CreateCommunity from '@/nex/protocols/matchmake-extension/methods/create-community'; +export * as UpdateCommunity from '@/nex/protocols/matchmake-extension/methods/update-community'; +export * as JoinCommunity from '@/nex/protocols/matchmake-extension/methods/join-community'; +export * as FindCommunityByGatheringId from '@/nex/protocols/matchmake-extension/methods/find-community-by-gathering-id'; export * as FindOfficialCommunity from '@/nex/protocols/matchmake-extension/methods/find-official-community'; +export * as FindCommunityByParticipant from '@/nex/protocols/matchmake-extension/methods/find-community-by-participant'; +export * as UpdatePrivacySetting from '@/nex/protocols/matchmake-extension/methods/update-privacy-setting'; +export * as GetMyBlackList from '@/nex/protocols/matchmake-extension/methods/get-my-black-list'; +export * as AddToBlackList from '@/nex/protocols/matchmake-extension/methods/add-to-black-list'; +export * as RemoveFromBlackList from '@/nex/protocols/matchmake-extension/methods/remove-from-black-list'; +export * as ClearMyBlackList from '@/nex/protocols/matchmake-extension/methods/clear-my-black-list'; +export * as ReportViolation from '@/nex/protocols/matchmake-extension/methods/report-violation'; +export * as IsViolationUser from '@/nex/protocols/matchmake-extension/methods/is-violation-user'; +export * as JoinMatchmakeSessionEx from '@/nex/protocols/matchmake-extension/methods/join-matchmake-session-ex'; export * as GetSimplePlayingSession from '@/nex/protocols/matchmake-extension/methods/get-simple-playing-session'; +export * as GetSimpleCommunity from '@/nex/protocols/matchmake-extension/methods/get-simple-community'; +export * as AutoMatchmakeWithGatheringId_Postpone from '@/nex/protocols/matchmake-extension/methods/auto-matchmake-with-gathering-id-postpone'; export * as UpdateProgressScore from '@/nex/protocols/matchmake-extension/methods/update-progress-score'; +export * as DebugNotifyEvent from '@/nex/protocols/matchmake-extension/methods/debug-notify-event'; +export * as GenerateMatchmakeSessionSystemPassword from '@/nex/protocols/matchmake-extension/methods/generate-matchmake-session-system-password'; +export * as ClearMatchmakeSessionSystemPassword from '@/nex/protocols/matchmake-extension/methods/clear-matchmake-session-system-password'; +export * as CreateMatchmakeSessionWithParam from '@/nex/protocols/matchmake-extension/methods/create-matchmake-session-with-param'; +export * as JoinMatchmakeSessionWithParam from '@/nex/protocols/matchmake-extension/methods/join-matchmake-session-with-param'; export * as AutoMatchmakeWithParam_Postpone from '@/nex/protocols/matchmake-extension/methods/auto-matchmake-with-param-postpone'; -export * as AutoMatchmakeWithSearchCriteria_Postpone from '@/nex/protocols/matchmake-extension/methods/auto-matchmake-with-search-criteria-postpone'; +export * as FindMatchmakeSessionByGatheringIdDetail from '@/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-gathering-id-detail'; +export * as BrowseMatchmakeSessionNoHolder from '@/nex/protocols/matchmake-extension/methods/browse-matchmake-session-no-holder'; +export * as BrowseMatchmakeSessionWithHostUrlsNoHolder from '@/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls-no-holder'; +export * as UpdateMatchmakeSessionPart from '@/nex/protocols/matchmake-extension/methods/update-matchmake-session-part'; +export * as RequestMatchmaking from '@/nex/protocols/matchmake-extension/methods/request-matchmaking'; +export * as WithdrawMatchmaking from '@/nex/protocols/matchmake-extension/methods/withdraw-matchmaking'; +export * as WithdrawMatchmakingAll from '@/nex/protocols/matchmake-extension/methods/withdraw-matchmaking-all'; +export * as FindMatchmakeSessionByGatheringId from '@/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-gathering-id'; +export * as FindMatchmakeSessionBySingleGatheringId from '@/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-single-gathering-id'; +export * as FindMatchmakeSessionByOwner from '@/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-owner'; +export * as FindMatchmakeSessionByParticipant from '@/nex/protocols/matchmake-extension/methods/find-matchmake-session-by-participant'; +export * as BrowseMatchmakeSessionNoHolderNoResultRange from '@/nex/protocols/matchmake-extension/methods/browse-matchmake-session-no-holder-no-result-range'; +export * as BrowseMatchmakeSessionWithHostUrlsNoHolderNoResultRange from '@/nex/protocols/matchmake-extension/methods/browse-matchmake-session-with-host-urls-no-holder-no-result-range'; \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/is-violation-user.ts b/src/nex/protocols/matchmake-extension/methods/is-violation-user.ts new file mode 100644 index 0000000..fd7d722 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/is-violation-user.ts @@ -0,0 +1,38 @@ +import NEXByteStream from '@/nex/byte-stream'; +import Bool from '@/nex/types/bool'; +import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +// * No request data +export class Request { + public static Name = 'IsViolationUser'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} + +export class Response { + public static Name = 'IsViolationUser'; + + private flag = new Bool(); + private score = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.flag.extractFrom(stream); + this.score.extractFrom(stream); + } + + public toJSON(): any { + return { + flag: this.flag, + score: this.score + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/join-community.ts b/src/nex/protocols/matchmake-extension/methods/join-community.ts new file mode 100644 index 0000000..3108666 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/join-community.ts @@ -0,0 +1,41 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'JoinCommunity'; + + private gid = new UInt32(); + private strMessage = new RVString(); + private strPassword = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.strMessage.extractFrom(stream); + this.strPassword.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid, + strMessage: this.strMessage, + strPassword: this.strPassword + }; + } +} + +// * No response data +export class Response { + public static Name = 'JoinCommunity'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/join-matchmake-session-ex.ts b/src/nex/protocols/matchmake-extension/methods/join-matchmake-session-ex.ts new file mode 100644 index 0000000..0aa334f --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/join-matchmake-session-ex.ts @@ -0,0 +1,64 @@ +import semver from 'compare-versions'; +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import Bool from '@/nex/types/bool'; +import UInt16 from '@/nex/types/uint16'; +import RVBuffer from '@/nex/types/buffer'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'JoinMatchmakeSessionEx'; + + private gid = new UInt32(); + private strMessage = new RVString(); + private dontCareMyBlackList = new Bool(); + private participationCount: UInt16; + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.strMessage.extractFrom(stream); + this.dontCareMyBlackList.extractFrom(stream); + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.4.0')) { + this.participationCount = new UInt16(); + this.participationCount.extractFrom(stream); + } + } + + public toJSON(): any { + const json: Record = { + gid: this.gid, + strMessage: this.strMessage, + dontCareMyBlackList: this.dontCareMyBlackList + }; + + if (this.participationCount !== undefined) { + json.participationCount = this.participationCount; + } + + return json; + } +} + +export class Response { + public static Name = 'JoinMatchmakeSessionEx'; + + private sessionKey = new RVBuffer(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.sessionKey.extractFrom(stream); + } + + public toJSON(): any { + return { + sessionKey: this.sessionKey + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/join-matchmake-session-with-param.ts b/src/nex/protocols/matchmake-extension/methods/join-matchmake-session-with-param.ts new file mode 100644 index 0000000..69efbb7 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/join-matchmake-session-with-param.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import JoinMatchmakeSessionParam from '@/nex/protocols/match-making/types/join-matchmake-session-param'; +import MatchmakeSession from '@/nex/protocols/match-making/types/matchmake-session'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'JoinMatchmakeSessionWithParam'; + + private joinMatchmakeSessionParam = new JoinMatchmakeSessionParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.joinMatchmakeSessionParam.extractFrom(stream); + } + + public toJSON(): any { + return { + joinMatchmakeSessionParam: this.joinMatchmakeSessionParam + }; + } +} + +export class Response { + public static Name = 'JoinMatchmakeSessionWithParam'; + + private joinedMatchmakeSession = new MatchmakeSession(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.joinedMatchmakeSession.extractFrom(stream); + } + + public toJSON(): any { + return { + joinedMatchmakeSession: this.joinedMatchmakeSession + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/join-matchmake-session.ts b/src/nex/protocols/matchmake-extension/methods/join-matchmake-session.ts new file mode 100644 index 0000000..35eaa09 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/join-matchmake-session.ts @@ -0,0 +1,56 @@ +import semver from 'compare-versions'; +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVString from '@/nex/types/string'; +import RVBuffer from '@/nex/types/buffer'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'JoinMatchmakeSession'; + + private gid = new UInt32(); + private strMessage = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.strMessage.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid, + strMessage: this.strMessage + }; + } +} + +export class Response { + public static Name = 'JoinMatchmakeSession'; + + private sessionKey: RVBuffer; + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + if (semver.satisfies(stream.title.library_versions.match_making, '>=3.0.0')) { + this.sessionKey = new RVBuffer(); + this.sessionKey.extractFrom(stream); + } + + this.sessionKey.extractFrom(stream); + } + + public toJSON(): any { + const json: Record = {}; + + if (this.sessionKey !== undefined) { + json.sessionKey = this.sessionKey; + } + + return json; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/modify-current-game-attribute.ts b/src/nex/protocols/matchmake-extension/methods/modify-current-game-attribute.ts new file mode 100644 index 0000000..e18cdc2 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/modify-current-game-attribute.ts @@ -0,0 +1,40 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'ModifyCurrentGameAttribute'; + + private gid = new UInt32(); + private attribIndex = new UInt32(); + private newValue = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.attribIndex.extractFrom(stream); + this.newValue.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid, + attribIndex: this.attribIndex, + newValue: this.newValue + }; + } +} + +// * No response data +export class Response { + public static Name = 'ModifyCurrentGameAttribute'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/open-participation.ts b/src/nex/protocols/matchmake-extension/methods/open-participation.ts new file mode 100644 index 0000000..d12876a --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/open-participation.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'OpenParticipation'; + + private gid = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid + }; + } +} + +// * No response data +export class Response { + public static Name = 'OpenParticipation'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/remove-from-black-list.ts b/src/nex/protocols/matchmake-extension/methods/remove-from-black-list.ts new file mode 100644 index 0000000..c7a60b4 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/remove-from-black-list.ts @@ -0,0 +1,35 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'RemoveFromBlackList'; + + private lstPrincipalId = new List(new PID()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.lstPrincipalId.extractFrom(stream); + } + + public toJSON(): any { + return { + lstPrincipalId: this.lstPrincipalId + }; + } +} + +// * No response data +export class Response { + public static Name = 'RemoveFromBlackList'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/report-violation.ts b/src/nex/protocols/matchmake-extension/methods/report-violation.ts new file mode 100644 index 0000000..c178e03 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/report-violation.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import PID from '@/nex/types/pid'; +import RVString from '@/nex/types/string'; +import UInt32 from '@/nex/types/uint32'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'ReportViolation'; + + private pid = new PID(); + private userName = new RVString(); + private violationCode = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pid.extractFrom(stream); + this.userName.extractFrom(stream); + this.violationCode.extractFrom(stream); + } + + public toJSON(): any { + return { + pid: this.pid, + userName: this.userName, + violationCode: this.violationCode + }; + } +} + +// * No response data +export class Response { + public static Name = 'ReportViolation'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/request-matchmaking.ts b/src/nex/protocols/matchmake-extension/methods/request-matchmaking.ts new file mode 100644 index 0000000..6507a7a --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/request-matchmaking.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import AutoMatchmakeParam from '@/nex/protocols/match-making/types/auto-matchmake-param'; +import UInt64 from '@/nex/types/uint64'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'RequestMatchmaking'; + + private autoMatchmakeParam = new AutoMatchmakeParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.autoMatchmakeParam.extractFrom(stream); + } + + public toJSON(): any { + return { + autoMatchmakeParam: this.autoMatchmakeParam + }; + } +} + +export class Response { + public static Name = 'RequestMatchmaking'; + + private requestId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.requestId.extractFrom(stream); + } + + public toJSON(): any { + return { + requestId: this.requestId + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/update-application-buffer.ts b/src/nex/protocols/matchmake-extension/methods/update-application-buffer.ts new file mode 100644 index 0000000..36adf65 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/update-application-buffer.ts @@ -0,0 +1,38 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RVBuffer from '@/nex/types/buffer'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UpdateApplicationBuffer'; + + private gid = new UInt32(); + private applicationBuffer = new RVBuffer(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.applicationBuffer.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid, + applicationBuffer: this.applicationBuffer + }; + } +} + +// * No response data +export class Response { + public static Name = 'UpdateApplicationBuffer'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/update-community.ts b/src/nex/protocols/matchmake-extension/methods/update-community.ts new file mode 100644 index 0000000..633d72a --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/update-community.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import PersistentGathering from '@/nex/protocols/match-making/types/persistent-gathering'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UpdateCommunity'; + + private community = new PersistentGathering(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.community.extractFrom(stream); + } + + public toJSON(): any { + return { + community: this.community + }; + } +} + +// * No response data +export class Response { + public static Name = 'UpdateCommunity'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/update-matchmake-session-attribute.ts b/src/nex/protocols/matchmake-extension/methods/update-matchmake-session-attribute.ts new file mode 100644 index 0000000..710a35f --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/update-matchmake-session-attribute.ts @@ -0,0 +1,38 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UpdateMatchmakeSessionAttribute'; + + private gid = new UInt32(); + private attribs = new List(new UInt32()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.gid.extractFrom(stream); + this.attribs.extractFrom(stream); + } + + public toJSON(): any { + return { + gid: this.gid, + attribs: this.attribs + }; + } +} + +// * No response data +export class Response { + public static Name = 'UpdateMatchmakeSessionAttribute'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/update-matchmake-session-part.ts b/src/nex/protocols/matchmake-extension/methods/update-matchmake-session-part.ts new file mode 100644 index 0000000..b8fa505 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/update-matchmake-session-part.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UpdateMatchmakeSessionParam from '@/nex/protocols/match-making/types/update-matchmake-session-param'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UpdateMatchmakeSessionPart'; + + private updateMatchmakeSessionParam = new UpdateMatchmakeSessionParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.updateMatchmakeSessionParam.extractFrom(stream); + } + + public toJSON(): any { + return { + updateMatchmakeSessionParam: this.updateMatchmakeSessionParam + }; + } +} + +// * No response data +export class Response { + public static Name = 'UpdateMatchmakeSessionPart'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/update-matchmake-session.ts b/src/nex/protocols/matchmake-extension/methods/update-matchmake-session.ts new file mode 100644 index 0000000..06de4f4 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/update-matchmake-session.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import AnyDataHolder from '@/nex/types/any-data-holder'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UpdateMatchmakeSession'; + + private anyGathering = new AnyDataHolder(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.anyGathering.extractFrom(stream); + } + + public toJSON(): any { + return { + anyGathering: this.anyGathering + }; + } +} + +// * No response data +export class Response { + public static Name = 'UpdateMatchmakeSession'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/update-notification-data.ts b/src/nex/protocols/matchmake-extension/methods/update-notification-data.ts new file mode 100644 index 0000000..1a8054f --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/update-notification-data.ts @@ -0,0 +1,55 @@ +import semver from 'compare-versions'; +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import UInt64 from '@/nex/types/uint64'; +import RVString from '@/nex/types/string'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +// * No request data +export class Request { + public static Name = 'UpdateNotificationData'; + + private uiType = new UInt32(); + private uiParam1: UInt32 | UInt64; + private uiParam2: UInt32 | UInt64; + private strParam = new RVString(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + if (semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) { + this.uiParam1 = new UInt64(); + this.uiParam2 = new UInt64(); + } else { + this.uiParam1 = new UInt32(); + this.uiParam2 = new UInt32(); + } + + this.uiType.extractFrom(stream); + this.uiParam1.extractFrom(stream); + this.uiParam2.extractFrom(stream); + this.strParam.extractFrom(stream); + } + + public toJSON(): any { + return { + uiType: this.uiType, + uiParam1: this.uiParam1, + uiParam2: this.uiParam2, + strParam: this.strParam + }; + } +} + +// * No response data +export class Response { + public static Name = 'UpdateNotificationData'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/update-privacy-setting.ts b/src/nex/protocols/matchmake-extension/methods/update-privacy-setting.ts new file mode 100644 index 0000000..44409df --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/update-privacy-setting.ts @@ -0,0 +1,37 @@ +import NEXByteStream from '@/nex/byte-stream'; +import Bool from '@/nex/types/bool'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UpdatePrivacySetting'; + + private onlineStatus = new Bool(); + private participationCommunity = new Bool(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.onlineStatus.extractFrom(stream); + this.participationCommunity.extractFrom(stream); + } + + public toJSON(): any { + return { + onlineStatus: this.onlineStatus, + participationCommunity: this.participationCommunity + }; + } +} + +// * No response data +export class Response { + public static Name = 'UpdatePrivacySetting'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/update-progress-score.ts b/src/nex/protocols/matchmake-extension/methods/update-progress-score.ts index 0614a38..bcaffaa 100644 --- a/src/nex/protocols/matchmake-extension/methods/update-progress-score.ts +++ b/src/nex/protocols/matchmake-extension/methods/update-progress-score.ts @@ -2,7 +2,8 @@ import NEXByteStream from '@/nex/byte-stream'; import UInt32 from '@/nex/types/uint32'; import UInt8 from '@/nex/types/uint8'; import type RMCMessage from '@/nex/rmc-message'; -import type * as RMCs from '@/types/nex/rmcs/matchmake-extension/update-progress-score'; + +// TODO - Add strict types for toJSON methods export class Request { public static Name = 'UpdateProgressScore'; @@ -17,7 +18,7 @@ export class Request { this.progressScore.extractFrom(stream); } - public toJSON(): RMCs.Request { + public toJSON(): any { return { gid: this.gid, progressScore: this.progressScore @@ -31,7 +32,7 @@ export class Response { constructor() {} - public toJSON(): RMCs.Response { + public toJSON(): any { return {}; } } \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/withdraw-matchmaking-all.ts b/src/nex/protocols/matchmake-extension/methods/withdraw-matchmaking-all.ts new file mode 100644 index 0000000..b5e15d3 --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/withdraw-matchmaking-all.ts @@ -0,0 +1,23 @@ +// TODO - Add strict types for toJSON methods + +// * No request data +export class Request { + public static Name = 'WithdrawMatchmakingAll'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} + +// * No response data +export class Response { + public static Name = 'WithdrawMatchmakingAll'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-extension/methods/withdraw-matchmaking.ts b/src/nex/protocols/matchmake-extension/methods/withdraw-matchmaking.ts new file mode 100644 index 0000000..ded445c --- /dev/null +++ b/src/nex/protocols/matchmake-extension/methods/withdraw-matchmaking.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt64 from '@/nex/types/uint64'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'WithdrawMatchmaking'; + + private requestId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.requestId.extractFrom(stream); + } + + public toJSON(): any { + return { + requestId: this.requestId + }; + } +} + +// * No response data +export class Response { + public static Name = 'WithdrawMatchmaking'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file From e55f767883fd8993912683ce775de16a90243231 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Wed, 8 Jan 2025 13:58:57 -0500 Subject: [PATCH 64/67] feat: complete MatchmakeReferee protocol --- src/nex/protocols/manager.ts | 3 + src/nex/protocols/matchmake-referee/index.ts | 176 ++++++++++++++++++ .../matchmake-referee/methods/create-stats.ts | 34 ++++ .../methods/end-round-without-report.ts | 34 ++++ .../matchmake-referee/methods/end-round.ts | 34 ++++ .../methods/get-not-summarized-round.ts | 35 ++++ .../methods/get-or-create-stats.ts | 42 +++++ .../methods/get-round-participants.ts | 42 +++++ .../matchmake-referee/methods/get-round.ts | 42 +++++ .../methods/get-start-round-param.ts | 42 +++++ .../methods/get-stats-all.ts | 43 +++++ .../methods/get-stats-primaries.ts | 47 +++++ .../methods/get-stats-primary.ts | 42 +++++ .../matchmake-referee/methods/index.ts | 13 ++ .../matchmake-referee/methods/reset-stats.ts | 23 +++ .../matchmake-referee/methods/start-round.ts | 42 +++++ .../matchmake-referee-end-round-param.ts | 35 ++++ ...matchmake-referee-personal-round-result.ts | 45 +++++ .../types/matchmake-referee-round.ts | 45 +++++ .../matchmake-referee-start-round-param.ts | 38 ++++ .../matchmake-referee-stats-init-param.ts | 33 ++++ .../types/matchmake-referee-stats-target.ts | 34 ++++ .../types/matchmake-referee-stats.ts | 77 ++++++++ 23 files changed, 1001 insertions(+) create mode 100644 src/nex/protocols/matchmake-referee/index.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/create-stats.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/end-round-without-report.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/end-round.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/get-not-summarized-round.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/get-or-create-stats.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/get-round-participants.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/get-round.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/get-start-round-param.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/get-stats-all.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/get-stats-primaries.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/get-stats-primary.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/index.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/reset-stats.ts create mode 100644 src/nex/protocols/matchmake-referee/methods/start-round.ts create mode 100644 src/nex/protocols/matchmake-referee/types/matchmake-referee-end-round-param.ts create mode 100644 src/nex/protocols/matchmake-referee/types/matchmake-referee-personal-round-result.ts create mode 100644 src/nex/protocols/matchmake-referee/types/matchmake-referee-round.ts create mode 100644 src/nex/protocols/matchmake-referee/types/matchmake-referee-start-round-param.ts create mode 100644 src/nex/protocols/matchmake-referee/types/matchmake-referee-stats-init-param.ts create mode 100644 src/nex/protocols/matchmake-referee/types/matchmake-referee-stats-target.ts create mode 100644 src/nex/protocols/matchmake-referee/types/matchmake-referee-stats.ts diff --git a/src/nex/protocols/manager.ts b/src/nex/protocols/manager.ts index f501cd2..ba51889 100644 --- a/src/nex/protocols/manager.ts +++ b/src/nex/protocols/manager.ts @@ -5,6 +5,7 @@ import NotificationEventsProtocol from '@/nex/protocols/notification-events'; import MatchMakingProtocol from '@/nex/protocols/match-making'; import MatchMakingExtProtocol from '@/nex/protocols/match-making-ext'; import MatchmakeExtensionProtocol from '@/nex/protocols/matchmake-extension'; +import MatchmakeRefereeProtocol from '@/nex/protocols/matchmake-referee'; import type RMCMessage from '@/nex/rmc-message'; import type ServiceProtocol from '@/types/nex/service-protocol'; @@ -26,6 +27,8 @@ export default function getProtocol(message: RMCMessage): ServiceProtocol | null return MatchMakingExtProtocol; case MatchmakeExtensionProtocol.ID: return MatchmakeExtensionProtocol; + case MatchmakeRefereeProtocol.ID: + return MatchmakeRefereeProtocol; } return null; diff --git a/src/nex/protocols/matchmake-referee/index.ts b/src/nex/protocols/matchmake-referee/index.ts new file mode 100644 index 0000000..25aa9e7 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/index.ts @@ -0,0 +1,176 @@ +import RMCMessage from '@/nex/rmc-message'; +import * as Methods from '@/nex/protocols/matchmake-referee/methods'; +import type Packet from '@/types/nex/packet'; + +export default class MatchmakeRefereeProtocol { + static ID = 0x78; + static Name = 'MatchmakeReferee'; + + static Methods = { + StartRound: 0x01, + GetStartRoundParam: 0x02, + EndRound: 0x03, + EndRoundWithoutReport: 0x04, + GetRoundParticipants: 0x05, + GetNotSummarizedRound: 0x06, + GetRound: 0x07, + GetStatsPrimary: 0x08, + GetStatsPrimaries: 0x09, + GetStatsAll: 0x0A, + CreateStats: 0x0B, + GetOrCreateStats: 0x0C, + ResetStats: 0x0D + }; + + private static handlers: Record any> = { + 0x01: MatchmakeRefereeProtocol.StartRound, + 0x02: MatchmakeRefereeProtocol.GetStartRoundParam, + 0x03: MatchmakeRefereeProtocol.EndRound, + 0x04: MatchmakeRefereeProtocol.EndRoundWithoutReport, + 0x05: MatchmakeRefereeProtocol.GetRoundParticipants, + 0x06: MatchmakeRefereeProtocol.GetNotSummarizedRound, + 0x07: MatchmakeRefereeProtocol.GetRound, + 0x08: MatchmakeRefereeProtocol.GetStatsPrimary, + 0x09: MatchmakeRefereeProtocol.GetStatsPrimaries, + 0x0A: MatchmakeRefereeProtocol.GetStatsAll, + 0x0B: MatchmakeRefereeProtocol.CreateStats, + 0x0C: MatchmakeRefereeProtocol.GetOrCreateStats, + 0x0D: MatchmakeRefereeProtocol.ResetStats + }; + + static handlePacket(packet: Packet): void { + if (!packet.message) { + // * This will never happen. Only checked to make TypeScript happy + return; + } + + const methodID = packet.message.methodID; + const handler = MatchmakeRefereeProtocol.handlers[methodID]; + + if (!handler) { + packet.message.methodName = `UnknownMethod_0x${methodID.toString(16).toUpperCase().padStart(2, '0')}`; + return; + } + + const messageDecoder = handler(packet.message); + + packet.message.parameters = new messageDecoder(packet.message); + packet.message.methodName = messageDecoder.Name; + } + + private static StartRound(message: RMCMessage): typeof Methods.StartRound.Request | typeof Methods.StartRound.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.StartRound.Request; + } else { + return Methods.StartRound.Response; + } + } + + + private static GetStartRoundParam(message: RMCMessage): typeof Methods.GetStartRoundParam.Request | typeof Methods.GetStartRoundParam.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetStartRoundParam.Request; + } else { + return Methods.GetStartRoundParam.Response; + } + } + + + private static EndRound(message: RMCMessage): typeof Methods.EndRound.Request | typeof Methods.EndRound.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.EndRound.Request; + } else { + return Methods.EndRound.Response; + } + } + + + private static EndRoundWithoutReport(message: RMCMessage): typeof Methods.EndRoundWithoutReport.Request | typeof Methods.EndRoundWithoutReport.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.EndRoundWithoutReport.Request; + } else { + return Methods.EndRoundWithoutReport.Response; + } + } + + + private static GetRoundParticipants(message: RMCMessage): typeof Methods.GetRoundParticipants.Request | typeof Methods.GetRoundParticipants.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetRoundParticipants.Request; + } else { + return Methods.GetRoundParticipants.Response; + } + } + + + private static GetNotSummarizedRound(message: RMCMessage): typeof Methods.GetNotSummarizedRound.Request | typeof Methods.GetNotSummarizedRound.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetNotSummarizedRound.Request; + } else { + return Methods.GetNotSummarizedRound.Response; + } + } + + + private static GetRound(message: RMCMessage): typeof Methods.GetRound.Request | typeof Methods.GetRound.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetRound.Request; + } else { + return Methods.GetRound.Response; + } + } + + + private static GetStatsPrimary(message: RMCMessage): typeof Methods.GetStatsPrimary.Request | typeof Methods.GetStatsPrimary.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetStatsPrimary.Request; + } else { + return Methods.GetStatsPrimary.Response; + } + } + + + private static GetStatsPrimaries(message: RMCMessage): typeof Methods.GetStatsPrimaries.Request | typeof Methods.GetStatsPrimaries.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetStatsPrimaries.Request; + } else { + return Methods.GetStatsPrimaries.Response; + } + } + + + private static GetStatsAll(message: RMCMessage): typeof Methods.GetStatsAll.Request | typeof Methods.GetStatsAll.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetStatsAll.Request; + } else { + return Methods.GetStatsAll.Response; + } + } + + + private static CreateStats(message: RMCMessage): typeof Methods.CreateStats.Request | typeof Methods.CreateStats.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.CreateStats.Request; + } else { + return Methods.CreateStats.Response; + } + } + + + private static GetOrCreateStats(message: RMCMessage): typeof Methods.GetOrCreateStats.Request | typeof Methods.GetOrCreateStats.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetOrCreateStats.Request; + } else { + return Methods.GetOrCreateStats.Response; + } + } + + + private static ResetStats(message: RMCMessage): typeof Methods.ResetStats.Request | typeof Methods.ResetStats.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ResetStats.Request; + } else { + return Methods.ResetStats.Response; + } + } +} diff --git a/src/nex/protocols/matchmake-referee/methods/create-stats.ts b/src/nex/protocols/matchmake-referee/methods/create-stats.ts new file mode 100644 index 0000000..b02d2f8 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/create-stats.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeRefereeStatsInitParam from '@/nex/protocols/matchmake-referee/types/matchmake-referee-stats-init-param'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'CreateStats'; + + private param = new MatchmakeRefereeStatsInitParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.param.extractFrom(stream); + } + + public toJSON(): any { + return { + param: this.param + }; + } +} + +// * No response data +export class Response { + public static Name = 'CreateStats'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/end-round-without-report.ts b/src/nex/protocols/matchmake-referee/methods/end-round-without-report.ts new file mode 100644 index 0000000..7a94d4b --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/end-round-without-report.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt64 from '@/nex/types/uint64'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'EndRoundWithoutReport'; + + private roundId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.roundId.extractFrom(stream); + } + + public toJSON(): any { + return { + roundId: this.roundId + }; + } +} + +// * No response data +export class Response { + public static Name = 'EndRoundWithoutReport'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/end-round.ts b/src/nex/protocols/matchmake-referee/methods/end-round.ts new file mode 100644 index 0000000..2a234d8 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/end-round.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeRefereeEndRoundParam from '@/nex/protocols/matchmake-referee/types/matchmake-referee-end-round-param'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'EndRound'; + + private endRoundParam = new MatchmakeRefereeEndRoundParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.endRoundParam.extractFrom(stream); + } + + public toJSON(): any { + return { + endRoundParam: this.endRoundParam + }; + } +} + +// * No response data +export class Response { + public static Name = 'EndRound'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/get-not-summarized-round.ts b/src/nex/protocols/matchmake-referee/methods/get-not-summarized-round.ts new file mode 100644 index 0000000..32f4cce --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/get-not-summarized-round.ts @@ -0,0 +1,35 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import MatchmakeRefereeRound from '@/nex/protocols/matchmake-referee/types/matchmake-referee-round'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +// * No request data +export class Request { + public static Name = 'GetNotSummarizedRound'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} + +export class Response { + public static Name = 'GetNotSummarizedRound'; + + private rounds = new List(new MatchmakeRefereeRound()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.rounds.extractFrom(stream); + } + + public toJSON(): any { + return { + rounds: this.rounds + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/get-or-create-stats.ts b/src/nex/protocols/matchmake-referee/methods/get-or-create-stats.ts new file mode 100644 index 0000000..843e1dd --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/get-or-create-stats.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeRefereeStatsInitParam from '@/nex/protocols/matchmake-referee/types/matchmake-referee-stats-init-param'; +import MatchmakeRefereeStats from '@/nex/protocols/matchmake-referee/types/matchmake-referee-stats'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetOrCreateStats'; + + private param = new MatchmakeRefereeStatsInitParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.param.extractFrom(stream); + } + + public toJSON(): any { + return { + param: this.param + }; + } +} + +export class Response { + public static Name = 'GetOrCreateStats'; + + private stats = new MatchmakeRefereeStats(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.stats.extractFrom(stream); + } + + public toJSON(): any { + return { + stats: this.stats + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/get-round-participants.ts b/src/nex/protocols/matchmake-referee/methods/get-round-participants.ts new file mode 100644 index 0000000..0445fef --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/get-round-participants.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt64 from '@/nex/types/uint64'; +import List from '@/nex/types/list'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetRoundParticipants'; + + private roundId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.roundId.extractFrom(stream); + } + + public toJSON(): any { + return { + roundId: this.roundId + }; + } +} + +export class Response { + public static Name = 'GetRoundParticipants'; + + private pids = new List(new UInt64()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pids.extractFrom(stream); + } + + public toJSON(): any { + return { + pids: this.pids + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/get-round.ts b/src/nex/protocols/matchmake-referee/methods/get-round.ts new file mode 100644 index 0000000..88bfc10 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/get-round.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt64 from '@/nex/types/uint64'; +import MatchmakeRefereeRound from '@/nex/protocols/matchmake-referee/types/matchmake-referee-round'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetRound'; + + private roundId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.roundId.extractFrom(stream); + } + + public toJSON(): any { + return { + roundId: this.roundId + }; + } +} + +export class Response { + public static Name = 'GetRound'; + + private round = new MatchmakeRefereeRound(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.round.extractFrom(stream); + } + + public toJSON(): any { + return { + round: this.round + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/get-start-round-param.ts b/src/nex/protocols/matchmake-referee/methods/get-start-round-param.ts new file mode 100644 index 0000000..29576a6 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/get-start-round-param.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt64 from '@/nex/types/uint64'; +import MatchmakeRefereeStartRoundParam from '@/nex/protocols/matchmake-referee/types/matchmake-referee-start-round-param'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetStartRoundParam'; + + private roundId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.roundId.extractFrom(stream); + } + + public toJSON(): any { + return { + roundId: this.roundId + }; + } +} + +export class Response { + public static Name = 'GetStartRoundParam'; + + private param = new MatchmakeRefereeStartRoundParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.param.extractFrom(stream); + } + + public toJSON(): any { + return { + param: this.param + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/get-stats-all.ts b/src/nex/protocols/matchmake-referee/methods/get-stats-all.ts new file mode 100644 index 0000000..b7772d8 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/get-stats-all.ts @@ -0,0 +1,43 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeRefereeStatsTarget from '@/nex/protocols/matchmake-referee/types/matchmake-referee-stats-target'; +import List from '@/nex/types/list'; +import MatchmakeRefereeStats from '@/nex/protocols/matchmake-referee/types/matchmake-referee-stats'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetStatsAll'; + + private target = new MatchmakeRefereeStatsTarget(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.target.extractFrom(stream); + } + + public toJSON(): any { + return { + target: this.target + }; + } +} + +export class Response { + public static Name = 'GetStatsAll'; + + private stats = new List(new MatchmakeRefereeStats()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.stats.extractFrom(stream); + } + + public toJSON(): any { + return { + stats: this.stats + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/get-stats-primaries.ts b/src/nex/protocols/matchmake-referee/methods/get-stats-primaries.ts new file mode 100644 index 0000000..a25b9b1 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/get-stats-primaries.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import MatchmakeRefereeStatsTarget from '@/nex/protocols/matchmake-referee/types/matchmake-referee-stats-target'; +import MatchmakeRefereeStats from '@/nex/protocols/matchmake-referee/types/matchmake-referee-stats'; +import QResult from '@/nex/types/qresult'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetStatsPrimaries'; + + private targets = new List(new MatchmakeRefereeStatsTarget()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.targets.extractFrom(stream); + } + + public toJSON(): any { + return { + targets: this.targets + }; + } +} + +export class Response { + public static Name = 'GetStatsPrimaries'; + + private stats = new List(new MatchmakeRefereeStats()); + private results = new List(new QResult()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.stats.extractFrom(stream); + this.results.extractFrom(stream); + } + + public toJSON(): any { + return { + stats: this.stats, + results: this.results + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/get-stats-primary.ts b/src/nex/protocols/matchmake-referee/methods/get-stats-primary.ts new file mode 100644 index 0000000..e93efb2 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/get-stats-primary.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeRefereeStatsTarget from '@/nex/protocols/matchmake-referee/types/matchmake-referee-stats-target'; +import MatchmakeRefereeStats from '@/nex/protocols/matchmake-referee/types/matchmake-referee-stats'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetStatsPrimary'; + + private target = new MatchmakeRefereeStatsTarget(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.target.extractFrom(stream); + } + + public toJSON(): any { + return { + target: this.target + }; + } +} + +export class Response { + public static Name = 'GetStatsPrimary'; + + private stats = new MatchmakeRefereeStats(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.stats.extractFrom(stream); + } + + public toJSON(): any { + return { + stats: this.stats + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/index.ts b/src/nex/protocols/matchmake-referee/methods/index.ts new file mode 100644 index 0000000..de0f269 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/index.ts @@ -0,0 +1,13 @@ +export * as StartRound from '@/nex/protocols/matchmake-referee/methods/start-round'; +export * as GetStartRoundParam from '@/nex/protocols/matchmake-referee/methods/get-start-round-param'; +export * as EndRound from '@/nex/protocols/matchmake-referee/methods/end-round'; +export * as EndRoundWithoutReport from '@/nex/protocols/matchmake-referee/methods/end-round-without-report'; +export * as GetRoundParticipants from '@/nex/protocols/matchmake-referee/methods/get-round-participants'; +export * as GetNotSummarizedRound from '@/nex/protocols/matchmake-referee/methods/get-not-summarized-round'; +export * as GetRound from '@/nex/protocols/matchmake-referee/methods/get-round'; +export * as GetStatsPrimary from '@/nex/protocols/matchmake-referee/methods/get-stats-primary'; +export * as GetStatsPrimaries from '@/nex/protocols/matchmake-referee/methods/get-stats-primaries'; +export * as GetStatsAll from '@/nex/protocols/matchmake-referee/methods/get-stats-all'; +export * as CreateStats from '@/nex/protocols/matchmake-referee/methods/create-stats'; +export * as GetOrCreateStats from '@/nex/protocols/matchmake-referee/methods/get-or-create-stats'; +export * as ResetStats from '@/nex/protocols/matchmake-referee/methods/reset-stats'; \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/reset-stats.ts b/src/nex/protocols/matchmake-referee/methods/reset-stats.ts new file mode 100644 index 0000000..87e5209 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/reset-stats.ts @@ -0,0 +1,23 @@ +// TODO - Add strict types for toJSON methods + +// * No request data +export class Request { + public static Name = 'ResetStats'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} + +// * No response data +export class Response { + public static Name = 'ResetStats'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/methods/start-round.ts b/src/nex/protocols/matchmake-referee/methods/start-round.ts new file mode 100644 index 0000000..648174f --- /dev/null +++ b/src/nex/protocols/matchmake-referee/methods/start-round.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import MatchmakeRefereeStartRoundParam from '@/nex/protocols/matchmake-referee/types/matchmake-referee-start-round-param'; +import UInt64 from '@/nex/types/uint64'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'StartRound'; + + private param = new MatchmakeRefereeStartRoundParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.param.extractFrom(stream); + } + + public toJSON(): any { + return { + param: this.param + }; + } +} + +export class Response { + public static Name = 'StartRound'; + + private roundId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.roundId.extractFrom(stream); + } + + public toJSON(): any { + return { + roundId: this.roundId + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/types/matchmake-referee-end-round-param.ts b/src/nex/protocols/matchmake-referee/types/matchmake-referee-end-round-param.ts new file mode 100644 index 0000000..fb5f243 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/types/matchmake-referee-end-round-param.ts @@ -0,0 +1,35 @@ +import Structure from '@/nex/types/structure'; +import UInt64 from '@/nex/types/uint64'; +import List from '@/nex/types/list'; +import MatchmakeRefereePersonalRoundResult from '@/nex/protocols/matchmake-referee/types/matchmake-referee-personal-round-result'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class MatchmakeRefereeEndRoundParam extends Structure { + public readonly typeName = 'MatchmakeRefereeEndRoundParam'; + + private roundId = new UInt64(); + private personalRoundResults = new List(new MatchmakeRefereePersonalRoundResult()); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.roundId.extractFrom(stream); + this.personalRoundResults.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + roundId: this.roundId, + personalRoundResults: this.personalRoundResults + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/types/matchmake-referee-personal-round-result.ts b/src/nex/protocols/matchmake-referee/types/matchmake-referee-personal-round-result.ts new file mode 100644 index 0000000..067430c --- /dev/null +++ b/src/nex/protocols/matchmake-referee/types/matchmake-referee-personal-round-result.ts @@ -0,0 +1,45 @@ +import Structure from '@/nex/types/structure'; +import PID from '@/nex/types/pid'; +import UInt32 from '@/nex/types/uint32'; +import Int32 from '@/nex/types/int32'; +import QBuffer from '@/nex/types/qbuffer'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class MatchmakeRefereePersonalRoundResult extends Structure { + public readonly typeName = 'MatchmakeRefereePersonalRoundResult'; + + private pid = new PID(); + private personalRoundResultFlag = new UInt32(); + private roundWinLoss = new UInt32(); + private ratingValueChange = new Int32(); + private buffer = new QBuffer(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.pid.extractFrom(stream); + this.personalRoundResultFlag.extractFrom(stream); + this.roundWinLoss.extractFrom(stream); + this.ratingValueChange.extractFrom(stream); + this.buffer.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + pid: this.pid, + personalRoundResultFlag: this.personalRoundResultFlag, + roundWinLoss: this.roundWinLoss, + ratingValueChange: this.ratingValueChange, + buffer: this.buffer + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/types/matchmake-referee-round.ts b/src/nex/protocols/matchmake-referee/types/matchmake-referee-round.ts new file mode 100644 index 0000000..d160641 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/types/matchmake-referee-round.ts @@ -0,0 +1,45 @@ +import Structure from '@/nex/types/structure'; +import UInt64 from '@/nex/types/uint64'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import MatchmakeRefereePersonalRoundResult from '@/nex/protocols/matchmake-referee/types/matchmake-referee-personal-round-result'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class MatchmakeRefereeRound extends Structure { + public readonly typeName = 'MatchmakeRefereeRound'; + + private roundId = new UInt64(); + private gid = new UInt32(); + private state = new UInt32(); + private personalDataCategory = new UInt32(); + private normalizedPersonalRoundResults = new List(new MatchmakeRefereePersonalRoundResult()); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.roundId.extractFrom(stream); + this.gid.extractFrom(stream); + this.state.extractFrom(stream); + this.personalDataCategory.extractFrom(stream); + this.normalizedPersonalRoundResults.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + roundId: this.roundId, + gid: this.gid, + state: this.state, + personalDataCategory: this.personalDataCategory, + normalizedPersonalRoundResults: this.normalizedPersonalRoundResults + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/types/matchmake-referee-start-round-param.ts b/src/nex/protocols/matchmake-referee/types/matchmake-referee-start-round-param.ts new file mode 100644 index 0000000..7ce3aa1 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/types/matchmake-referee-start-round-param.ts @@ -0,0 +1,38 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class MatchmakeRefereeStartRoundParam extends Structure { + public readonly typeName = 'MatchmakeRefereeStartRoundParam'; + + private personalDataCategory = new UInt32(); + private gid = new UInt32(); + private pids = new List(new PID()); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.personalDataCategory.extractFrom(stream); + this.gid.extractFrom(stream); + this.pids.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + personalDataCategory: this.personalDataCategory, + gid: this.gid, + pids: this.pids + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/types/matchmake-referee-stats-init-param.ts b/src/nex/protocols/matchmake-referee/types/matchmake-referee-stats-init-param.ts new file mode 100644 index 0000000..515372d --- /dev/null +++ b/src/nex/protocols/matchmake-referee/types/matchmake-referee-stats-init-param.ts @@ -0,0 +1,33 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class MatchmakeRefereeStatsInitParam extends Structure { + public readonly typeName = 'MatchmakeRefereeStatsInitParam'; + + private category = new UInt32(); + private initialRatingValue = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.category.extractFrom(stream); + this.initialRatingValue.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + category: this.category, + initialRatingValue: this.initialRatingValue + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/types/matchmake-referee-stats-target.ts b/src/nex/protocols/matchmake-referee/types/matchmake-referee-stats-target.ts new file mode 100644 index 0000000..501d6de --- /dev/null +++ b/src/nex/protocols/matchmake-referee/types/matchmake-referee-stats-target.ts @@ -0,0 +1,34 @@ +import Structure from '@/nex/types/structure'; +import PID from '@/nex/types/pid'; +import UInt32 from '@/nex/types/uint32'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class MatchmakeRefereeStatsTarget extends Structure { + public readonly typeName = 'MatchmakeRefereeStatsTarget'; + + private pid = new PID(); + private category = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.pid.extractFrom(stream); + this.category.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + pid: this.pid, + category: this.category + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/matchmake-referee/types/matchmake-referee-stats.ts b/src/nex/protocols/matchmake-referee/types/matchmake-referee-stats.ts new file mode 100644 index 0000000..65693b1 --- /dev/null +++ b/src/nex/protocols/matchmake-referee/types/matchmake-referee-stats.ts @@ -0,0 +1,77 @@ +import Structure from '@/nex/types/structure'; +import UInt64 from '@/nex/types/uint64'; +import UInt32 from '@/nex/types/uint32'; +import PID from '@/nex/types/pid'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class MatchmakeRefereeStats extends Structure { + public readonly typeName = 'MatchmakeRefereeStats'; + + private uniqueId = new UInt64(); + private category = new UInt32(); + private pid = new PID(); + private recentDisconnection = new UInt32(); + private recentViolation = new UInt32(); + private recentMismatch = new UInt32(); + private recentWin = new UInt32(); + private recentLoss = new UInt32(); + private recentDraw = new UInt32(); + private totalDisconnect = new UInt32(); + private totalViolation = new UInt32(); + private totalMismatch = new UInt32(); + private totalWin = new UInt32(); + private totalLoss = new UInt32(); + private totalDraw = new UInt32(); + private ratingValue = new UInt32(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.uniqueId.extractFrom(stream); + this.category.extractFrom(stream); + this.pid.extractFrom(stream); + this.recentDisconnection.extractFrom(stream); + this.recentViolation.extractFrom(stream); + this.recentMismatch.extractFrom(stream); + this.recentWin.extractFrom(stream); + this.recentLoss.extractFrom(stream); + this.recentDraw.extractFrom(stream); + this.totalDisconnect.extractFrom(stream); + this.totalViolation.extractFrom(stream); + this.totalMismatch.extractFrom(stream); + this.totalWin.extractFrom(stream); + this.totalLoss.extractFrom(stream); + this.totalDraw.extractFrom(stream); + this.ratingValue.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + uniqueId: this.uniqueId, + category: this.category, + pid: this.pid, + recentDisconnection: this.recentDisconnection, + recentViolation: this.recentViolation, + recentMismatch: this.recentMismatch, + recentWin: this.recentWin, + recentLoss: this.recentLoss, + recentDraw: this.recentDraw, + totalDisconnect: this.totalDisconnect, + totalViolation: this.totalViolation, + totalMismatch: this.totalMismatch, + totalWin: this.totalWin, + totalLoss: this.totalLoss, + totalDraw: this.totalDraw, + ratingValue: this.ratingValue + } + }; + } +} \ No newline at end of file From d6530a0d5d302770fa3d25320f2b0c4dc516dfc9 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Wed, 8 Jan 2025 14:21:50 -0500 Subject: [PATCH 65/67] feat: complete Ranking protocol --- src/nex/protocols/manager.ts | 3 + src/nex/protocols/ranking/index.ts | 198 ++++++++++++++++++ .../ranking/methods/change-all-attributes.ts | 38 ++++ .../ranking/methods/change-attributes.ts | 42 ++++ .../ranking/methods/delete-all-scores.ts | 34 +++ .../ranking/methods/delete-common-data.ts | 34 +++ .../protocols/ranking/methods/delete-score.ts | 38 ++++ .../ranking/methods/get-approx-order.ts | 56 +++++ .../methods/get-cached-top-x-ranking.ts | 46 ++++ .../methods/get-cached-top-x-rankings.ts | 47 +++++ .../ranking/methods/get-common-data.ts | 42 ++++ .../methods/get-ranking-by-pid-list.ts | 59 ++++++ .../methods/get-ranking-by-unique-id-list.ts | 58 +++++ .../protocols/ranking/methods/get-ranking.ts | 58 +++++ .../protocols/ranking/methods/get-stats.ts | 49 +++++ src/nex/protocols/ranking/methods/index.ts | 15 ++ .../ranking/methods/upload-common-data.ts | 38 ++++ .../protocols/ranking/methods/upload-score.ts | 38 ++++ .../ranking/types/ranking-cached-result.ts | 42 ++++ .../types/ranking-change-attributes-param.ts | 38 ++++ .../ranking/types/ranking-order-param.ts | 46 ++++ .../ranking/types/ranking-rank-data.ts | 56 +++++ .../protocols/ranking/types/ranking-result.ts | 41 ++++ .../ranking/types/ranking-score-data.ts | 48 +++++ .../protocols/ranking/types/ranking-stats.ts | 26 +++ 25 files changed, 1190 insertions(+) create mode 100644 src/nex/protocols/ranking/index.ts create mode 100644 src/nex/protocols/ranking/methods/change-all-attributes.ts create mode 100644 src/nex/protocols/ranking/methods/change-attributes.ts create mode 100644 src/nex/protocols/ranking/methods/delete-all-scores.ts create mode 100644 src/nex/protocols/ranking/methods/delete-common-data.ts create mode 100644 src/nex/protocols/ranking/methods/delete-score.ts create mode 100644 src/nex/protocols/ranking/methods/get-approx-order.ts create mode 100644 src/nex/protocols/ranking/methods/get-cached-top-x-ranking.ts create mode 100644 src/nex/protocols/ranking/methods/get-cached-top-x-rankings.ts create mode 100644 src/nex/protocols/ranking/methods/get-common-data.ts create mode 100644 src/nex/protocols/ranking/methods/get-ranking-by-pid-list.ts create mode 100644 src/nex/protocols/ranking/methods/get-ranking-by-unique-id-list.ts create mode 100644 src/nex/protocols/ranking/methods/get-ranking.ts create mode 100644 src/nex/protocols/ranking/methods/get-stats.ts create mode 100644 src/nex/protocols/ranking/methods/index.ts create mode 100644 src/nex/protocols/ranking/methods/upload-common-data.ts create mode 100644 src/nex/protocols/ranking/methods/upload-score.ts create mode 100644 src/nex/protocols/ranking/types/ranking-cached-result.ts create mode 100644 src/nex/protocols/ranking/types/ranking-change-attributes-param.ts create mode 100644 src/nex/protocols/ranking/types/ranking-order-param.ts create mode 100644 src/nex/protocols/ranking/types/ranking-rank-data.ts create mode 100644 src/nex/protocols/ranking/types/ranking-result.ts create mode 100644 src/nex/protocols/ranking/types/ranking-score-data.ts create mode 100644 src/nex/protocols/ranking/types/ranking-stats.ts diff --git a/src/nex/protocols/manager.ts b/src/nex/protocols/manager.ts index ba51889..486800f 100644 --- a/src/nex/protocols/manager.ts +++ b/src/nex/protocols/manager.ts @@ -5,6 +5,7 @@ import NotificationEventsProtocol from '@/nex/protocols/notification-events'; import MatchMakingProtocol from '@/nex/protocols/match-making'; import MatchMakingExtProtocol from '@/nex/protocols/match-making-ext'; import MatchmakeExtensionProtocol from '@/nex/protocols/matchmake-extension'; +import RankingProtocol from '@/nex/protocols/ranking'; import MatchmakeRefereeProtocol from '@/nex/protocols/matchmake-referee'; import type RMCMessage from '@/nex/rmc-message'; import type ServiceProtocol from '@/types/nex/service-protocol'; @@ -27,6 +28,8 @@ export default function getProtocol(message: RMCMessage): ServiceProtocol | null return MatchMakingExtProtocol; case MatchmakeExtensionProtocol.ID: return MatchmakeExtensionProtocol; + case RankingProtocol.ID: + return RankingProtocol; case MatchmakeRefereeProtocol.ID: return MatchmakeRefereeProtocol; } diff --git a/src/nex/protocols/ranking/index.ts b/src/nex/protocols/ranking/index.ts new file mode 100644 index 0000000..a0461cd --- /dev/null +++ b/src/nex/protocols/ranking/index.ts @@ -0,0 +1,198 @@ +import RMCMessage from '@/nex/rmc-message'; +import * as Methods from '@/nex/protocols/ranking/methods'; +import type Packet from '@/types/nex/packet'; + +export default class RankingProtocol { + static ID = 0x70; + static Name = 'Ranking'; + + static Methods = { + UploadScore: 0x1, + DeleteScore: 0x2, + DeleteAllScores: 0x3, + UploadCommonData: 0x4, + DeleteCommonData: 0x5, + GetCommonData: 0x6, + ChangeAttributes: 0x7, + ChangeAllAttributes: 0x8, + GetRanking: 0x9, + GetApproxOrder: 0xA, + GetStats: 0xB, + GetRankingByPIDList: 0xC, + GetRankingByUniqueIdList: 0xD, + GetCachedTopXRanking: 0xE, + GetCachedTopXRankings: 0xF + }; + + private static handlers: Record any> = { + 0x1: RankingProtocol.UploadScore, + 0x2: RankingProtocol.DeleteScore, + 0x3: RankingProtocol.DeleteAllScores, + 0x4: RankingProtocol.UploadCommonData, + 0x5: RankingProtocol.DeleteCommonData, + 0x6: RankingProtocol.GetCommonData, + 0x7: RankingProtocol.ChangeAttributes, + 0x8: RankingProtocol.ChangeAllAttributes, + 0x9: RankingProtocol.GetRanking, + 0xA: RankingProtocol.GetApproxOrder, + 0xB: RankingProtocol.GetStats, + 0xC: RankingProtocol.GetRankingByPIDList, + 0xD: RankingProtocol.GetRankingByUniqueIdList, + 0xE: RankingProtocol.GetCachedTopXRanking, + 0xF: RankingProtocol.GetCachedTopXRankings + }; + + static handlePacket(packet: Packet): void { + if (!packet.message) { + // * This will never happen. Only checked to make TypeScript happy + return; + } + + const methodID = packet.message.methodID; + const handler = RankingProtocol.handlers[methodID]; + + if (!handler) { + packet.message.methodName = `UnknownMethod_0x${methodID.toString(16).toUpperCase().padStart(2, '0')}`; + return; + } + + const messageDecoder = handler(packet.message); + + packet.message.parameters = new messageDecoder(packet.message); + packet.message.methodName = messageDecoder.Name; + } + + private static UploadScore(message: RMCMessage): typeof Methods.UploadScore.Request | typeof Methods.UploadScore.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UploadScore.Request; + } else { + return Methods.UploadScore.Response; + } + } + + + private static DeleteScore(message: RMCMessage): typeof Methods.DeleteScore.Request | typeof Methods.DeleteScore.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.DeleteScore.Request; + } else { + return Methods.DeleteScore.Response; + } + } + + + private static DeleteAllScores(message: RMCMessage): typeof Methods.DeleteAllScores.Request | typeof Methods.DeleteAllScores.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.DeleteAllScores.Request; + } else { + return Methods.DeleteAllScores.Response; + } + } + + + private static UploadCommonData(message: RMCMessage): typeof Methods.UploadCommonData.Request | typeof Methods.UploadCommonData.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.UploadCommonData.Request; + } else { + return Methods.UploadCommonData.Response; + } + } + + + private static DeleteCommonData(message: RMCMessage): typeof Methods.DeleteCommonData.Request | typeof Methods.DeleteCommonData.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.DeleteCommonData.Request; + } else { + return Methods.DeleteCommonData.Response; + } + } + + + private static GetCommonData(message: RMCMessage): typeof Methods.GetCommonData.Request | typeof Methods.GetCommonData.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetCommonData.Request; + } else { + return Methods.GetCommonData.Response; + } + } + + + private static ChangeAttributes(message: RMCMessage): typeof Methods.ChangeAttributes.Request | typeof Methods.ChangeAttributes.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ChangeAttributes.Request; + } else { + return Methods.ChangeAttributes.Response; + } + } + + + private static ChangeAllAttributes(message: RMCMessage): typeof Methods.ChangeAllAttributes.Request | typeof Methods.ChangeAllAttributes.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.ChangeAllAttributes.Request; + } else { + return Methods.ChangeAllAttributes.Response; + } + } + + + private static GetRanking(message: RMCMessage): typeof Methods.GetRanking.Request | typeof Methods.GetRanking.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetRanking.Request; + } else { + return Methods.GetRanking.Response; + } + } + + + private static GetApproxOrder(message: RMCMessage): typeof Methods.GetApproxOrder.Request | typeof Methods.GetApproxOrder.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetApproxOrder.Request; + } else { + return Methods.GetApproxOrder.Response; + } + } + + + private static GetStats(message: RMCMessage): typeof Methods.GetStats.Request | typeof Methods.GetStats.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetStats.Request; + } else { + return Methods.GetStats.Response; + } + } + + + private static GetRankingByPIDList(message: RMCMessage): typeof Methods.GetRankingByPIDList.Request | typeof Methods.GetRankingByPIDList.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetRankingByPIDList.Request; + } else { + return Methods.GetRankingByPIDList.Response; + } + } + + + private static GetRankingByUniqueIdList(message: RMCMessage): typeof Methods.GetRankingByUniqueIdList.Request | typeof Methods.GetRankingByUniqueIdList.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetRankingByUniqueIdList.Request; + } else { + return Methods.GetRankingByUniqueIdList.Response; + } + } + + + private static GetCachedTopXRanking(message: RMCMessage): typeof Methods.GetCachedTopXRanking.Request | typeof Methods.GetCachedTopXRanking.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetCachedTopXRanking.Request; + } else { + return Methods.GetCachedTopXRanking.Response; + } + } + + + private static GetCachedTopXRankings(message: RMCMessage): typeof Methods.GetCachedTopXRankings.Request | typeof Methods.GetCachedTopXRankings.Response { + if (message.type === RMCMessage.REQUEST) { + return Methods.GetCachedTopXRankings.Request; + } else { + return Methods.GetCachedTopXRankings.Response; + } + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/change-all-attributes.ts b/src/nex/protocols/ranking/methods/change-all-attributes.ts new file mode 100644 index 0000000..b211030 --- /dev/null +++ b/src/nex/protocols/ranking/methods/change-all-attributes.ts @@ -0,0 +1,38 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RankingChangeAttributesParam from '@/nex/protocols/ranking/types/ranking-change-attributes-param'; +import UInt64 from '@/nex/types/uint64'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'ChangeAllAttributes'; + + private changeParam = new RankingChangeAttributesParam(); + private uniqueId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.changeParam.extractFrom(stream); + this.uniqueId.extractFrom(stream); + } + + public toJSON(): any { + return { + changeParam: this.changeParam, + uniqueId: this.uniqueId + }; + } +} + +// * No response data +export class Response { + public static Name = 'ChangeAllAttributes'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/change-attributes.ts b/src/nex/protocols/ranking/methods/change-attributes.ts new file mode 100644 index 0000000..4f5a100 --- /dev/null +++ b/src/nex/protocols/ranking/methods/change-attributes.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RankingChangeAttributesParam from '@/nex/protocols/ranking/types/ranking-change-attributes-param'; +import UInt64 from '@/nex/types/uint64'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'ChangeAttributes'; + + private category = new UInt32(); + private changeParam = new RankingChangeAttributesParam(); + private uniqueId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.category.extractFrom(stream); + this.changeParam.extractFrom(stream); + this.uniqueId.extractFrom(stream); + } + + public toJSON(): any { + return { + category: this.category, + changeParam: this.changeParam, + uniqueId: this.uniqueId + }; + } +} + +// * No response data +export class Response { + public static Name = 'ChangeAttributes'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/delete-all-scores.ts b/src/nex/protocols/ranking/methods/delete-all-scores.ts new file mode 100644 index 0000000..00ab734 --- /dev/null +++ b/src/nex/protocols/ranking/methods/delete-all-scores.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt64 from '@/nex/types/uint64'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'DeleteAllScores'; + + private uniqueId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.uniqueId.extractFrom(stream); + } + + public toJSON(): any { + return { + uniqueId: this.uniqueId + }; + } +} + +// * No response data +export class Response { + public static Name = 'DeleteAllScores'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/delete-common-data.ts b/src/nex/protocols/ranking/methods/delete-common-data.ts new file mode 100644 index 0000000..bc11a07 --- /dev/null +++ b/src/nex/protocols/ranking/methods/delete-common-data.ts @@ -0,0 +1,34 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt64 from '@/nex/types/uint64'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'DeleteCommonData'; + + private uniqueId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.uniqueId.extractFrom(stream); + } + + public toJSON(): any { + return { + uniqueId: this.uniqueId + }; + } +} + +// * No response data +export class Response { + public static Name = 'DeleteCommonData'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/delete-score.ts b/src/nex/protocols/ranking/methods/delete-score.ts new file mode 100644 index 0000000..c87d759 --- /dev/null +++ b/src/nex/protocols/ranking/methods/delete-score.ts @@ -0,0 +1,38 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import UInt64 from '@/nex/types/uint64'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'DeleteScore'; + + private category = new UInt32(); + private uniqueId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.category.extractFrom(stream); + this.uniqueId.extractFrom(stream); + } + + public toJSON(): any { + return { + category: this.category, + uniqueId: this.uniqueId + }; + } +} + +// * No response data +export class Response { + public static Name = 'DeleteScore'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/get-approx-order.ts b/src/nex/protocols/ranking/methods/get-approx-order.ts new file mode 100644 index 0000000..d998d93 --- /dev/null +++ b/src/nex/protocols/ranking/methods/get-approx-order.ts @@ -0,0 +1,56 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RankingOrderParam from '@/nex/protocols/ranking/types/ranking-order-param'; +import UInt64 from '@/nex/types/uint64'; +import PID from '@/nex/types/pid'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetApproxOrder'; + + private category = new UInt32(); + private orderParam = new RankingOrderParam(); + private score = new UInt32(); + private uniqueId = new UInt64(); + private principalId = new PID(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.category.extractFrom(stream); + this.orderParam.extractFrom(stream); + this.score.extractFrom(stream); + this.uniqueId.extractFrom(stream); + this.principalId.extractFrom(stream); + } + + public toJSON(): any { + return { + category: this.category, + orderParam: this.orderParam, + score: this.score, + uniqueId: this.uniqueId, + principalId: this.principalId + }; + } +} + +export class Response { + public static Name = 'GetApproxOrder'; + + private pOrder = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pOrder.extractFrom(stream); + } + + public toJSON(): any { + return { + pOrder: this.pOrder + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/get-cached-top-x-ranking.ts b/src/nex/protocols/ranking/methods/get-cached-top-x-ranking.ts new file mode 100644 index 0000000..8092991 --- /dev/null +++ b/src/nex/protocols/ranking/methods/get-cached-top-x-ranking.ts @@ -0,0 +1,46 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RankingOrderParam from '@/nex/protocols/ranking/types/ranking-order-param'; +import RankingCachedResult from '@/nex/protocols/ranking/types/ranking-cached-result'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetCachedTopXRanking'; + + private category = new UInt32(); + private orderParam = new RankingOrderParam(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.category.extractFrom(stream); + this.orderParam.extractFrom(stream); + } + + public toJSON(): any { + return { + category: this.category, + orderParam: this.orderParam + }; + } +} + +export class Response { + public static Name = 'GetCachedTopXRanking'; + + private pResult = new RankingCachedResult(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pResult.extractFrom(stream); + } + + public toJSON(): any { + return { + pResult: this.pResult + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/get-cached-top-x-rankings.ts b/src/nex/protocols/ranking/methods/get-cached-top-x-rankings.ts new file mode 100644 index 0000000..f8c96bf --- /dev/null +++ b/src/nex/protocols/ranking/methods/get-cached-top-x-rankings.ts @@ -0,0 +1,47 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt32 from '@/nex/types/uint32'; +import RankingOrderParam from '@/nex/protocols/ranking/types/ranking-order-param'; +import RankingCachedResult from '@/nex/protocols/ranking/types/ranking-cached-result'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetCachedTopXRankings'; + + private categories = new List(new UInt32()); + private orderParams = new List(new RankingOrderParam()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.categories.extractFrom(stream); + this.orderParams.extractFrom(stream); + } + + public toJSON(): any { + return { + categories: this.categories, + orderParams: this.orderParams + }; + } +} + +export class Response { + public static Name = 'GetCachedTopXRankings'; + + private pResults = new List(new RankingCachedResult()); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pResults.extractFrom(stream); + } + + public toJSON(): any { + return { + pResults: this.pResults + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/get-common-data.ts b/src/nex/protocols/ranking/methods/get-common-data.ts new file mode 100644 index 0000000..6684eb8 --- /dev/null +++ b/src/nex/protocols/ranking/methods/get-common-data.ts @@ -0,0 +1,42 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt64 from '@/nex/types/uint64'; +import RVBuffer from '@/nex/types/buffer'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetCommonData'; + + private uniqueId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.uniqueId.extractFrom(stream); + } + + public toJSON(): any { + return { + uniqueId: this.uniqueId + }; + } +} + +export class Response { + public static Name = 'GetCommonData'; + + private commonData = new RVBuffer(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.commonData.extractFrom(stream); + } + + public toJSON(): any { + return { + commonData: this.commonData + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/get-ranking-by-pid-list.ts b/src/nex/protocols/ranking/methods/get-ranking-by-pid-list.ts new file mode 100644 index 0000000..cb71b40 --- /dev/null +++ b/src/nex/protocols/ranking/methods/get-ranking-by-pid-list.ts @@ -0,0 +1,59 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import PID from '@/nex/types/pid'; +import UInt8 from '@/nex/types/uint8'; +import UInt32 from '@/nex/types/uint32'; +import RankingOrderParam from '@/nex/protocols/ranking/types/ranking-order-param'; +import UInt64 from '@/nex/types/uint64'; +import RankingResult from '@/nex/protocols/ranking/types/ranking-result'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetRankingByPIDList'; + + private principalIdList = new List(new PID()); + private rankingMode = new UInt8(); + private category = new UInt32(); + private orderParam = new RankingOrderParam(); + private uniqueId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.principalIdList.extractFrom(stream); + this.rankingMode.extractFrom(stream); + this.category.extractFrom(stream); + this.orderParam.extractFrom(stream); + this.uniqueId.extractFrom(stream); + } + + public toJSON(): any { + return { + principalIdList: this.principalIdList, + rankingMode: this.rankingMode, + category: this.category, + orderParam: this.orderParam, + uniqueId: this.uniqueId + }; + } +} + +export class Response { + public static Name = 'GetRankingByPIDList'; + + private pResult = new RankingResult(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pResult.extractFrom(stream); + } + + public toJSON(): any { + return { + pResult: this.pResult + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/get-ranking-by-unique-id-list.ts b/src/nex/protocols/ranking/methods/get-ranking-by-unique-id-list.ts new file mode 100644 index 0000000..0167ba8 --- /dev/null +++ b/src/nex/protocols/ranking/methods/get-ranking-by-unique-id-list.ts @@ -0,0 +1,58 @@ +import NEXByteStream from '@/nex/byte-stream'; +import List from '@/nex/types/list'; +import UInt64 from '@/nex/types/uint64'; +import UInt8 from '@/nex/types/uint8'; +import UInt32 from '@/nex/types/uint32'; +import RankingOrderParam from '@/nex/protocols/ranking/types/ranking-order-param'; +import RankingResult from '@/nex/protocols/ranking/types/ranking-result'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetRankingByUniqueIdList'; + + private nexUniqueIdList = new List(new UInt64()); + private rankingMode = new UInt8(); + private category = new UInt32(); + private orderParam = new RankingOrderParam(); + private uniqueId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.nexUniqueIdList.extractFrom(stream); + this.rankingMode.extractFrom(stream); + this.category.extractFrom(stream); + this.orderParam.extractFrom(stream); + this.uniqueId.extractFrom(stream); + } + + public toJSON(): any { + return { + nexUniqueIdList: this.nexUniqueIdList, + rankingMode: this.rankingMode, + category: this.category, + orderParam: this.orderParam, + uniqueId: this.uniqueId + }; + } +} + +export class Response { + public static Name = 'GetRankingByUniqueIdList'; + + private pResult = new RankingResult(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pResult.extractFrom(stream); + } + + public toJSON(): any { + return { + pResult: this.pResult + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/get-ranking.ts b/src/nex/protocols/ranking/methods/get-ranking.ts new file mode 100644 index 0000000..c2ad4ad --- /dev/null +++ b/src/nex/protocols/ranking/methods/get-ranking.ts @@ -0,0 +1,58 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt8 from '@/nex/types/uint8'; +import UInt32 from '@/nex/types/uint32'; +import RankingOrderParam from '@/nex/protocols/ranking/types/ranking-order-param'; +import UInt64 from '@/nex/types/uint64'; +import PID from '@/nex/types/pid'; +import RankingResult from '@/nex/protocols/ranking/types/ranking-result'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetRanking'; + + private rankingMode = new UInt8(); + private category = new UInt32(); + private orderParam = new RankingOrderParam(); + private uniqueId = new UInt64(); + private principalId = new PID(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.rankingMode.extractFrom(stream); + this.category.extractFrom(stream); + this.orderParam.extractFrom(stream); + this.uniqueId.extractFrom(stream); + this.principalId.extractFrom(stream); + } + + public toJSON(): any { + return { + rankingMode: this.rankingMode, + category: this.category, + orderParam: this.orderParam, + uniqueId: this.uniqueId, + principalId: this.principalId + }; + } +} + +export class Response { + public static Name = 'GetRanking'; + + private pResult = new RankingResult(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pResult.extractFrom(stream); + } + + public toJSON(): any { + return { + pResult: this.pResult + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/get-stats.ts b/src/nex/protocols/ranking/methods/get-stats.ts new file mode 100644 index 0000000..1749e3e --- /dev/null +++ b/src/nex/protocols/ranking/methods/get-stats.ts @@ -0,0 +1,49 @@ +import NEXByteStream from '@/nex/byte-stream'; +import UInt32 from '@/nex/types/uint32'; +import RankingOrderParam from '@/nex/protocols/ranking/types/ranking-order-param'; +import RankingStats from '@/nex/protocols/ranking/types/ranking-stats'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'GetStats'; + + private category = new UInt32(); + private orderParam = new RankingOrderParam(); + private flags = new UInt32(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.category.extractFrom(stream); + this.orderParam.extractFrom(stream); + this.flags.extractFrom(stream); + } + + public toJSON(): any { + return { + category: this.category, + orderParam: this.orderParam, + flags: this.flags + }; + } +} + +export class Response { + public static Name = 'GetStats'; + + private pStats = new RankingStats(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.pStats.extractFrom(stream); + } + + public toJSON(): any { + return { + pStats: this.pStats + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/index.ts b/src/nex/protocols/ranking/methods/index.ts new file mode 100644 index 0000000..8d6498d --- /dev/null +++ b/src/nex/protocols/ranking/methods/index.ts @@ -0,0 +1,15 @@ +export * as UploadScore from '@/nex/protocols/ranking/methods/upload-score'; +export * as DeleteScore from '@/nex/protocols/ranking/methods/delete-score'; +export * as DeleteAllScores from '@/nex/protocols/ranking/methods/delete-all-scores'; +export * as UploadCommonData from '@/nex/protocols/ranking/methods/upload-common-data'; +export * as DeleteCommonData from '@/nex/protocols/ranking/methods/delete-common-data'; +export * as GetCommonData from '@/nex/protocols/ranking/methods/get-common-data'; +export * as ChangeAttributes from '@/nex/protocols/ranking/methods/change-attributes'; +export * as ChangeAllAttributes from '@/nex/protocols/ranking/methods/change-all-attributes'; +export * as GetRanking from '@/nex/protocols/ranking/methods/get-ranking'; +export * as GetApproxOrder from '@/nex/protocols/ranking/methods/get-approx-order'; +export * as GetStats from '@/nex/protocols/ranking/methods/get-stats'; +export * as GetRankingByPIDList from '@/nex/protocols/ranking/methods/get-ranking-by-pid-list'; +export * as GetRankingByUniqueIdList from '@/nex/protocols/ranking/methods/get-ranking-by-unique-id-list'; +export * as GetCachedTopXRanking from '@/nex/protocols/ranking/methods/get-cached-top-x-ranking'; +export * as GetCachedTopXRankings from '@/nex/protocols/ranking/methods/get-cached-top-x-rankings'; \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/upload-common-data.ts b/src/nex/protocols/ranking/methods/upload-common-data.ts new file mode 100644 index 0000000..e49189f --- /dev/null +++ b/src/nex/protocols/ranking/methods/upload-common-data.ts @@ -0,0 +1,38 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RVBuffer from '@/nex/types/buffer'; +import UInt64 from '@/nex/types/uint64'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UploadCommonData'; + + private commonData = new RVBuffer(); + private uniqueId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.commonData.extractFrom(stream); + this.uniqueId.extractFrom(stream); + } + + public toJSON(): any { + return { + commonData: this.commonData, + uniqueId: this.uniqueId + }; + } +} + +// * No response data +export class Response { + public static Name = 'UploadCommonData'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/methods/upload-score.ts b/src/nex/protocols/ranking/methods/upload-score.ts new file mode 100644 index 0000000..fac0483 --- /dev/null +++ b/src/nex/protocols/ranking/methods/upload-score.ts @@ -0,0 +1,38 @@ +import NEXByteStream from '@/nex/byte-stream'; +import RankingScoreData from '@/nex/protocols/ranking/types/ranking-score-data'; +import UInt64 from '@/nex/types/uint64'; +import type RMCMessage from '@/nex/rmc-message'; + +// TODO - Add strict types for toJSON methods + +export class Request { + public static Name = 'UploadScore'; + + private scoreData = new RankingScoreData(); + private uniqueId = new UInt64(); + + constructor(message: RMCMessage) { + const stream = new NEXByteStream(message.parametersData!, message.connection.title); + + this.scoreData.extractFrom(stream); + this.uniqueId.extractFrom(stream); + } + + public toJSON(): any { + return { + scoreData: this.scoreData, + uniqueId: this.uniqueId + }; + } +} + +// * No response data +export class Response { + public static Name = 'UploadScore'; + + constructor() {} + + public toJSON(): any { + return {}; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/types/ranking-cached-result.ts b/src/nex/protocols/ranking/types/ranking-cached-result.ts new file mode 100644 index 0000000..88018b8 --- /dev/null +++ b/src/nex/protocols/ranking/types/ranking-cached-result.ts @@ -0,0 +1,42 @@ +import DateTime from '@/nex/types/datetime'; +import UInt8 from '@/nex/types/uint8'; +import RankingResult from '@/nex/protocols/ranking/types/ranking-result'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class RankingCachedResult extends RankingResult { + public get typeName(): string { + return 'RankingCachedResult'; + } + + private createdTime = new DateTime(); + private expiredTime = new DateTime(); + private maxLength = new UInt8(); + + public extractFrom(stream: NEXByteStream): void { + super.extractFrom(stream); + + this.extractHeaderFrom(stream); + + this.createdTime.extractFrom(stream); + this.expiredTime.extractFrom(stream); + this.maxLength.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __parent: super.toJSON(), + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + createdTime: this.createdTime, + expiredTime: this.expiredTime, + maxLength: this.maxLength + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/types/ranking-change-attributes-param.ts b/src/nex/protocols/ranking/types/ranking-change-attributes-param.ts new file mode 100644 index 0000000..2c03ad6 --- /dev/null +++ b/src/nex/protocols/ranking/types/ranking-change-attributes-param.ts @@ -0,0 +1,38 @@ +import Structure from '@/nex/types/structure'; +import UInt8 from '@/nex/types/uint8'; +import List from '@/nex/types/list'; +import UInt64 from '@/nex/types/uint64'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class RankingChangeAttributesParam extends Structure { + public readonly typeName = 'RankingChangeAttributesParam'; + + private modificationFlag = new UInt8(); + private groups = new List(new UInt8()); + private param = new UInt64(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.modificationFlag.extractFrom(stream); + this.groups.extractFrom(stream); + this.param.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + modificationFlag: this.modificationFlag, + groups: this.groups, + param: this.param + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/types/ranking-order-param.ts b/src/nex/protocols/ranking/types/ranking-order-param.ts new file mode 100644 index 0000000..85fc817 --- /dev/null +++ b/src/nex/protocols/ranking/types/ranking-order-param.ts @@ -0,0 +1,46 @@ +import Structure from '@/nex/types/structure'; +import UInt8 from '@/nex/types/uint8'; +import UInt32 from '@/nex/types/uint32'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class RankingOrderParam extends Structure { + public readonly typeName = 'RankingOrderParam'; + + private orderCalculation = new UInt8(); + private groupIndex = new UInt8(); + private groupNum = new UInt8(); + private timeScope = new UInt8(); + private offset = new UInt32(); + private length = new UInt8(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.orderCalculation.extractFrom(stream); + this.groupIndex.extractFrom(stream); + this.groupNum.extractFrom(stream); + this.timeScope.extractFrom(stream); + this.offset.extractFrom(stream); + this.length.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + orderCalculation: this.orderCalculation, + groupIndex: this.groupIndex, + groupNum: this.groupNum, + timeScope: this.timeScope, + offset: this.offset, + length: this.length + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/types/ranking-rank-data.ts b/src/nex/protocols/ranking/types/ranking-rank-data.ts new file mode 100644 index 0000000..e00767f --- /dev/null +++ b/src/nex/protocols/ranking/types/ranking-rank-data.ts @@ -0,0 +1,56 @@ +import Structure from '@/nex/types/structure'; +import PID from '@/nex/types/pid'; +import UInt64 from '@/nex/types/uint64'; +import UInt32 from '@/nex/types/uint32'; +import List from '@/nex/types/list'; +import UInt8 from '@/nex/types/uint8'; +import RVBuffer from '@/nex/types/buffer'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class RankingRankData extends Structure { + public readonly typeName = 'RankingRankData'; + + private principalId = new PID(); + private uniqueId = new UInt64(); + private order = new UInt32(); + private category = new UInt32(); + private score = new UInt32(); + private groups = new List(new UInt8()); + private param = new UInt64(); + private commonData = new RVBuffer(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.principalId.extractFrom(stream); + this.uniqueId.extractFrom(stream); + this.order.extractFrom(stream); + this.category.extractFrom(stream); + this.score.extractFrom(stream); + this.groups.extractFrom(stream); + this.param.extractFrom(stream); + this.commonData.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + principalId: this.principalId, + uniqueId: this.uniqueId, + order: this.order, + category: this.category, + score: this.score, + groups: this.groups, + param: this.param, + commonData: this.commonData + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/types/ranking-result.ts b/src/nex/protocols/ranking/types/ranking-result.ts new file mode 100644 index 0000000..3d44a8c --- /dev/null +++ b/src/nex/protocols/ranking/types/ranking-result.ts @@ -0,0 +1,41 @@ +import Structure from '@/nex/types/structure'; +import List from '@/nex/types/list'; +import RankingRankData from '@/nex/protocols/ranking/types/ranking-rank-data'; +import UInt32 from '@/nex/types/uint32'; +import DateTime from '@/nex/types/datetime'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class RankingResult extends Structure { + public get typeName(): string { + return 'RankingResult'; + } + + private rankDataList = new List(new RankingRankData()); + private totalCount = new UInt32(); + private sinceTime = new DateTime(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.rankDataList.extractFrom(stream); + this.totalCount.extractFrom(stream); + this.sinceTime.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + rankDataList: this.rankDataList, + totalCount: this.totalCount, + sinceTime: this.sinceTime + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/types/ranking-score-data.ts b/src/nex/protocols/ranking/types/ranking-score-data.ts new file mode 100644 index 0000000..6c755ba --- /dev/null +++ b/src/nex/protocols/ranking/types/ranking-score-data.ts @@ -0,0 +1,48 @@ +import Structure from '@/nex/types/structure'; +import UInt32 from '@/nex/types/uint32'; +import UInt8 from '@/nex/types/uint8'; +import List from '@/nex/types/list'; +import UInt64 from '@/nex/types/uint64'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class RankingScoreData extends Structure { + public readonly typeName = 'RankingScoreData'; + + private category = new UInt32(); + private score = new UInt32(); + private orderBy = new UInt8(); + private updateMode = new UInt8(); + private groups = new List(new UInt8()); + private param = new UInt64(); + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + this.category.extractFrom(stream); + this.score.extractFrom(stream); + this.orderBy.extractFrom(stream); + this.updateMode.extractFrom(stream); + this.groups.extractFrom(stream); + this.param.extractFrom(stream); + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + category: this.category, + score: this.score, + orderBy: this.orderBy, + updateMode: this.updateMode, + groups: this.groups, + param: this.param + } + }; + } +} \ No newline at end of file diff --git a/src/nex/protocols/ranking/types/ranking-stats.ts b/src/nex/protocols/ranking/types/ranking-stats.ts new file mode 100644 index 0000000..abc9b4a --- /dev/null +++ b/src/nex/protocols/ranking/types/ranking-stats.ts @@ -0,0 +1,26 @@ +import Structure from '@/nex/types/structure'; +import type NEXByteStream from '@/nex/byte-stream'; + +export default class RankingStats extends Structure { + public readonly typeName = 'RankingStats'; + + + public extractFrom(stream: NEXByteStream): void { + this.extractHeaderFrom(stream); + + } + + public new(): this { + return new (this.constructor as new () => this)(); + } + + public toJSON(): any { + return { + __version: this.structureVersion, + __displayTypeName: this.typeName, + __typeName: this.typeName, + __fields: { + } + }; + } +} \ No newline at end of file From 07241a04169110fb6746ce05fefa9aa8281b4bc2 Mon Sep 17 00:00:00 2001 From: Jonathan Barrow Date: Wed, 8 Jan 2025 14:22:52 -0500 Subject: [PATCH 66/67] chore: update method IDs in MatchmakeReferee protocol --- src/nex/protocols/matchmake-referee/index.ts | 52 ++++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/nex/protocols/matchmake-referee/index.ts b/src/nex/protocols/matchmake-referee/index.ts index 25aa9e7..c30d751 100644 --- a/src/nex/protocols/matchmake-referee/index.ts +++ b/src/nex/protocols/matchmake-referee/index.ts @@ -7,35 +7,35 @@ export default class MatchmakeRefereeProtocol { static Name = 'MatchmakeReferee'; static Methods = { - StartRound: 0x01, - GetStartRoundParam: 0x02, - EndRound: 0x03, - EndRoundWithoutReport: 0x04, - GetRoundParticipants: 0x05, - GetNotSummarizedRound: 0x06, - GetRound: 0x07, - GetStatsPrimary: 0x08, - GetStatsPrimaries: 0x09, - GetStatsAll: 0x0A, - CreateStats: 0x0B, - GetOrCreateStats: 0x0C, - ResetStats: 0x0D + StartRound: 0x1, + GetStartRoundParam: 0x2, + EndRound: 0x3, + EndRoundWithoutReport: 0x4, + GetRoundParticipants: 0x5, + GetNotSummarizedRound: 0x6, + GetRound: 0x7, + GetStatsPrimary: 0x8, + GetStatsPrimaries: 0x9, + GetStatsAll: 0xA, + CreateStats: 0xB, + GetOrCreateStats: 0xC, + ResetStats: 0xD }; private static handlers: Record any> = { - 0x01: MatchmakeRefereeProtocol.StartRound, - 0x02: MatchmakeRefereeProtocol.GetStartRoundParam, - 0x03: MatchmakeRefereeProtocol.EndRound, - 0x04: MatchmakeRefereeProtocol.EndRoundWithoutReport, - 0x05: MatchmakeRefereeProtocol.GetRoundParticipants, - 0x06: MatchmakeRefereeProtocol.GetNotSummarizedRound, - 0x07: MatchmakeRefereeProtocol.GetRound, - 0x08: MatchmakeRefereeProtocol.GetStatsPrimary, - 0x09: MatchmakeRefereeProtocol.GetStatsPrimaries, - 0x0A: MatchmakeRefereeProtocol.GetStatsAll, - 0x0B: MatchmakeRefereeProtocol.CreateStats, - 0x0C: MatchmakeRefereeProtocol.GetOrCreateStats, - 0x0D: MatchmakeRefereeProtocol.ResetStats + 0x1: MatchmakeRefereeProtocol.StartRound, + 0x2: MatchmakeRefereeProtocol.GetStartRoundParam, + 0x3: MatchmakeRefereeProtocol.EndRound, + 0x4: MatchmakeRefereeProtocol.EndRoundWithoutReport, + 0x5: MatchmakeRefereeProtocol.GetRoundParticipants, + 0x6: MatchmakeRefereeProtocol.GetNotSummarizedRound, + 0x7: MatchmakeRefereeProtocol.GetRound, + 0x8: MatchmakeRefereeProtocol.GetStatsPrimary, + 0x9: MatchmakeRefereeProtocol.GetStatsPrimaries, + 0xA: MatchmakeRefereeProtocol.GetStatsAll, + 0xB: MatchmakeRefereeProtocol.CreateStats, + 0xC: MatchmakeRefereeProtocol.GetOrCreateStats, + 0xD: MatchmakeRefereeProtocol.ResetStats }; static handlePacket(packet: Packet): void { From cb7406c6d11211d0be4d355e913576b2fddd89fb Mon Sep 17 00:00:00 2001 From: Ash Logan Date: Fri, 10 Jan 2025 14:06:47 +1100 Subject: [PATCH 67/67] fix: Account for NEX versions in JoinMatchmakeSessionParam I have the strangest feeling that I made this exact commit to nex-protocols-go months ago --- .../types/join-matchmake-session-param.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/nex/protocols/match-making/types/join-matchmake-session-param.ts b/src/nex/protocols/match-making/types/join-matchmake-session-param.ts index 4bf6388..276bf65 100644 --- a/src/nex/protocols/match-making/types/join-matchmake-session-param.ts +++ b/src/nex/protocols/match-making/types/join-matchmake-session-param.ts @@ -1,3 +1,4 @@ +import semver from 'compare-versions'; import Structure from '@/nex/types/structure'; import UInt32 from '@/nex/types/uint32'; import List from '@/nex/types/list'; @@ -20,8 +21,8 @@ export default class JoinMatchmakeSessionParam extends Structure { private strSystemPassword = new RVString(); private joinMessage = new RVString(); private participationCount = new UInt16(); - private extraParticipants = new UInt16(); - private blockListParam = new MatchmakeBlockListParam(); + private extraParticipants: UInt16; // * SV 1 / NEX 4.0 + private blockListParam: MatchmakeBlockListParam; // * NEX 4.0 public extractFrom(stream: NEXByteStream): void { this.extractHeaderFrom(stream); @@ -35,8 +36,16 @@ export default class JoinMatchmakeSessionParam extends Structure { this.strSystemPassword.extractFrom(stream); this.joinMessage.extractFrom(stream); this.participationCount.extractFrom(stream); - this.extraParticipants.extractFrom(stream); - this.blockListParam.extractFrom(stream); + + if (this.structureVersion >= 1 || semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) { + this.extraParticipants = new UInt16(); + this.extraParticipants.extractFrom(stream); + } + + if (semver.satisfies(stream.title.library_versions.match_making, '>=4.0.0')) { + this.blockListParam = new MatchmakeBlockListParam(); + this.blockListParam.extractFrom(stream); + } } public new(): this { @@ -63,4 +72,4 @@ export default class JoinMatchmakeSessionParam extends Structure { } }; } -} \ No newline at end of file +}